commit c3c9fee2fbea94385cc0ab1281b48d00ef88be15 Author: Ivan Date: Mon Jun 7 11:56:04 2021 +0800 first diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..ca1bab9 --- /dev/null +++ b/.babelrc @@ -0,0 +1,43 @@ +{ + "presets": [ + [ + "env", + { + "loose": true, + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + } + ], + "stage-2" + ], + "plugins": ["transform-vue-jsx"], + "env": { + "utils": { + "presets": [ + [ + "env", + { + "loose": true, + "modules": "commonjs", + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + } + ], + ], + "plugins": [ + ["module-resolver", { + "root": ["element-ui"], + "alias": { + "element-ui/src": "element-ui/lib" + } + }] + ] + }, + "test": { + "plugins": ["istanbul"] + } + } +} diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..aa95173 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,11 @@ +src/utils/popper.js +src/utils/date.js +examples/play +*.sh +node_modules +lib +coverage +*.md +*.scss +*.woff +*.ttf diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..ad4aa56 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,17 @@ +{ + "globals": { + "ga": true, + "chrome": true + }, + "plugins": ["html", "json"], + "extends": "elemefe", + "rules": { + "no-restricted-globals": ["error", "event", "fdescribe"] + }, + "parserOptions": { + "ecmaVersion": 6, + "ecmaFeatures": { + "jsx": true + } + } +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1e73b4e --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +test/**/*.js linguist-language=Vue diff --git a/.github/CONTRIBUTING.en-US.md b/.github/CONTRIBUTING.en-US.md new file mode 100644 index 0000000..ee651f7 --- /dev/null +++ b/.github/CONTRIBUTING.en-US.md @@ -0,0 +1,60 @@ +# Element UI Contributing Guide + +Hi! Thank you for choosing Element UI. + +Element UI is a Vue 2.0 based component library for developers, designers and product managers. + +We are excited that you are interested in contributing to Element. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines. + +## Issue Guidelines + +- Issues are exclusively for bug reports, feature requests and design-related topics. Other questions may be closed directly. If any questions come up when you are using Element, please hit [Gitter](https://gitter.im/element-en/Lobby) for help. + +- Before submitting an issue, please check if similar problems have already been issued. + +- Please specify which version of `Element` and `Vue` you are using, and provide OS and browser information. [JSFiddle](https://jsfiddle.net/) is recommended to build a live demo so that your issue can be reproduced clearly. + +## Pull Request Guidelines + +- Fork this repository to your own account. Do not create branches here. + +- Commit info should be formatted as `[Component Name]: Info about commit.` (e.g. `Button: Fix xxx bug`) + +- **DO NOT** include files inside `lib` directory. + +- Make sure that running `npm run dist` outputs the correct files. + +- For the sake of compatibility and file size, our babel configuration only imported `preset-2015`, so APIs like `Array.prototype.find` and `Object.assign` in `ES2015` are not recommended. You can import third party polyfills if necessary. + +- Rebase before creating a PR to keep commit history clear. + +- Make sure PRs are created to `dev` branch instead of `master` branch. + +- If your PR fixes a bug, please provide a description about the related bug. + +- Merging a PR takes two maintainers: one approves the changes after reviewing, and then the other reviews and merges. + +## Prerequisites +`Node.js 4+`, `yarn` and `npm 3+` are required. Note: we use yarn to lock dependency versions, so you should install dependencies using `yarn` instead of `npm install`. +```shell +git clone git@github.com:ElemeFE/element.git +npm run dev + +# open http://localhost:8085 +``` + +> **Notice**: modify `examples/play/index.vue` file, use the component you contribute, then run `npm run dev:play`, go ahead [http://localhost:8085](http://localhost:8085), get result, more quickly and friendly. + +To build: + +```shell +npm run dist +``` + +## Component Developing Guidelines +- Run `make new ` to create project directory for a new component. Test codes, entry file and documentation are included. +- Refer to `Button` for nested components. +- Refer to `Select` for components that depend on other components. + +## Code Style +Just comply with the [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) configuration of [ElemeFE](https://github.com/elemefe). diff --git a/.github/CONTRIBUTING.es.md b/.github/CONTRIBUTING.es.md new file mode 100644 index 0000000..d5c6022 --- /dev/null +++ b/.github/CONTRIBUTING.es.md @@ -0,0 +1,67 @@ +# 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+`, `yarn` y `npm 3+` son requisitos. Nota: Usamos yarn para bloquear versiones de dependencias, por lo que debería instalar dependencias usando `yarn` en lugar de `npm install`. +. +```shell +git clone git@github.com:ElemeFE/element.git +npm run dev + +# abra http://localhost:8085 +``` + +> **Notice**: modify `examples/play/index.vue` file, use the component you contribute, then run `npm run dev:play`, go ahead [http://localhost:8085](http://localhost:8085), get result, more quickly and friendly. + +Para armar: + +``` +shell +npm run dist +``` + +## Guía Para Desarrollo de Componentes +- Corra el comando `make new ` para crear el directorio de su proyecto para un componente nuevo. Verifique su código fuente test, archivo de entrada y documentación 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). + diff --git a/.github/CONTRIBUTING.fr-FR.md b/.github/CONTRIBUTING.fr-FR.md new file mode 100644 index 0000000..f8112be --- /dev/null +++ b/.github/CONTRIBUTING.fr-FR.md @@ -0,0 +1,60 @@ +# Guide à destination des contributeurs d'Element UI + +Bonjour! Merci d'avoir choisi Element UI. + +Element UI est une bibliothèque de composants basée sur Vue 2.0 pour les développeurs, les designers et les chefs de produits. + +Nous sommes ravis que vous souhaitiez contribuer à Element. Avant de soumettre votre contribution, veuillez vous assurer de prendre un moment pour lire les indications suivantes. + +## Concernant les issues + +- Les issues concernent exclusivement les bugs, les demandes de fonctionnalités et les sujets liés à la conception. Les questions concernant d'autres sujets peuvent être fermées directement. Si vous avez des questions à propos de l'utilisation d'Element, veuillez vous rendre sur [Gitter](https://gitter.im/element-en/Lobby) pour obtenir de l'aide. + +- Avant de soumettre une issue, veuillez vérifier si des problèmes similaires n'ont pas déjà été signalés. + +- Veuillez spécifier la version de `Element` et `Vue` que vous utilisez, et fournir des informations sur le système d'exploitation et le navigateur. [JSFiddle](https://jsfiddle.net/) est recommandé afin de construire une démo pour que votre problème puisse être reproduit clairement. + +## Concernant les pull requests + +- Faites un fork de ce dépôt vers votre compte. Ne créez pas de branches ici. + +- Les informations de validation doivent être formatées en tant que `[Nom du composant] : Info à propos de ce commit` (par exemple `Button : Fix xxx bug`) + +- **NE PAS** inclure de fichiers dans le répertoire `lib`. + +- Assurez-vous que l'exécution de `npm run dist` génère les bons fichiers. + +- Pour des raisons de compatibilité et de taille de fichier, notre configuration babel n'importait que `preset-2015`, donc les API comme `Array.prototype.find` et `Object.assign` dans `ES2015` ne sont pas recommandées. Vous pouvez importer des polyfills si nécessaire. + +- Faites un rebase avant la création d'une PR pour garder l'historique clair. + +- Assurez-vous que les PRs sont créés dans la branche `dev` au lieu de la branche `master`. + +- Si votre PR corrige un bug, veuillez fournir une description du bug en question. + +- La fusion d'un PR nécessite deux responsables: l'un approuve les modifications après révision, puis l'autre les révise et les fusionne. + +## Pré-requis +`Node.js 4+`, `yarn` et `npm 3+` sont requis. Note: nous utilisons yarn pour verrouiller les versions des dépendances, donc vous devriez installer les dépendances en utilisant `yarn` au lieu de `npm install`. +```shell +git clone git@github.com:ElemeFE/element.git +npm run dev + +# open http://localhost:8085 +``` + +> **Remarque** : modifiez le fichier `examples/play/index.vue`, utilisez le composant auquel vous contribuez, puis lancez `npm run dev:play`, allez sur [http://localhost:8085](http://localhost:8085), regardez le résultat rapidement et facilement. + +Pour le build: + +```shell +npm run dist +``` + +## Concernant le développement de composants +- Exécutez `make new ` pour créer un répertoire pour le nouveau composant. Les tests, le fichier d'entrée et la documentation sont inclus. +- Reportez-vous au `Button` pour les composants imbriqués. +- Reportez-vous à `Select` pour connaître les composants qui dépendent d'autres composants. + +## Style du code +Il suffit de se conformer à la configuration [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) de [ElemeFE](https://github.com/elemefe). diff --git a/.github/CONTRIBUTING.zh-CN.md b/.github/CONTRIBUTING.zh-CN.md new file mode 100644 index 0000000..17b3cc8 --- /dev/null +++ b/.github/CONTRIBUTING.zh-CN.md @@ -0,0 +1,58 @@ +# Element UI 贡献指南 + +Hi! 首先感谢你使用 Element UI。 + +Element UI 是一套为开发者、设计师和产品经理准备的开源组件库,旨在快速搭建页面。它基于 Vue 2.0 开发,并提供了配套的设计资源,充分满足可定制化的需求。 + +Element UI 的成长离不开大家的支持,如果你愿意为 Element UI 贡献代码或提供建议,请阅读以下内容。 + +## Issue 规范 +- issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。如果你在使用时产生了疑问,请到 Slack 或 [Gitter](https://gitter.im/ElemeFE/element) 里咨询。 + +- 在提交 issue 之前,请搜索相关内容是否已被提出。 + +- 请说明 Element UI 和 Vue 的版本号,并提供操作系统和浏览器信息。推荐使用 [JSFiddle](https://jsfiddle.net/) 生成在线 demo,这能够更直观地重现问题。 + +## Pull Request 规范 +- 请先 fork 一份到自己的项目下,不要直接在仓库下建分支。 + +- commit 信息要以`[组件名]: 描述信息` 的形式填写,例如 `Button: fix xxx bug`。 + +- **不要提交** `lib` 里面打包的文件。 + +- 执行 `npm run dist` 后可以正确打包文件。 + +- 为了兼容性以及最终打包的文件体积考虑,我们的 babel 只引入了 `preset-2015`,所以不建议使用 ES2015 的 API,例如 `Array.prototype.find`、`Object.assign`等。如果有需要,请引入第三方的 polyfill。 + +- 提交 PR 前请 rebase,确保 commit 记录的整洁。 + +- 确保 PR 是提交到 `dev` 分支,而不是 `master` 分支。 + +- 如果是修复 bug,请在 PR 中给出描述信息。 + +- 合并代码需要两名维护人员参与:一人进行 review 后 approve,另一人再次 review,通过后即可合并。 + +## 开发环境搭建 +首先你需要 Node.js 4+,yarn 和 npm 3+。注意:我们使用 yarn 进行依赖版本的锁定,所以请不要使用 `npm install` 安装依赖。 +```shell +git clone git@github.com:ElemeFE/element.git +npm run dev + +# open http://localhost:8085 +``` + +> **提示**:可以运行 `npm run dev:play`,修改 `examples/play/index.vue` 文件,调用你修改后的组件,仍然访问 [http://localhost:8085](http://localhost:8085),查看修改效果,更快更方便。 + +打包代码: + +```shell +npm run dist +``` + +## 组件开发规范 +- 通过 `make new` 创建组件目录结构,包含测试代码、入口文件、文档 +- 如果包含父子组件,需要更改目录结构,参考 `Button` +- 组件内如果依赖了其他组件,需要在当前组件内引入,参考 `Select` + +## 代码规范 +遵循饿了么前端的 [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) 即可 diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..cc77845 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,15 @@ + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..149bb4e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Create new issue + url: https://elementui.github.io/issue-generator + about: The issue which is not created via https://elementui.github.io/issue-generator will be closed immediately. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..12f9bf8 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +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) | [Español](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.es.md) | [Français](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.fr-FR.md)). +* [ ] Make sure you are merging your commits to `dev` branch. +* [ ] Add some descriptions and refer relative issues for you PR. diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 0000000..9f728c5 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 365 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +# exemptLabels: + # - pinned + # - security +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9b3749 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +node_modules +.DS_Store +npm-debug.log +yarn-debug.log +yarn-error.log +lerna-debug.log +npm-debug.log.* +yarn-debug.log.* +yarn-error.log.* +lerna-debug.log.* +lib +.idea +.vscode +examples/element-ui +examples/pages/en-US +examples/pages/zh-CN +examples/pages/es +examples/pages/fr-FR +fe.element/element-ui +.npmrc +coverage +waiter.config.js +build/bin/algolia-key.js +.envrc diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..4a38c75 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +sudo: false +language: node_js +node_js: 10 +addons: + chrome: stable +before_install: +- export TRAVIS_COMMIT_MSG="[deploy] $(git log --format='%h - %B' --no-merges -n 1)" +- export TRAVIS_COMMIT_USER="$(git log --no-merges -n 1 --format=%an)" +- export TRAVIS_COMMIT_EMAIL="$(git log --no-merges -n 1 --format=%ae)" +after_success: +- sh build/deploy-ci.sh +- cat ./test/unit/coverage/lcov.info | ./node_modules/.bin/coveralls diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md new file mode 100644 index 0000000..ddd1c39 --- /dev/null +++ b/CHANGELOG.en-US.md @@ -0,0 +1,1774 @@ +## Changelog + +### 2.15.1 + +*2021-02-23* + +#### Bug fixes + +- Drawer + - bugfix (by @cs1707) +- Image + - fix incorrect image object fit ratio in IE (#19583 by @charlie0228) +- Cascader + - fix cascader panel active path (#20730 by @cs1707) +- Calendar + - fix calendar component i18n bug (#20758 by @iamkun) +- ColorPicker + - fix bugs (by @UxieVerity) + +#### Optimization + +- Doc + - update Axure resource v2.1.0 (by @iamkun) + +### 2.15.0 + +*2021-01-15* + +#### Bug fixes + +- Select + - Fix placeholder i18n bug (#17644 by @nzh63) +- Popconfirm + - Popconfirm i18n bug by @iamkun) +- Drawer + - Fix focus bug (#20626 by @cs1707) +- Image + - Preview optimization (#20652 by @cs1707) + +#### Optimization + +- Doc + - Fix typo in french translation of datetime-picker.md (#20543 by @lonk) + - Add format attribute description to the progress component (#20641 by @cs1707) + +### 2.14.1 + +*2020-11-11* + +#### Bug fixes + +- Popover + - Compatible with Vue 2.6 new v-slot syntax (#20424 by @iamkun) + +#### Optimization + +- I18n + - Update Arabic translation (#20202 by @elkattan) + - Update Uighur translation (#20177 by @IlhamTahir) + +### 2.14.0 + +*2020-10-29* + +#### Breaking changes + +- Popconfirm + - Rename event name to `confirm`, `cancel` (#20240 by @hugiron) + +#### Bug fixes + +- Progress + - Fix attribute error (#19985 by @Caaalabash) + +#### Optimization + +- I18n + - Update Russian translation (#19451 by @yangirov) + - Update Khmer translation (#20077 by @Sovai) + - Update Ukrainian translation (#20344 by @MammutAlex) + +### 2.13.2 + +*2020-05-18* + +#### Bug fixes + +- Autocomplete + - Fix change event bug (#19200 by @sxzz) +- Image + - Update error status (#19194 by @lhx6538665) + +#### Optimization + +- I18n + - Update ru-RU popconfirm translation (#19220 by @Opppex) + - Update vi translation (#19244 by @quangln2810) + - Update Catalan and Spanish translations (#19296 by @Ismaaa) + - Update Indonesia translation (#19320) by @therour) + - Update Brazilian Portuguese translation (#19374 by @diegomengarda) + +### 2.13.1 + +*2020-04-13* + +#### New features +- Autocomplete + - Add change event (#17913 by @sxzz) + +#### Bug fixes + +- Autocomplete + - Fix suggestion error when textarea (#18478 by @Roojay) +- Carousel + - Fix console typo bug (#18264 by @IceFox) +- Image + - Fix preview dose not show when preview list not contain src issue (#18975) (#19130 by @luckyCao) + - Fix shortcut key not work at second time issue (#18983) (#19156 by @luckyCao) + - Don't show image-viewer when preview is false (#18967 by @inooNgt) +- Transfer + - Fix incorrect line-height of el-transfer's first list item when it was used with el-form-item (#18917 by @Hanx) +- InputNumber + - Correctly compute inputNumberDisabled (#18439 by @ashuser-pendo) +- Chore + - Remove index intro (#19155 by @iamkun) +- Doc + - Popconfirm doc update (#18324 by @iamkun) + - Fix step-strictly docs typo (#18705 by @dream2023) + - Fix a type error in document of steps component (#17555 by @haoranyu) + +### 2.13.0 + +*2019-11-26* + +#### New features + +- Popconfirm + - Add popconfirm component (#17548 by @iamkun) + +#### Bug fixes + +- BackTop + - Use cubic bezier scrolling (by @lon) +- DatePicker + - Fix bug of only select min date of date range problem (#17191 by @smk0621) +- Select + - Fix select test cases by (@msidolphin) +- Tree + - Add font-size for the style of tree empty-text (#17094 by @spengjie) +- Table + - Column header can be costumed (#17291 by @ziyoung) + - Update table header cell style (#17284 by @ziyoung) + - Fix table header height after filter (#17348 by @ziyoung) + - Fixed row-style with display not work (#17002 by @a631807682) + - Fix header table not display (#17341 by @ziyoung) +- Calendar + - Import el-button and el-button-group (#17376 by @masongzhi) +- MessageBox + - Fix icon position error (#17410 by @nullptru) +- TimePicker + - Set the selection range after scrolling up or down (#16868 by @mattheyan) +- Message + - Fix close instace offsetHeight(#17564) (#17852 by @gzwgq222) +- Form + - Callback of validateField should be optional (#17314 by @CarterLi) +- Cascader + - Fix TypeScript 3.7 compatibility (#17881 by @CarterLi) +- Menu + - Fix router NavigationDuplicated error when using vue-router@^3.1.0 (#17269 by @iamkun) +- Dropdown + - Update type file (#17550 by @iamkun) +- Progress + - Add strokeLinecap prop (#17552 by @iamkun) +- InfiniteScroll + - Skip trigger event on invisible element (#17553 by @iamkun) +- Image + - Perfect picture preview behavior (#16985 by @luckyCao) + - Fix shield the page when preview big image (#16796 by @luckyCao) +- Drawer + - Bugfix drawer-append-to-body-not-working (#16953 by @JeremyWuuuuu) +- Select + - Fix tag show value or empty issue (17199 by @luckyCao) +- Scrollbar + - Fix FireFox scroll bar width (#18091 by @iamkun) + +#### Optimization + +- I18n + - Update sv-SE.js (#17926 by @FOLLGAD) + - Update avatar component fr doc (#17762 by @blombard) +- Docs + - Fix time-select typo (#17250 by @wacky6) + - Fix Drawer attribute accepted value typo in es (#17122 by @haoranyu) + - Update Spanish changelog 2.12.0 (#17364 by @Gonzalo2310) + - Fix Changelog typo (#17874 by @renlixin) + - Fix Loading demo (#17862 by @MBearo) + - Add input event in input Events Table (#18061 by @zhouxinyong) + - Delete Input repeat change event (#18085 by @zhouxinyong) + +### 2.12.0 + +*2019-08-29* + +#### New features + +- Popover + - Add close-delay prop (#16671 by @LachlanStuart) +- Theme + - Add Chrome Extension: Element Theme Extension (#16686 by @iamkun) +- Icon + - Add font-display to @font-face declaration (#16805 by @iamfaizalandyka) + +#### Bug fixes + +- Carousel + - Fix onChange emit value (#16705 by @iamkun) +- Notification + - Fix modifying incoming option object (#16704 by @iamkun) +- DatePicker + - Add className for picker option (#16632 by @iamkun) +- DateTimePicker + - Fix time-spinner not scroll to right position (#16854 by @jesse-li) +- Table + - Prevent click handler after drag (#16850 by @ziyoung) + - Fix chrome crash when set thead css display to none (#16956 by @luckyCao) + - Fix wrong empty block height (#16861 by @ziyoung) + - Not throw error when calling toggleExpansion (#16304 by @yyjjqq94) + - Not trigger sort-change event when mounted (#17113 by @a631807682) + - Fix setCurrentRow unable to clear highlight row (#16879 by @ziyoung) + - Fix expand-row-keys not work when data is loaded asynchronously (#16899 by @ziyoung) + - set toggleAllSelection as instance property (#17137 by @ziyoung) +- Tree + - Fix distance between label and checkbox (#16799 by @Hazlank) +- Tabs + - Fix incorrect TabItem's position (#16520 by @victorting) + - Fix activated tab is out of visual range bug (#17033 by @nullptru) +- Calendar + - Fix weekdays i18n issue (#16772 by @ubitoffee) + - fix locale error (#17208 by @iamkun) +- Cascader + - Fix CascaderPanel display error (#16716 by @zhangHongEn) + - Fix disable status and close button issue (#16224 by @yyjjqq94) +- Input + - Fix Korean composition event (#15069 by @MoonHyuk) + - Fix click event of clear button not trigger when using v-loading (#16576 by @a631807682) +- Select + - Not toggle dropdown when filtering (#17205 by @luckyCao) +- Transfer + - Fix style error (#17206 by @iamkun) +- Dialog + - update sass var (#16365 by @haoranyu) +- RadioGroup + - Not produce invalid HTML in table if "is" attribute is specify (#17070 by @nullptru) +- Divider + - Support custom classes (#17078 by @island205) + +#### Optimization + +- Checkbox + - Improve screen reader experience (#16575 by @tylertrotter) +- Docs + - Update changelog (#16773 by @SimonaliaChen) + - Update contributing guide (#14800 by @sinchang) + - Fix typo in Drawer docs (#16848 by @winkay) + - Update custom theme (#16983 by @iamkun) + - Add Esperanto translation (#16955 by @maxkoryukov) + - Update input-number document about change event (#16316 by @luckyCao) + - Update spanish doc 2.11.1 (#16961 by @Gonzalo2310) +- I18n + - Remove translation of 'year' in catalan language as in the other languages (#14722 by @oscaralbareda) + - Update spanish changelog 2.10.0 and 2.10.1 (#16548 by @Gonzalo2310) + - Update ar.js (#16653 by @l3op) +- Test + - Correct spelling error (#16672 by @boomler) + - Refactor unit test to use data-uri (#16847 by @a631807682) +- Types + - Fix httprequest type (#16633 by @luckyCao) + +### 2.11.1 + +*2019-07-26* + +#### Bug fixes + +- Image + - Fix Image component SSR compatibility (#16737 by @luckyCao) +- Chore + - Update dart-sass compatibility (#16744 by @LewisChennnnn) + +### 2.11.0 + +*2019-07-25* + +#### New features + +- Drawer + - Add drawer component (#16577 by @JeremyWuuuuu) + +#### Bug fixes + +- Checkbox + - Enhance css selector (#16006 by @Hazlank) +- Tree + - Make el-tree generic (#15934 by @JeremyWuuuuu) + - Set isCurrent prop to False (#15870 by @kkkisme) +- Dropdown + - Fix split-button caret default color (#15931 by @JuniorTour) +- Cascader + - Fix level 1 children is empty update problem (#16399 by @luckyCao) + - Add sets default values when lazy is true (#16420 by @luckyCao) + - Fix display errors when node value is duplicate (#15935 by @junyiz) + - Expose getCheckedNodes and fix options change bug (#16709 by @SimonaliaChen) +- Calendar + - Display correct header when range is specified (#16354 by @ziyoung) +- Submenu + - Fix prop append-to-body (#16289 by @a631807682) +- Table + - Fix tree table when updating data (#16481 by @island205) +- Select + - Fix memory leak issue (#16463 by @island205) +- InfiniteScroll + - Update naming & doc (#16698 by @iamkun) +- Avatar + - Fix image not center vertically issue (#16489 by @luckyCao) +- Dialog + - Add destroyOnClose attribute (#16455 by @ziyoung) +- Image + - Add big Image preview feature (#16333 by @luckyCao) + +#### Optimization + +- Docs + - Fix dropdown demo (#16193 by @webxmsj) + - Fix typo in table documents (#15971 by @howiefh) +- I18n + - Update translation of Thai language (#16689 by @ponkrit) +- Chore + - Update theme base api (#16607 by @iamkun) + - Add form theme token (#16699 by @iamkun) + - Mark ali inner user's access (#16609 by @iamkun) + - Fix doc anchor bug (#16692 by @iamkun) + +### 2.10.1 + +*2019-07-02* + +#### Bug fixes + +- Table + - Fix sort icon (#15439 by @bezany) + - Fix layout breaks when append slot exists (#16332 by @ziyoung) + - Fix showOverflowTooltip not reactive (#16295 by @a631807682) + - Register scrollbar in filter-panel (#16246 by @ziyoung) +- Chore + - Fix 2.9 docs (#16233 by @ziyoung) + - Fix index page theme intro english css style issue (#16254 by @iamkun) + +#### Optimization + +- Tag + - Compatible with IE (#16334 by @ziyoung) +- Chore + - Update Dingtalk Group QR image (#16236 by @iamkun) +- Doc + - Update online theme roller doc (#16244 by @iamkun) + +### 2.10.0 + +*2019-06-25* + +#### New features + +- I18n + - Added Uzbek language (#15796 by @ogabek96) +- Calendar + - Add first-day-of-week attribute (#16047 by @ziyoung) +- Avatar + - Add avatar component (#16144 by @luckyCao) +- Upload: + - Add capability to customize thumbnail template (#13192 by @victorzhuk) + +#### Bug fixes + +- Tree + - Not highlight tree node when currentKey is null (#15668 by @yyjjqq94) + - Fix issue #15538 caused by two Tree sharing the same data (#15615 by @VanMess) +- Upload + - Update the parameter `fileList` type (#15716 by @underfin) +- Table + - Fix loading icon not display (#15868 by @ziyoung) + - Fix background color of complex table when hovering (#15504 by @cnlon) + - Fix current-row-key and select event bug (#15983 by @ziyoung) + - Height accepts more units (#16013 by @ziyoung) + - Fix reserve-selection not work (#16135 by @ziyoung) +- Docs + - Fix Divider attribute type in zh-cn (#15889 by @haoranyu) +- Menu + - Fixed submenu hidden bug after adding popper-append-to-body (#15391 by @PanJiaChen) +- Select + - Fix initialInputHeight (#15989 by @yyjjqq94) + - Fix default-first-option behavior when typing Chinese (#15431 by @VanMess) + - fix double import problem (#16215 by @lengband) +- Message + - Add type def for offset option (#16027 by @matjaz) +- Timeline + - Fix reverse broken (#16091 by @ziyoung) +- Slider + - Fix #15545 by adding explains about "input" event in Chinese (#15588 by @VanMess) +- InfiniteScroll + - Update package name (#16125 by @iamkun) +- MessageBox + - Fix  distinguishCancelAndClose action not same as docs bug (#15438 by @qingdengyue) +- PopupManager + - Fix z-index cannot be rewritten at first using (#15738 by @luckyCao) +- Docs + - Delete an incorrect closing html tag and empty block code (#16194 by @Alexeykhr) +- Chore + - Update test api host (#15807 by @iamkun) + +#### Optimization + +- Tree + - Modify loop conditions to improve performance (#15699 by @KingJeason) +- Theme + - Refine GA track & Update footer link forward to online theme roller (#16007 by @island205) +- Badge + - Update badge prop check (#16198 by @iamkun) +- Avatar + - Update theme config var (#16202 by @luckyCao) +- I18n + - Update pt-br.js (#15776 by @gigioSouza) + - Update Farsi translation (#15881 by @pamenary) +- Docs + - Add missing components in quickstart (#16063 by @pape2016) + - Update french translation (#16208 by @blombard) + - Add description $slots.default (#15444 by @Alexeykhr) + - Update Spanish Doc 2.9.1 (#15840 by @Gonzalo2310) + - Fix spelling mistakes in fr (#15837 by @blombard) + - Update changelog 2.9.2 Spanish (#16185 by @Gonzalo2310) + +#### Breaking changes + +- Form + - Remove success status (#16159 by @ziyoung) + +### 2.9.2 + +*2019-06-21* + +#### Bug fixes + +- Chore + - Fix TS definitions file (#15805 by @NateScarlet) + +### 2.9.1 + +*2019-05-30* + +#### New features + +- Table + - default-expand-all, expand-row-keys, toggle-row-expansion method and expand-change event are supported in Tree Table (#15709 by @ziyoung) + +#### Bug fixes + +- Table + - Fix some bugs (#15709 by @ziyoung) +- Theme + - Update api host (#15784 by @iamkun) + +#### Optimization + +- Chore + - Update InfiniteScroll type (#15794 by @iamkun) + +### 2.9.0 + +*2019-05-30* + +#### New features + +- Backtop + - Add Backtop component (#15541 by @iamkun) +- PageHeader + - Add PageHeader component (#15714 by @ziyoung) +- InfiniteScroll + - Add InfiniteScroll directive (#15567 by @iamkun) +- Cascader + - Add multiple mode and filter-method (#15611 by @SimonaliaChen) +- Message + - Display in stack mode (#15639 by @island205) +- Tag + - Add prop effect (#15725 by @SimonaliaChen) +- Tabs + - Left align title when type is card (#15695 by @luckyCao) +- DatePicker + - Support literal strings (#15525 by island205) +- Image + - Add support for transmit attrs and listeners (#15578 by @VanMess) +- Theme + - Add popup background (#15412 by @iamkun) +- Chore + - Update new 2.9.0 index page (#15682 by @iamkun) + +#### Bug fixes + +- Table + - Fix sort-change behaviour when sort condition is null (#15012 by @joelxr) +- Image + - Fix ssr and object-fit compatibility (#15346 by @SimonaliaChen) +- Input + - Fix show-word-count style in el-form (#15359 by @lvjiaxuan) + - Fix clear icon is not centered (#15354 by @YiiGuxing) +- Calendar + - Fix not correct day of week when the day is Sunday (#15399 by @qingdengyue) + - Fix October disappear bug (#15394 by @qingdengyue) +- Tabs + - Fix basic tab nested in card tab padding error (#15461 by @SimonaliaChen) +- Tag + - Fix stop propagation problem (#15150 by @infjer) +- Form + - Fix input-group within form-item height error (#15457 by @SimonaliaChen) + - Fix resetFields issue (15181 by @luckyCao) +- Tooltip + - Fix custom tabindex not work (#15619 by @SimonaliaChen ) +- Link + - Fix link icon style class (#15752 by @iamkun) +- Select + - Revert set value to null when cleared (#15447 by @iamkun) +- Loading + - Fix dom not change when loading state change quickly (#15123 by @FAKER-A) +- Switch + - Label with el-switch repeating event (#15178 by @FAKER-A) +- Slider + - Fix style problem when clicking slider bar(#15561 by @luckyCao) +- Radio + - Fix issue 14808 (#14809 by @OverTree) +- Form + - Fix resetFields issue (15181 by @luckyCao) +- Chore + - Upgrade dependencies and fix demo bug (#15324 by ziyoung) +- Type + - Fix loading type definition (#15635 by @iamkun) + - Fix Icon type (#15634 by @iamkun) + - Fix Link type definition (#15402 by @iamkun) + +#### Optimization + +- Cascader + - Refactor (#15611 by @SimonaliaChen) +- Chore + - Update make new component logic (by @iamkun) +- Docs + - Rename variable in docs (#15185 by @liupl) + - Fix image attribute type and default value (#15423 by @haoranyu) + - Fix form doc bug (#15228 by @SHERlocked93) + +### 2.8.2 + +*2019-04-25* + +#### Bug fixes + +- Icon + - Update icon (#15272 by @iamkun) +- Docs + - Fix Form and Input doc style (#15273 by @ziyoung) + +### 2.8.1 + +*2019-04-25* + +#### Bug fixes + +- Icon + - Update icon of cascader and select (#15264 by @SimonaliaChen) + - Update icon (#15258 #15268 by @iamkun) + +#### Optimization + +- Chore + - Update build script (#15267 by @ziyoung) +- Docs + - Fix link underline color (#15265 by @iamkun) +- Other + - Fix migrating config not compatible with camel case props and events (#15260 by @SimonaliaChen) + +### 2.8.0 + +*2019-04-25* + +#### New features + +- Divider + - Add divider component (#15055 by @island205) +- Rate + - Add custom colors and icon-classes by passing a object (#15051 by @SimonaliaChen) +- Link + - Add link component (#15052 by @iamkun) +- Calendar + - Add calendar component (#14908 by @ziyoung) +- Icon + - Add icon (#15214 by @iamkun) +- Alert + - Add dark theme (#15041 by @island205) +- Image + - Add image component (#15117 by @SimonaliaChen) +- Collapse + - CollapseItem can be disabled (#15076 by @ziyoung) +- Carousel + - Add direction attribute and support vertical direction (#15122 by @ziyoung) +- Pagination + - Add hide-on-single-page attribute (#15096 by @ziyoung) +- Slider + - Add marks attribute (#15133 by @luckyCao) +- Input + - Add show-word-count attribute (#15075 by @luckyCao) +- InputNumber + - Add step-strictly attribute (#15050 by @luckyCao) +- Tooltip, Dropdown, Popover + - Support tabindex attribute (#15167 by @ziyoung) + +#### Bug fixes + +- Notification + - Fix title word break (#15008 by @iamkun) +- Form + - Fix switching the rules in el-form not work (#14985 by @luckyCao) + - Fix label style (#14969 by @ziyoung) + - Required FormItem displays asterisk when label is auto (#15144 by @ziyoung) +- Pagination + - Fix slot not updated (#14711 by @lucyhao) +- Table + - Fix load bug in lazy mode (#15101 by @ziyoung) + - Fix cell width when colspan is grater than 1 (#15196 by @ziyoung) + - Improve performance (#14868 by @ziyoung) + - Don't emit triggers sort-change during initialization (#14625 by @PeanutWatson) + - Equal behaviour for height and max-height (#14660 by @arthurdenner) +- Dialog + - Fix dialog body correctly break long words (#15027 by @iamkun) +- Alert + - update type definition (#15186 by @ziyoung) +- Tabs + - Fix issue where Promise rejection was hitting application (#14816 by @ffxsam) + - Rerender when slot changes (#15238 by @ziyoung) +- Message + - Fix type definition (#14968 by @agoni1212) +- Select + - Fix error when value is undefined or null (#15022 by @luckyCao) +- Tree + - Delete current node after it removed (#14604 by @sinchang) + - Improve performance (#14881 by @ChenZhuoSteve) +- Dropdown + - Fix style (#14907 by @doing123) +- Slider + - Fix broken keyboard a11y bug (#14792 by @erezsob) +- Menu + - ActiveIndex value shall be null if defaultIndex does not exist(#14074 by @hoythan) +- Directive + - RepeatClick: use Date.now() instead of new Date() (#14776 by @pavelmash) +- Upload + - Fix Upload transparent picture display style (#15039 by @iamkun) +- Theme + - Add zero border (#15256 by @iamkun) + +#### Optimization + +- Chore + - Update changelog zh-cn (#14965 by @iamkun) + - Hide demo description when it's empty (#15014 by @ziyoung) + - Display dev server info by default by @iamkun) + - Fix 2.6.0 changelog error (#15026 by @iamkun) + - Update build config (#14821 by @abc3660170) + - Add hmr (#15221 by @SimonaliaChen) + - Use sourcemap in dev environment (#15087 by @ibufu) +Docs + - Rename variable in docs (#14602 #15003 #15094 #15105 by @liupl) + - Fix upload doc error (#15023 by @iamkun) + - Update Form custom validator doc (#15040 by @iamkun) + - Update Tabs docs to display vertical tabs (#15053 by @iamkun) + - Use eleme.cn as domain (#15139 by @ziyoung) + - Fix Image route name (#15194 by @iamkun) + - Remove duplicated fr translation (#15207 by @iamkun) + +#### Breaking changes + +- Rate + - Fix decimal display support in disabled mode (#15089 by @haoranyu) +- Select + - Use placeholder option label to set placeholder in filter mode (#14989 by @ibufu) + +### 2.7.2 + +*2019-04-03* + +#### Bug fixes + +- Form + - Fix auto `label-width` style (#14955 by @ziyoung) + +#### Optimization +- Docs + - Fix doc img link error (#14957 by @iamkun) +- Chore + - Fix deploy mkdir error (#14952 by @iamkun) + +### 2.7.1 + +*2019-04-03* + +#### Bug fixes + +- Select + - Set value to null when cleared (#14322 by @aaronfulkerson) +- Input + - Update DOM dependent values on type change (#14889 by @wacky6) +- Table + - Make `defaultExpandAll` works when expanded column exists (#14935 by @ziyoung) +- Dialog + - Background color can be configured (#14939 by @ziyoung) +- Form + - `label-width` supports auto width (#14944 by @ziyoung) + +#### Optimization +- Docs + - Update Spanish docs (#14913 by @Gonzalo2310) + - Add French doc for new component (#14924 by @ziyoung) + - Optimize Tabs docs (#14938 by @ziyoung) + +### 2.7.0 + +*2019-03-28* + +#### New features + +- Table + - Add support tree structure data (#14632 by @ziyoung) + +#### Bug fixes + +- Tabs + - Use primary color as boxShadow color (#14558 by @Richard-Choooou) + - Rerender when label changes (#14496 by @akki-jat) +- Table + - Footer follows body cell align (#14730 by @ziyoung) +- NavMenu + - Fix click el-submenu trigger childMenu pop again bug (#14443 by @PanJiaChen) +- Dropdown + - Make compatible with 2.6 new v-slot syntax (#14832 by @ziyoung) +- ColorPicker + - Fix handle error hex color string (#14793 by @iamkun) +- Tree + - Revert pr #13349 (#14847 by @ziyoung) +- Tooltip + - Display when initial value is true (#14826 by @ziyoung) +- Docs + - Update cascader docs (#14442 by @panhezeng) +- Style + - Fix media query in sm-only, md-only, lg-only (#14611 by @sinchang) + +#### Optimization + +- Chore + - Add webpage description (#14802 by @iamkun) + +### 2.6.3 + +*2019-03-21* + +#### Bug fixes + +- Fix Cascader demo style (#14789 by @ziyoung) +- Remove unnecessary DOM operation (#14788 by @ziyoung) +- Fix DatePicker default-value DST (#14562 by @wacky6) + +### 2.6.2 + +*2019-03-21* + +#### New features + +- DatePicker + - Add monthrange for type attribute (#14487 by @zxyRealm) +- i18n + - Add Croatian locale (#14360 by @danijelh) + +#### Bug fixes + +- Input + - Fix regression (#14572 by @wacky6) +- DatePicker + - Fix first-day-of-week computation (#14523 by @sinchang) + - Fix week picker's value-format (#13754 by @wacky6) +- Steps + - Fix issue #14502 (#14596 by @sinchang) + - Fix style with simple theme (#14610 by @sinchang) +- Docs + - Update french doc for 2.6.1 and fix typos (#14555 by @smalesys) + - Rename variable in Table docs (#14587 by @likwotsing) + - Add french search index (#14565 by @iamkun) + - Fix TimePicker page style (#14579 by @ziyoung) + - Rename variable in Upload docs (#14593 by @liupl) + - French translation update (#14643 by @smalesys) + - Update Form async validator docs (#14694 by @iamkun) + - Fix tooltip doc error (#14748 by @iamkun) + - Fix typo (#14751 by @2bj) + - Fix highlighting control elements for Webkit touch (#14703 by @VladG0r) + +#### Optimization + +- Chore + - Update ci build script (#14600 by @ziyoung) + - Update ga tracking (#14560 by @iamkun) + - Add more ga event (#14633 by @iamkun) + - Update discusion group (#14741 by @iamkun) + - Update test deps and conf (#14735 by @wacky6) + - Upgrade gulp (#14745 by @ziyoung) + - Use codepen to display demo & fix doc error (#14747 by @ziyoung) + +### 2.6.1 + +*2019-03-03* + +#### Bug fixes + +- **Don't specify node version** (by @iamkun in #14546) +- Fix doc directory in `deloy-faas.sh` (by @ziyoung in #14553) +- Fix date style issue in changelog for 2.6.0 (by @island205 in #14547) +- Fix doc typo (by @wack6 in #14552) + +### 2.6.0 + +*2019-03-01* + +#### New features +- Timeline + - Add timeline component (by @jikkai in #14248) +- DropdownItem + - Add icon prop to `el-dropdown-item` (by @gabrielboliveira in #14088) +- Input + - Add show-password props (by @phshy0607 in #13966) +- Select + - Add slot `empty` (by @elfman in #13785) +- Autocomplete + - Add highlight-first-item prop (by @YamenSharaf in #14269) +- I18n + - Created Armenian locale (by @hamletbarsamyan in #14214) +- Docs + - French translation (by @smalesys in #12153, #14418, #14434) + +#### Optimization +- Alert + - Update alert description default slot class (by @iamkun in #14488) +- Input + - Update input password (by @iamkun in #14480) +- InputNumber + - Remove unnecessary parseFloat (by @JuniorTour in #14172) +- Menu + - Add support for `el-menu-item` without index (by @georgyfarniev in #13298) +- Table + - Remove some html DOM operations (by @elfman in #13643) +- Upload + - Optimize code (by @elfman in #13973) +- Popup + - Optimize code (by @KAionro in #14413) +- Docs + - Add more detail about how to run play mode for contribution (by @island205 in #14355) + - Warn input as a controlled component (by @wacky6 in #14463) + - Update Table doc (by @luguokong in #14329) + - Update input doc (by @iamkun in #14437) + - Update custom-theme docs (by @wangguohao in #14297) + - Make the icon style change when hover on it (by @tuxinghuan in #14295) +- Build + - Minimizing css and js for Element doc site (by @iamkun in #14430) + - Speeding up webpack (by @hetech in #14484) + - Use cli to select release version (by @hetech in #14354) +- Install stale for issue handling (by @island205 in #14392) + +#### Bug fixes +- Menu + - Fix subMenu focus bug when switch browser tab (by @liupl in #13976) +- MessageBox + - Fix type definition (by @NateScarlet in #14278) +- ScrollBar + - Prevent right button click on thumb (by @xifeiwu in #14196) +- Switch + - Trigger form validation if value changes (by @hetech in #14426) +- Table + - Make toggleAllSelection method an instance method (by @letanure in #14075) +- Tabs & Dropdown + - Fix style (by @hetech in #14452) +- Tree + - Empty-text tips are different from tables (by @ColinCll in #14331) +- Docs + - Fix DatetimePicker format doc error (by @iamkun in #14290) + - Spelling issue in datepicker documentation (by @helmut in #14481) + - Fix pagination doc style (by @liuchuzhang in #14451) + +#### Breaking changes +- Table + - Fix params order of row events (by @jikkai in #12086) + +### 2.5.4 + +*2019-02-01* + +#### Bug fixes + +- Build: Fix babel config issue which lead to collapse transition broken (by @island205 in #14282) + +### 2.5.3 + +*2019-01-31* + +#### Optimization + +- Optimize code of Message (by @vok123 in #14029) +- Retire gh-pages (by @ziyoung in #14266) +- Add IssueHunt link (by @island205 in #14261) + +#### Bug fixes + +- Fix UMD module error on server side (by @island205 in #14242) +- Fix active TabBar style (by @iamkun in #14240) +- Fix Table demo code error (by @xunmeng in #14253) + +### 2.5.2 + +*2019-01-27* + +#### Optimization +- Docs: + - Update ChangeLog ES 2.5.1 (by @Gonzalo2310 in #14231) + +#### Bug fixes +- Build: + - Delete unremoved comments in umd module `lib/index.js` (by @island205 in #14233) + - Fix export error fired in commonjs module used in nuxt.js (by @island205 in #14232) + - Fix 2.5.1 build issues (by @iamkun in #14228) + +### 2.5.1 + +*2019-01-26* + +#### Optimization +- DatePicker: highlight current month and year (by @Debiancc in #14211) +- Update 2.5.0 changelog (by @wacky6 in #14217) + +#### Bug fixes +- Fix export issue generate by webpack upgrading (by @island205 in #14220) +- Keep 2.4.11 docs && new sub folder for 2.5+ (by @iamkun in #14222) + +### 2.5.0 + +*2019-01-25* + +#### New features +- DatePicker + - Add `validate-event` attribute (by @ziyoung in #13531) +- DateTimePicker + - `pickerOptions` support `selectableRange` option (by @eeeeeeeason) +- Tag + - Add `click` event (by @licdream in #14106) +- I18n + - support Kyrgyz language (by @zzjframework in #14174) + +#### Optimization +- Upgrade to webpack@4 (by @jikkai in #14173) +- Input + - Simplify implementation, follow one-way data flow. Fix several related bugs (by @wacky6 in #13471) +- Update Axure file,add new components (by @ziyoung in #13773) + +#### Bug fixes +- Autocomplete + - Fix dropdown's last line beging clipped (by @ziyoung in #13597) + - Fix missing popper arrow (by @liuchuzhang in #13762) +- Carousel + - Cleanup timer when component is destroyed (by @elfman in #13820) +- Cascader + - Remove deprecated property of computed props (by @iamkun in #13737) + - Fix CascaderOption's type definition in TypeScript (by @NateScarlet in #13613) + - Fix icon covering the text (by @ziyoung in #13596) +- Checkbox + - Refine style (by @PanJiaChen) +- DatePicker + - Add missing v-for `key` in TimeSpinner (by @Ende93 in #13547) + - Fix week highlight on year boundary (by @suyi91 in #13883) +- Input + - Fix textarea DOM node reference (by @laomu1988 @island205 in #13803) +- Pagination + - Input value won't be less than 1 (by @elfman in #13727) +- Popover + - Fix popover issues with hover trigger (by @goldengecko in #13104) + - Fix popper instance memory leak (by @qpxtWhite in #13988) +- Radio + - Refine style (by @ohhoney1) +- Table + - Enhanced table sorting when clicking on the sorting arrow (by @ohhoney1 in #12890) + - Fix empty text vertical alignment issue on IE10+ (by @imzjy in #13638) + - Fix index type documentation (by @ilovefafa in #13628) + - Fix `show-summary` display issue when multilevel header has fixed attr (by @luckyCao in #13914) +- Tabs + - Fix auto scroll bug (by @iamkun in #13696) + - Get the correct tab through tab name (by @iamkun in #13705) + - Use paneName instead of name to determine pane style (by @iamkun in #13733) +- Tree + - Fix `showCheckbox` prop on `Tree` can not affect their children `tree-node` (by @KidneyFlower) + - Update doc and definition file (by @ziyoung in #13540) +- Upload + - Add `url` prop to upload file when `list-type` changed (by @elfman in #13771) +- Slider + - Fix source code indentation (by @wacky6 in #13955) +- I18n + - Add missing Catalan translations (by @jaumesala) + - Add missing ru translation (by @justlp in #13658) + - Fix Finnish translations (by @jenkrisu in #14137) +- Doc + - Update Spanish doc 2.4.11 (by @Gonzalo2310 in #13522) +- Others + - Remove unnecessary script (by @ziyoung) + - Fix error anchor link (by @iamkun in #13753) + - Fix inconsistent capitalization in documentation (by @wonderjar) + - Add DingDing chat group qr code to readme (by @iamkun in #13957) + - Add yarn logs to .gitignore (by @mimimi in #13922) + - Remove sponsor duotai (by @island205 in #14156) + - Update readme qr code src (by @iamkun in #13960) + - Update CDN link, fix typo (by @ziyoung) + +### 2.4.11 + +*2018-11-21* + +- Revert pr #13296. Fixed clicking on Menu external causing Submenu collapsed, #13478 +- Adjust small screen (xs) media query breakpoints, #13468 (by @alekoshen712) + +### 2.4.10 + +*2018-11-16* + +- Fixed multiple clicks on Select to display the drop-down list, #13268 +- The clear icon for input is not displayed when Form is disabled, #13208 +- Adjust the style of Select, Progress, Autocomplete, Tooltip, Collaspe, TimePicker, #13188 (by @porcelainHeart) #13210 #13266 #13257 #13290 #13347 (by @PanJiaChen) +- Carousel component added `loop` attribute, #13217 +- When the data of Table changes, the highlighted line will remain, #13200 +- Table header scoped slot can receive parameters, #13263 +- Table's `clearFilter` method supports arguments, #13176 +- Tooltip is no longer created when there is no content in the Table cell, #13152 (by @rongxingsun) +- The input box contents of the ColorPicker panel can be displayed correctly, #13278 +- ColorPicker no longer triggers form validation when dragging, #13299 +- InputNumber added `select `method, #13286 (by @st-sloth) +- Autocomplete added `clear` event, #12171(by arthurdenner) #13326 +- You can close Menu by clicking on Menu outside, #13296 +- Form's `validateField` method can receive arguments, #13319 +- Cascader added `visible-change` event, #13415 +- DatePicker added range-separator slot, #13272 (by @milworm) +- Tree adds `iconClass` and `currentNodeKey` properties, #13337 #13197 (by @isnifer) +- Progress's` status` added text #13198 (by @ali-master) +- Fixing tree's `defaultCheckedKeys` caused an error, #13349 (by @dive2Pro) + +### 2.4.9 + +*2018-10-26* + +- The parameter of Form's `clearValidate` supports string, #12990 (by @codinglobster) +- Added type attribute for Badge, #12991 +- Users can use scoped-slot to customize table column header #13012 (by @ivanseidel) +- Fixed the input box of Select unable to type text under IE, #13034 (by @GaliMU) +- Select option does not wrap when space is enough, #12329 (by @akki-jat) +- When dropdown list of Select is expanded, the arrow icon will also display correctly, #12353 (by @firesh) +- Fixed that the size attribute of Select does not work, #13070 +- Select multiple values can be cleared, #13049 (by @ZSkycat) +- Fixed the last TabNav unable be deleted, #13039 +- Fixed that TabNav label is not displayed correctly, #13178 +- Added title slot for Alert, #13082 (by @Kingwl) +- Fixed an issue where the tooltip content in Table was incorrect, #13159 (by @elfman) +- Optimize the animation of Upload when file is deleted, #12987 +- Adjusted style of InputNumber when control button is not displayed, #13052 + +### 2.4.8 + +- Not displaying outline when Switch is focused, #12771 +- Fixed Dropdown's style in ButtonGroup, #12819 (by @bluejfox) +- Added opened event for Dialog, #12828 +- Fixed the incorrect display order of TabNav, #12846 +- Fixed the problem that Tabs did not scroll to the selected tab, #12948 +- Fixed the problem that the identifier does not display when the Tree node is dragged, #12854 +- The validate event parameter of Form contains the validation message, #12860 (by @YamenSharaf) +- Fixed DatePicker not to verify the validity of user input time, #12898 +- Fixed the problem that `render-header` attribute of Table header doesn't work, #12914 + +### 2.4.7 + +*2018-09-14* + +- Fixed DatePicker not triggering form validation, #12328 #12348 +- Fixed DatePicker throwing errors in multiple mode, #12347 +- Fixed incorrect position of DatePicker spinner, #12415 (by @rang-ali) +- Fixed automatic filling of DatePicker input box, #12521 (by @abdallanayer) +- Fixed Input not highlighted in Cascader, #12341 +- Fixed wrong order of Tabpane, #12346 +- Fixed incorrect position of ColorPicker cursor, #12376 (by @cnwhy) +- Fixed the style of Submenu, #2457 +- Fixed not highlighted after Submenu is selected, #12479 +- Fixed incorrect values selected by Cascader, #12508 (by @huangjinqiang) +- Fixed incorrect value of Pagination input box, #12525 +- Fixed order that Pagination triggers events, #12530 +- Fixed Table Filter not displayed, #12539 +- Fixed Tree unable to delete nodes, #12684 +- Fixed height of Select Input changing in single mode, #12719 +- Fixed style of FormItem label in nested Form, #12748 +- Added `autocomplete` attribute for Input, deprecated `auto-complete`, #12514 (by @axetroy) +- Added slots-scope for Form to display validation information, #12715 (by @YamenSharaf) + +### 2.4.6 + +*2018-08-09* + +- Fixed Table not showing filter icon when `filters` is assigned empty array, #12165 +- Fixed Menu not saving active state when `collapse` is changed, #12178 (by @elfman) +- Fixed Cascader not escaping special characters for Regexp, #12248 +- Fixed disabled RadioButton showing box-shadow when clicked, #12262 +- Fixed arrow key not effect when default value is `undefined`,#12322 +- Fixed query function of Select not debounced in multi mode, #12181 +- Fixed query keyword of Select disappearing in multi mode, #12304 +- Fixed incorrect width of Dialog when it is displayed in full screen, #12203 +- Fixed incorrect display of Main on IE, #12237 +- Fixed Input triggering two form validations, #12260 +- Fixed adding new Tree node causing nodes to disappear, #12256 +- Fixed Tree node not deleted after dragging, #12279 +- Fixed Popover not visible when InputNumber focuses, #12284 +- Added `popper-append-to-body` attribute for Autocomplete, #12241 +- Added `sync` modifier support for Pagination's `page-size` attribute, #12281 + +### 2.4.5 + +*2018-07-26* + +- Fixed Table setting `class-name` does not work for `expand` column, #12006 +- Added `toggleAllSelection` method for Table, #12047 +- Fixed wrong position of suffix slot when Input contains Select, #12108 +- Fixed `line-height` of Option unable to set, #12120 +- Fixed TimeSelect with default value of `null` could not be assigned after executing `resetField`, #12010 +- Fixed keydown event which is not arrow key does not work in Tree, #12008 +- Fixed parent node checked in lazy mode, #12106 +- Added `includeHalfChecked` parameter for getCheckedNodes of Tree, #12014 + +### 2.4.4 + +*2018-07-13* + +- Fixed triggering Select validation after Form resetting, #11837 +- Fixed wrong position of Input `suffix` slot when `suffix` slot with `append` slot, #11951 +- Fixed clearable Input still displaying the clear icon when readonly, #11967 +- Fixed Tree node checked when it's disabled, #11847 +- Fixed Tree's `default-checked-keys` not working, #11971 +- Fixed `empty-text` not visible when Tree node filtered, #11971 +- Fixed the position of oversized `empty-text` in Table, #11965 +- Fixed Table row not be unhighlighted when `current-row-key` is assigned to `null`, #11866 +- Fixed showing filter dropdown when `filters` is an empty array, #11864 +- Fixed Radio's label does not stop event propagation, #11912 + +### 2.4.3 + +*2018-07-03* + +- Fixed `allow-drop` not working properly when Tree nodes have a custom height, #11797 +- Now you can pass a parameter to the `clearValidate` method of Form, specifying which FormItems' validation results need to be cleared, #11821 +- Added `distinguishCancelAndClose` attribute for MessageBox, #11831 + +### 2.4.2 + +*2018-06-26* + +- Now `class-name` and `label-class-name` of Table are reactive, #11626 +- Fixed Table still highlighting clicked row when `highlight-current-row` is `false`, #11646 +- Fixed a style bug of ButtonGroup when it has only one `round` or `circle` Button, #11605 +- Fixed style of page size Select of Pagination, #11622 +- Fixed Menu's `open` method error when `collapse` is dynamically changed, #11646 +- Added `activeName` and `oldActiveName` parameters to the before-leave hook of Tabs, #11713 +- Fixed Cascader focused after outside clicked, #11588 +- Fixed Cascader not closing when option is clicked when `change-on-select` is true, #11623 +- Now updating Select's value programmatically will trigger form validation, #11672 + +### 2.4.1 + +*2018-06-08* + +- Removed Autocomplete's duplicate type declaration, #11388 +- Fixed Select's dropdown arrow style in FireFox when nested in Form, #11427 +- Fixed clear icon of Select still showing when the initial value is `null`, #11460 +- Fixed disabled radio showing box-shadow when clicked, #11462 +- Added `iconClass` attribute for MessageBox, #11499 +- Added `stretch` attribute for Tabs, #11476 +- Fixed rendering order issue of TabPane when Tabs is `lazy`, #11461 +- Fixed Table not retaining current highlight row when expanded, #11464 +- Fixed focusing state when `before-leave` returns a resolved promise, #11386 +- Fixed disabled Popover still creating poppers, #11426 +- Fixed Tree's endless loop when a new node is added in lazy mode, #11430 (by @wangjingf) +- Added `closed` event for Dialog, #11490 + +### 2.4.0 Fullerene + +*2018-05-28* + +#### New features +- General + - Dev tool and bundler is switched to native webpack, #11216 + - Now you can globally set the initial z-index of popups, #11257 +- Autocomplete + - Added `hide-loading` attribute, #11260 +- Button + - Now you can use the `size` attribute on circle buttons to control their sizes, #11275 +- InputNumber + - Added `precision` attribute, #11281 +- Tabs + - Added `before-leave` attribute, #11259 + - Added `lazy` attribute, #11167(by @Kingwl) +- Table + - Added `sort` method to manually sort the table, #11311 + +#### Bug fixes +- Input + - Fixed an issue that causes a re-render when using the Chinese IME to quickly input text, #11235 (by @STLighter) +- Popover + - Fixed the console error when the triggering element is Radio or Checkbox, #11265 +- Breadcrumb + - Fixed the `to` attribute not supporting dynamic update, #11286 +- Upload + - Fixed the console error when a File is resolved in the returned Promise of the `beforeUpload` method, #11297 (by @qusiba) +- Tooltip + - Fixed arrow not positioned correctly when content is empty, #11335 +- Autocomplete + - Fixed incorrect input suggestions after deleting keyword quickly, #11323 +- ColorPicker + - Fixed `active-change` event incorrectly triggering when picker dropdown is closed, #11304 +- Table + - Fixed style error of oversized filter panel, #11314 + - Fixed currently selected row not retained when the table is sorted, #11348 +- Checkbox + - Fixed single checkbox not supporting validation, #11271 +- Radio + - Fixed disabled Radio still being selected when pressing space key, #11303 +- MessageBox + - Fixed the `el-popup-parent--hidden` class not removed when opening MessageBox in succession, #11371 + +### 2.3.9 + +*2018-05-18* + +- Fixed when the source data does not have the field specified by a TableColumn's `prop` attribute, an error would occur when the mouse moves into that column's cells, #11137 +- The `lockScroll` attribute of pop up components no longer adds an inline style to the parent element, but instead adds a class name, #11114 +- Fixed the icon of Progress not displaying when its `status` is exception, #11172 +- Fixed options' `disabled` attribute not working in filterable Cascader's filter result list, #11185 +- Fixed an issue where Table's expanded row cannot be collapsed if the data source is updated after its expansion, #11186 +- `setCurrentKey` of Tree now accepts `null` as its param to cancel the currently highlighted node, #11205 + +### 2.3.8 + +*2018-05-11* + +- Fixed DatePicker panel jumping to the current month after picking a date in a non-current month when `type` is dates, #10973 +- Fixed clearable Input still displaying the clear icon when readonly, #10912 +- Fixed closing the DatePicker panel without changing the value incorrectly triggering the `change` event, #11017 +- Fixed keyboard navigation not working properly when Select has grouped options, #11058 +- Added `prefix` named slot for Select, #11063 +- Added `clearValidate` method for FormItem, #11076 +- Added `checkOnClickNode` attribute for Tree, #11111 + +### 2.3.7 + +*2018-04-29* + +- Fixed Table not updating its header widths when the scroll bar disappears due to filtering, #10834 +- Fixed clearable Input still showing the clear icon when its initial value is `null`, #10912 +- Fixed incorrect trigger of the `active-change` event after changing ColorPicker's binding value programatically, #10903 (by @zhangbobell) +- Fixed filterable Select causing an infinite loop when navigating options using keyboard if all options are disabled, #10945 + +### 2.3.6 + +*2018-04-21* + +- Fixed wrong behavior of Tree's `allow-drop` callback when `type` parameter is used, #10821 +- Now you can properly enter keywords in filterable single Select in IE11, #10822 +- Fixed single Select incorrectly triggering `blur` event after clicking an option, #10822 + +### 2.3.5 + +*2018-04-20* + +- Fixed incorrect highlights in DatePicker panel when `type` is week, #10712 +- Fixed InputNumber being empty when its initial value is 0, #10714 +- Added `automatic-dropdown` attribute for Select, #10042 (by @Seebiscuit) +- Fixed disabled Rate's value still being updated by navigation keys, #10726 (by @Richard-Choooou) +- Now DatePicker's `type` attribute can be `'dates'`, where you can pick multiple dates in one picker, #10650 (by @Mini256) +- Added `prev-click` and `next-click` events for Pagination, #10755 +- Added `pager-count` attribute for Pagination, #10493 (by @chongjohn716) +- Added `type` as the 3rd param of Tree's `allow-drop` attribute callback, #10792 +- Now we use ResizeObserver to detect DOM element resizing, #10779 + +### 2.3.4 + +*2018-04-12* + +- Deleted duplicate `showTimeout` attribute in SubMenu's TypeScript declaration, #10566 (by @kimond) +- Now you can customize Transfer's data item using scoped slot, #10577 +- Fixed clicking disabled prev and next button of Pagination still triggers `current-change` event, #10628 +- Fixed Textarea displaying `undefined` in SSR when its value is not set, #10630 +- Fixed disabled TabItem style when `type` is border-card, #10640 +- Added `$index` as `formatter`'s fourth param of Table, #10645 +- Fixed CheckboxButton not exported in TypeScript declaration, #10666 + +### 2.3.3 + +*2018-04-04* + +- Added `shadow` attribute for Card, #10418 (by @YunYouJun) +- Fixed Badge being hidden when `value` is `0`, #10470 +- Fixed some bugs of draggable Tree, #10474 #10494 +- Added `placement` for Autocomplete, #10475 +- Now `default-time` attribute also works in non-range DateTimePicker, #10321 (by @RickMacTurk) +- Removed the blue outline of TabItem after the browser blurs or is minimized, #10503 +- Added `popper-append-to-body` attribute for SubMenu, #10515 +- Removed visual feedback when hovering on non-link BreadcrumbItem, #10551 +- Fixed InputNumber's `change` event to ensure the component's binding value is updated in the event handler, #10553 + +### 2.3.2 + +*2018-03-29* + +- Fixed an Autocomplete regression, #10442 + +### 2.3.1 + +*2018-03-29* + +- Fixed a regression that `type` of Input is not passed down to the native input element, #10415 +- Added `blur` method for Select, #10416 + +### 2.3.0 Diamond + +*2018-03-28* + +#### New features +- Table + - Now `formatter` of TableColumn can be dynamically updated, #10184 (by @elfman) + - Added `select-on-indeterminate` attribute, #9924 (by @syn-zeta) +- Menu + - Added `collapse-transition` attribute, #8809 (by @limichange) +- Input + - Added `select` method, #10229 + - Added `blur` method, #10356 +- ColorPicker + - Added `predefine` attribute, #10170 (by @elfman) +- Tree + - Added `draggable`, `allow-drop` and `allow-drag` attributes, and `node-drag-start`, `node-drag-enter`, `node-drag-leave`, `node-drag-over`, `node-drag-end` and `node-drop` events, #9251 #10372 (by @elfman) +- Form + - `validate` method now has a second parameter, containing information of form items that failed the validation, #10279 + - Added `validate` event, #10351 +- Progress + - Added `color` attribute, #10352 (by @YunYouJun) +- Button + - Added `circle` attribute, #10359 (by @YunYouJun) + +#### Bug fixes +- Form + - Fixed label of FormItem not align with mixed Input, #10189 +- Menu + - Now collapsed Menu will only show the Tooltip when the `title` slot of MenuItem is set, #10193 (by @PanJiaChen) +- Pagination + - Fixed `current-change` event wrongly triggering without user interaction, #10247 +- DatePicker + - Now the date and time value in the dropdown panel are correctly formatted based on the `format` attribute, #10174(by @remizovvv) +- Upload + - Fixed `accept` attribute not working when `drag` is true, #10278 + +### 2.2.2 + +*2018-03-14* + +- Added `clear` event for Input, #9988 (by @blackmiaool) +- Now manual input of ColorPicker supports `hsl`, `hsv` and `rgb` modes, #9991 +- Fixed DatePicker not triggering `change` event when its initial value is cleared, #9986 +- Now icon class related attributes of Rate support dynamic updates, #10003 +- Fixed Table with fixed columns not updating its height correctly if `max-height` is set, #10034 +- Now DatePicker's range mode supports reverse selection (clicking the end date, then clicking the start date), #8156 (by @earlymeme) +- Added `disabled` attribute for Pagination, #10006 +- Added `after-enter` and ` after-leave` events for Popover, #10047 +- Fixed Select not triggering validation when user selects an option after executing `resetFields` of Form, #10105 +- Fixed incorrect widths of fixed columns of Table in some cases, #10130 +- Fixed MessageBox inheriting the `title` attribute of its previous instance when called without `title`, #10126 (by @Pochodaydayup) +- Added `input-size` attribute for Slider, #10154 +- Added `left-check-change` and `right-check-change` events for Transfer, #10156 + +### 2.2.1 + +*2018-03-02* + +- Fixed Aside, Header and Footer shrinking in some layout, #9812 +- Fixed Table with a `height` attribute not rendering in SSR, #9876 +- Fixed expandable Table not calculating its height when a row is expanded, #9848 +- Fixed `change` event not trigger when manually typing date in DateTimePicker, #9913 +- Fixed Select showing its options when the input box is right-clicked, #9894 (by @openks) +- Added `tooltip-class` attribute for Slider, #9957 +- Now Select will stay focused after selection, #9857 (by @Seebiscuit) +- Added `target-order` attribute for Transfer, #9960 + +### 2.2.0 Graphite + +*2018-02-12* + +#### New features +- Menu + - Added `popper-class` and `disabled` attributes for SubMenu, #9604 #9771 + - Horizontal Menu now supports multi-layered SubMenu, #9741 +- Tree + - Added `node-contextmenu` event, #9678 + - Now you can customize node template using scoped slot, #9686 + - Added `getNode`, `remove`, `append`, `insertBefore`, `insertAfter`, `getCheckedKeys`, `getHalfCheckedNodes`, `getHalfCheckedKeys` methods and `check` event, #9718 #9730 +- Transfer + - Added `clearQuery` method, #9753 +- Select + - Added `popper-append-to-body` attribute, #9782 + +#### Bug fixes +- Table + - Fixed clicking expanding icon of an expandable row triggers `row-click` event, #9654 + - Fixed layout not update when column width is changed by user dragging, #9668 + - Fixed style issue when summary row co-exists with fixed columns, #9667 +- Container + - Fixed container components not stretching in IE11, #9655 +- Loading + - Fixed Loading not showing when the value of `v-loading` is changed to true in the `mounted` hook, #9722 +- Switch + - Fixed two native click events are triggered when Switch is clicked, #9760 + +### 2.1.0 Charcoal + +*2018-01-31* + +#### New features +- Cascader + - Added `focus` and `blur` events, #9184 (by @viewweiwu) +- Table + - The `filter-method` now has a third param `column`, #9196 (by @liyanlong) +- DatePicker + - Added `prefix-icon` and `clear-icon` attributes, #9237 (by @AdamSGit) + - Added `default-time` attribute, #9094 (by @nighca) + - `value-format` now supports `timestamp`, #9319 (by @wacky6) +- InputNumber + - Now the binding value can be `undefined`, #9361 +- Select + - Added `auto-complete` attribute, #9388 +- Form + - Added `disabled` attribute, #9529 + - Added `validateOnRuleChange` attribute, #8141 +- Notificaition + - Added `closeAll` method, #9514 + +#### Bug fixes +- InputNumber + - Fixed value resetting when typing decimal point, #9116 +- Dropdown + - Fixed dropdown menu incorrect positioning when the page only has a horizontal scrollbar in some browsers, #9138 (by @banzhuanmei) +- Table + - Fixed an error in calculating number of fixed columns after the column data changes, #9188(by @kolesoffac) + - Fixed the border of the last column of the grouped header not properly displayed, #9326 + - Fixed incorrect positioning of table header in Safari, #9327 + - Fixed expanded row collapsing when the table data changes, #9462 + - Fixed unnecessary multiple renders in some conditions, #9426 + - Fixed column width calculation error when `width` of TableColumn changes, #9426 +- Loading + - Fixed Loading not hiding correctly in some conditions, #9313 +- DatePicker + - Fixed `focus` method not working in range mode, #9437 + - Fixed clicking the "now" button still selecting the current date even if it is disabled, #9470 (by @wacky6) + - Fixed date clamping when navigating, #9577 (by @wacky6) +- Steps + - Fixed style error in IE 11, #9454 + +#### Breaking changes +- Menu + - The popup menu in `collapse` mode now appends directly to `body`, so that it is visible when nested in Aside, #9263 +- Table + - Now checking the checkboxes in multi-selection Table doesn't trigger `row-click` event, #9467 +- Loading + - The `z-index` of non-fullscreen loading mask is changed to 2000. The `z-index` of fullscreen loading mask will update dynamically with the popup components, #9522 +- Dropdown + - `show-timeout` and `hide-timeout` attributes now only works when trigger is `hover`, #9573 + +### 2.0.11 + +*2018-01-08* + +- Fixed border color issue of Select when in `prepend` or `append` slot of Input, #9089 +- Fixed `remove-tag` event's parameter of Select, #9090 +- Added `show-timeout` and `hide-timeout` attributes for SubMenu, #8934 (by @HugoLew) +- Fixed missing Tooltip style of `show-overflow-tooltip` when Table is imported on demand, #9130 +- Fixed Table column's sorting malfunctioning after `clearSort` is executed on that column, #9100 (by @zEmily) +- i18n config file for Czech is renamed from `cz` to `cs-CZ`, #9164 + +### 2.0.10 + +*2017-12-29* + +- Fixed wrong max height calculation of Table when fixed column and summary row co-exist, #9026 +- Fixed uncompiled color style of empty text in Table, #9028 +- Now DatePicker only emits `change` event when value is truly changed, #9029 (by @remizovvv) +- Added `tabindex` attribute for Input, #9041 (by @dicklwm) + +### 2.0.9🎄 + +*2017-12-24* + +- Added `before-remove` hook function for Upload, #8788 (by @firesh) +- Fixed initial value of `error` not working for FormItem, #8840 +- Now Loading directive supports custom class name by assigning `element-loading-custom-class` attribute, #8826 (by @earlymeme) +- Fixed CarouselItem becoming invisible when data is asynchronously updated, #8921 +- Added `renderAfterExpand` attribute for Tree, #8972 + +### 2.0.8 + +*2017-12-12* + +- Added Spanish documentation +- Fixed `show-timeout` of Dropdown not working when trigger is click, #8734 (by @presidenten) +- Fixed Form validation timing for rules whose trigger is blur, #8776 +- Fixed blur event of ranged DatePicker, #8784 +- `format` of TimePicker now supports AM/PM, #8620 (by @firesh) + +### 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* + +- Improved accessibility for Cascader, Dropdown, Message, Notification, Popover, Tooltip and Tree +- Fixed Container resize when the width of viewport decreases, #8042 +- Fixed Tree's `updateKeyChildren` incorrectly deleting child nodes, #8100 +- Fixed bordered CheckboxButton's height when nested in a Form, #8100 +- Fixed Menu's parsing error for custom colors, #8153 (by @zhouyixiang) + +### 2.0.3 + +*2017-11-03* + +- Fixed `editable` and `readonly` attributes for ranged DatePicker, #7922 +- Fixed style error of nested Tabs, #7941 +- Fixed style error of the last Step of vertical Steps, #7980 +- Fixed trigger timing of `current-change` event for Pagination, #7995 +- Fixed unregistered Tooltip in Menu, #7995 + +### 2.0.2 + +*2017-10-31* + +- Now right-clicking the buttons of InputNumber won't change its value, #7817 +- `validate` method of Form can now wait for asynchronous validations before executing its callback, #7774 (by @Allenice) +- Fixed range selection of DatePicker not working in Chromium 53-57 browsers, #7838 +- Fixed missing preview and delete icons of Upload when its `list-type` is picture-card, #7857 +- Added `sort-by` attribute for TableColumn, #7828 (by @wangfengming) +- Fixed DatePicker sometimes displaying wrong year number when selecting the first week in week mode, #7860 (by @hh23485) +- Fixed icon style error of vertical Steps, #7891 +- The hot area for node arrows in Tree is expanded, #7891 + +### 2.0.1 + +*2017-10-28* + +- Fixed style error of RadioButton and CheckboxButton, #7793 +- Fixed TimePicker not respond to mouse scroll in some conditions, #7811 +- Fixed incomplete styles of some components when imported on demand, #7811 + +### 2.0.0 Carbon + +*2017-10-27* + +#### New features +- General + - A new theme: `theme-chalk` + - Accessibility of the following components are improved: Alert, AutoComplete, Breadcrumb, Button, Checkbox, Collapse, Input, InputNumber, Menu, Progress, Radio, Rate, Slider, Switch, Upload + - Added TypeScript typings + - All existing icons are redesigned. Some new icons are added + - Added a series of breakpoint-based utility classes that hide elements when the viewport size meets certain conditions + - Added layout components: Container, Header, Aside, Main, Footer + - Now you can configure component sizes globally. When importing Element, you can add a global config object with a `size` prop to configure default sizes for all components. +- Button + - Added `round` attribute. It's used for round-cornered Buttons #6643 +- TimeSelect + - Now can be navigated by `Up` and `Down`, and hitting `Enter` selects the time #6023 +- TimePicker + - Now can be navigated by arrow keys, and hitting `Enter` selects the time #6050 + - Added `start-placeholder` and `end-placeholder`. They're placeholders for the two input boxes in range mode #7169 + - Added `arrow-control` attribute to spin the time with arrows #7438 +- Tree + - Now child nodes don't render before the first expand #6257 + - Added `check-descendants` attribute. It determines if child nodes are checked when checking their parent node in `lazy` mode #6235 +- Tag + - Added `size` attribute #7203 +- Datepicker + - Now `timeFormat` can format the TimePicker when type is set to `datetimerange` #6052 + - Added `start-placeholder` and `end-placeholder`. They're placeholders for the two input boxes in range mode #7169 + - Added `value-format` attribute to customize the format of the binding value, #7367 + - Added `unlink-panels` attribute to unlink the two date panels when selecting a date range +- MessageBox + - Added `closeOnHashChange` attribute #6043 + - Added `center` attribute so that the content can be centered #7029 + - Added `roundButton` attribute to display round Buttons #7029 + - Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string* #6043 + - Added `inputType` attribute to assign type for the inner input box, #7651 +- Dialog + - Added `width`、`fullscreen`、`append-to-body` attributes. Now Dialog can be nested + - Added `center` attribute so that the content can be centered #7042 + - Added `focus-after-closed`、`focus-after-open` to improve accessibility #6511 +- ColorPicker + - Now you can type colors in the input box #6167 + - Added `size` and `disabled` attributes #7026 + - Added `popper-class` attribute #7351 +- Message + - Now color of the icons can be overridden by CSS #6207 + - Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string* #6207 + - Added `center` attribute so that the content can be centered #6875 +- Notification + - Added `position` attribute to configure where Notification pops up #6231 + - Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string* #6231 + - Added `showClose` attribute to hide the close button #6402 +- Rate + - Added `show-score` attribute to determine if current score is displayed #6295 +- Tabs + - Added `tab-position` attribute #6096 +- Radio + - Added `border` and `size` attributes #6690 +- Checkbox + - Added `border` and `size` attributes #6690 +- Alert + - Added `center` attribute so that the content can be centered #6876 +- Menu + - Added `background-color`, `text-color` and `active-text-color` attributes #7064 + - Added `open` and `close` methods to open and close SubMenu programmatically, #7412 +- Form + - Added `inline-message` attribute to determine if the validation message is displayed in inline style #7032 + - Added `status-icon` attribute to display a feedback icon when validated #7032 + - Form and FormItem now have a `size` attribute. Inner components will inherit this size if not specified on themselves, #7428 + - `validate` method will now return a promise if the callback is omitted, #7405 + - Added `clearValidate` method for clearing validating results for all form items, #7623 +- Input + - Added `suffix` and `prefix` named slots, `suffixIcon` and `prefixIcon` attributes to add contents inside the input box #7032 +- Breadcrumb + - Added `separator-class` attribute to support icons as item separators #7203 +- Steps + - Added `simple` attribute to activate simple-styled Steps #7274 +- Pagination + - Added `prev-text` and `next-text` attributes to customize texts of previous page and next page #7005 +- Loading + - Now you can customize spinner icon and background color with `spinner` and `background` prop, #7390 +- Autocomplete + - Added `debounce` attribute, #7413 +- Upload + - Added `limit` and `on-exceed` attributes to limit the amount of files, #7405 +- DateTimePicker + - Added `time-arrow-control` attribute to activate `arrow-control` of the nesting TimePicker, #7438 +- Layout + - Added a new breakpoint `xl` for viewport wider than 1920px +- Table + - Added `span-method` attribute for merging cells + - Added `clearSort` method to clear sorting programmatically + - Added `clearFilter` method to clear filter programmatically + - For expandable rows, when a row is expanded, a `.expanded` class will be added to its class list, so that you can customize its style + - Added `size` attribute + - Added `toggleRowExpansion` method to expand or collapse expandable rows programmatically + - Added `cell-class-name` attribute to assign class name for cells + - Added `cell-style` attribute to style cells + - Added `header-row-class-name` attribute to assign class name for header rows + - Added `header-row-style` attribute to style header rows + - Added `header-cell-class-name` attribute to assign class name for header cells + - Added `header-cell-style` attribute to style header cells + - TableColumn's `prop` attribute now accepts `object[key]` notations + - Added `index` attribute for TableColumn to customize row indices +- Select + - Added `reserve-keyword` attribute for reserving current search keyword after selecting an option + +#### Bug fixes +- DatePicker + - Fixed `v-model` returning the second day of the selected week in week mode #6038 + - Fixed the first input being cleared in `daterange` type #6021 +- DateTimePicker + - Fixed DateTimePicker and TimePicker affecting each other when picked #6090 + - Fixed hour and second can be beyond limit when selecting time #6076 +- TimePicker + - Fixed `v-model` not update correctly when blurred #6023 +- Dialog + - Fixed texts having blurry edges when opening and closing nesting dropdowns #6088 +- Select + - Improved performance. Now Vue dev-tool won't crash when a large number of Selects are destroyed #6151 +- Table + - Fixed a bug that Table remains hiding when its parent element appears from `display: none` + - Fixed Table expanding its width when its parent element has `display: flex` + - Fixed a bug that fixed columns of a Table with `append` slot would disappear when data is dynamically fetched + - Fixed `expand-row-keys` attribute not working with initial value + - Fixed filter failing when `data` updates + - Fixed a calculation error of fixed columns layout with grouped headers + - Fixed a dynamic `max-height` bug + - Fixed some style calculation errors + +#### Breaking changes +- General + - Removed `theme-default` + - Compatible with Vue 2.5.2+ and IE 10+ + - `change` event of form components and `current-change` event of Pagination now only trigger on user interaction + - `size` attribute of Button and form components now accept `medium`, `small` and `mini` + - To facilitate the use of third-party icons, `icon` attribute of Button and Steps, `prefix-icon` and `suffix-icon` attributes of Input now require a full class name +- Dialog + - Removed `size` attribute. Now the size of Dialog can be configured by `width` and `fullscreen` + - Now the visibility of Dialog cannot be controlled by `v-model` +- Rate + - `text-template` is renamed to `score-template` +- Dropdown + - `menu-align` is renamed to `placement`. Now it supports more positions +- Transfer + - `footer-format` is renamed to `format` +- Switch + - Attributes starting with `on-*` will be parsed to events in JSX, making all `on-*` attributes of Switch not + able to work in JSX. So `on-*` attributes are renamed to `active-*`, and accordingly `off-*` attributes are renamed to `inactive-*`. This change affects the following attributes: `on-icon-class`, `off-icon-class`, `on-text`, `off-text`, `on-color`, `off-color`, `on-value`, `off-value` + - `active-text` and `inactive-text` attributes now don't have default values +- Tag + - `type` attribute now accepts `success`, `info`, `warning` and `danger` +- Menu + - Removed `theme` attribute. The color of Menu can be configured using `background-color`, `text-color` and `active-text-color` +- Input + - Removed `icon` attribute. Now the suffix icon can be configured using `suffix-icon` attribute or `suffix` named slot + - Removed `on-icon-click` attribute and `click` event. Now to add click handler on icons, please use named slots + - `change` event now behaves like the native input element, which triggers only on blur or pressing enter. If you need to respond to user input in real time, you can use `input` event. +- Autocomplete + - Removed `custom-item` attribute. Now the template of input suggestions can be customized using `scoped slot` + - Removed `props` attribute. Now you can use `value-key` attribute to designate key name of the input suggestion object for display +- Steps + - Removed `center` attribute + - Now the Steps will fill its parent container by default +- DatePicker + - The params of DatePicker's `change` event is now the binding value itself. Its format is controlled by `value-format` +- Table + - Removed support for customizing column template using `inline-template` + - `sort-method` now aligns with `Array.sort`. It should return a number instead of a boolean + - `append` slot is moved outside the `tbody` element to avoid multiple rendering + - `expand` event is renamed to `expand-change` + - The params of `row-class-name` and `row-style` method is now an object + +## +* Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to [XSS attacks](https://en.wikipedia.org/wiki/Cross-site_scripting). So when `dangerouslyUseHTMLString` is on, please make sure the content of `message` is trusted, and **never** assign `message` to user-provided content. diff --git a/CHANGELOG.es.md b/CHANGELOG.es.md new file mode 100644 index 0000000..f88f2a1 --- /dev/null +++ b/CHANGELOG.es.md @@ -0,0 +1,1782 @@ +## Changelog + +### 2.15.1 + +*2021-02-23* + +#### Bug fixes + +- Drawer + - bugfix (by @cs1707) +- Image + - fix incorrect image object fit ratio in IE (#19583 by @charlie0228) +- Cascader + - fix cascader panel active path (#20730 by @cs1707) +- Calendar + - fix calendar component i18n bug (#20758 by @iamkun) +- ColorPicker + - fix bugs (by @UxieVerity) + +#### Optimization + +- Doc + - update Axure resource v2.1.0 (by @iamkun) +### 2.15.0 + +*2021-01-15* + +#### Bug fixes + +- Select + - Fix placeholder i18n bug (#17644 by @nzh63) +- Popconfirm + - Popconfirm i18n bug by @iamkun +- Drawer + - Fix focus bug (#20626 by @cs1707) +- Image + - Preview optimization (#20652 by @cs1707) + +#### Optimization + +- Doc + - Fix typo in french translation of datetime-picker.md (#20543 by @lonk) + - Add format attribute description to the progress component (#20641 by @cs1707) + +### 2.14.1 + +*2020-11-11* + +#### Bug fixes + +- Popover + - Compatible with Vue 2.6 new v-slot syntax (#20424 by @iamkun) + +#### Optimization + +- I18n + - Update Arabic translation (#20202 by @elkattan) + - Update Uighur translation (#20177 by @IlhamTahir) + +### 2.14.0 + +*2020-10-29* + +#### Breaking changes + +- Popconfirm + - Rename event name to `confirm`, `cancel` (#20240 by @hugiron) + +#### Bug fixes + +- Progress + - Fix attribute error (#19985 by @Caaalabash) + +#### Optimization + +- I18n + - Update Russian translation (#19451 by @yangirov) + - Update Khmer translation (#20077 by @Sovai) + - Update Ukrainian translation (#20344 by @MammutAlex) + +### 2.13.2 + +*2020-05-18* + +#### Corrección de errores + +- Autocomplete + - Arreglado el error cuando se daba el evento change (#19200 by @sxzz) +- Image + - Actualizado el estado de error (#19194 by @lhx6538665) + +#### Optimización + +- I18n + - Actualización de la traducción del popconfirm al Ruso (#19220 by @Opppex) + - Actualización de la traducción al vi (#19244 by @quangln2810) + - Actualización de la traducción al Catalán y al Español (#19296 by @Ismaaa) + - Actualización de la traducción al Indonesio (#19320) by @therour) + - Actualización de la traducción al Portugués Brasileño (#19374 by @diegomengarda) + + +### 2.13.1 + +*2020-04-13* + +#### Nuevas características +- Autocomplete + - Agregado el evento change (#17913 by @sxzz) + +#### Corrección de errores + +- Autocomplete + - Solucionado el error de la sugerencia en textarea (#18478 by @Roojay) +- Carousel + - Arreglado el error de escritura de la consola (#18264 by @IceFox) +- Image + - Solucionado el error de que no se mostraba el preview si no existía el src (#18975) (#19130 by @luckyCao) + - Arreglado el problema de que el shortcut key no funcionaba la segunda vez (#18983) (#19156 by @luckyCao) + - No muestra la imagen cuando preview es falso (#18967 by @inooNgt) +- Transfer + - Corregida la altura (line-height) incorrecta del primer elemento del el-transfer cuando era usado con el-form-item (#18917 by @Hanx) +- InputNumber + - Calculo correcto de inputNumberDisabled (#18439 by @ashuser-pendo) +- Tarea + - Se quito la introducción del index (#19155 by @iamkun) +- Documentación + - Actualización de la documentación de Popconfirm (#18324 by @iamkun) + - Arreglado el error tipográfico de la documentación de Fix step-strictly (#18705 by @dream2023) + - Corregido un type error en la documentación de steps component (#17555 by @haoranyu) + +### 2.13.0 + +*2019-11-26* + +#### Nuevas características + +- Popconfirm + - Agregado componente popconfirm (#17548 by @iamkun) + +#### Corrección de errores + +- BackTop + - Se usa cubic bezier para el scroll (by @lon) +- DatePicker + - Arreglado el fallo cuando solo se elegía fecha mínima en un rango de fechas (#17191 by @smk0621) +- Select + - Arreglado los casos de test del select (by @msidolphin) +- Tree + - Agregado font-size para el estilo del texto cuando esta vacío el tree (#17094 by @spengjie) +- Table + - La cabecera de la columna puede modificarse (#17291 by @ziyoung) + - Se actualizo el estilo de la cabecera de la tabla de la celda (#17284 by @ziyoung) + - Se soluciono el problema de height de la cabecera de la tabla después de un filtro (#17348 by @ziyoung) + - Corregido el estilo de la fila que con display no funcionaba (#17002 by @a631807682) + - Arreglado que la cabecera de la tabla no se mostraba (#17341 by @ziyoung) +- Calendar + - La importación de el-button y el-button-group (#17376 by @masongzhi) +- MessageBox + - Corregido el error de posición del icono (#17410 by @nullptru) +- TimePicker + - Establecido el rango de selección después de hacer scroll (#16868 by @mattheyan) +- Message + - Corregido el offsetHeight al cerrar la instancia(#17564) (#17852 by @gzwgq222) +- Form + - La función de llamada de validateField es opcional (#17314 by @CarterLi) +- Cascader + - Corregida la compatibilidad con TypeScript 3.7 (#17881 by @CarterLi) +- Menu + - Corregido el error de la ruta de navegación duplicada cuando se usaba vue-router@^3.1.0 (#17269 by @iamkun) +- Dropdown + - Actualización del tipo de archivo (#17550 by @iamkun) +- Progress + - Agregada la prop strokeLinecap (#17552 by @iamkun) +- InfiniteScroll + - Salto del disparo de evento en elementos invisibles (#17553 by @iamkun) +- Image + - Comportamiento perfecto de personalización de imágenes (#16985 by @luckyCao) + - Corregida la pagina cuando se hace preview de imágenes grandes (#16796 by @luckyCao) +- Drawer + - Corregido el fallo del append-to-body del drawer que no funcionaba (#16953 by @JeremyWuuuuu) +- Select + - Corregido: ahora muestra el tag o el valor vacío (17199 by @luckyCao) +- Scrollbar + - Arreglado el ancho del scroll en FireFox (#18091 by @iamkun) + +#### Optimización + +- I18n + - Actualizado sv-SE.js (#17926 by @FOLLGAD) + - Actualizada la documentación para francés para el componente avatar (#17762 by @blombard) +- Docs + - Arreglada la typografia de time-select (#17250 by @wacky6) + - Arreglado en Drawer, ahora el atributo value acepta tipografías en español (#17122 by @haoranyu) + - Actualización del Changelog 2.12.0 al español (#17364 by @Gonzalo2310) + - Arreglo de la tipografía del Changelog (#17874 by @renlixin) + - Arreglada la demo de Loading (#17862 by @MBearo) + - Agregado el evento input en los inputs de Table (#18061 by @zhouxinyong) + - Eliminado el evento repetitivo change de los input (#18085 by @zhouxinyong) + +### 2.12.0 + +*2019-08-29* + +#### Nuevas características + +- Popover + - Agregada la prop close-delay (#16671 by @LachlanStuart) +- Theme + - Añadida la extensión Chrome: Element Theme Extensión (#16686 by @iamkun) +- Icon + - Añadido font-display a la declaración @font-face (#16805 by @iamfaizalandyka) + +#### Corrección de errores + +- Carousel + - Corregido el valor emitido por onChange (#16705 by @iamkun) +- Notification + - Corrección de la modificación del objeto de opción entrante (#16704 by @iamkun) +- DatePicker + - Agregado el className para la opción picker (#16632 by @iamkun) +- DateTimePicker + - Corrección del time-spinner que no se desplazaba a la posición correcta (#16854 by @jesse-li) +- Table + - Evitar la propagación del click después del arrastre (#16850 by @ziyoung) + - Corregido una error en chrome que se producía cuando el css de thead tenia display: none (#16956 by @luckyCao) + - Corregida la altura incorrecta de los bloques vacíos (#16861 by @ziyoung) + - No hay lanzamiento de error cuando se llama a toggleExpansion (#16304 by @yyjjqq94) + - No se lanza el evento sort-change cuando esta montado (#17113 by @a631807682) + - Corregido que el setCurrentRow no borraba la linea resaltada (#16879 by @ziyoung) + - Corregido que expand-row-keys no funcionaba cuando los datos eran cargados asincrónicamente (#16899 by @ziyoung) + - Establecido toggleAllSelection como propiedad instanciada (#17137 by @ziyoung) +- Tree + - Corregida la distancia entre label y checkbox (#16799 by @Hazlank) +- Tabs + - Corregida la posición incorrecta de los item's del Tab (#16520 by @victorting) + - Corregido el error de que la pestaña activada estaba fuera del rango visual (#17033 by @nullptru) +- Calendar + - Arreglado el problema de los días de la semana con i18n (#16772 by @ubitoffee) + - Corregido el error de localización (#17208 by @iamkun) +- Cascader + - Corregido un error de visualización del CascaderPanel (#16716 by @zhangHongEn) + - Corregido el problema de disable status y close button (#16224 by @yyjjqq94) +- Input + - Arreglado el evento de composición coreana (#15069 by @MoonHyuk) + - Arreglado el evento click del botón clear que no se lanzaba cuando se usaba v-loading (#16576 by @a631807682) +- Select + - No cambiaba el dropdown cuando se filtraba (#17205 by @luckyCao) +- Transfer + - Arreglado un error de estilo (#17206 by @iamkun) +- Dialog + - Actualizada las variables Sass (#16365 by @haoranyu) +- RadioGroup + - No produce HTML invalido en la tabla si el atributo 'is' es especificado (#17070 by @nullptru) +- Divider + - Soporta clases personalizadas (#17078 by @island205) + +#### Optimización + +- Checkbox + - Mejorada la experiencia del lector de pantalla (#16575 by @tylertrotter) +- Docs + - Actualizado changelog (#16773 by @SimonaliaChen) + - Actualizada la guía de contribución (#14800 by @sinchang) + - Arreglado typo en la documentación de Drawer (#16848 by @winkay) + - Actualizado el tema personalizado (#16983 by @iamkun) + - Agregada traducción en Esperanto (#16955 by @maxkoryukov) + - Actualizada la documentación de input-number sobre el evento change (#16316 by @luckyCao) + - Actualizada la documentación en Español 2.11.1 (#16961 by @Gonzalo2310) +- I18n + - Eliminada la traducción de 'year' en idioma Catalán como en otros idiomas (#14722 by @oscaralbareda) + - Actualizado el changelog de las versiones 2.10.0 y 2.10.1 en Español (#16548 by @Gonzalo2310) + - Actualizado ar.js (#16653 by @l3op) +- Test + - Corregir error ortográfico (#16672 by @boomler) + - Refractorizacion del unit test para usar data-uri (#16847 by @a631807682) +- Types + - Corrección del tipo httprequest (#16633 by @luckyCao) + +### 2.11.1 + +*2019-07-26* + +#### Corrección de errores + +- Image + - Corregido el componente Image para compatibilidad SSR (#16737 by @luckyCao) +- Tarea + - Actualizado para compatibilidad con dart-sass by @LewisChennnnn) + +### 2.11.0 + +*2019-07-25* + +#### Nuevas características + +- Drawer + - Agregado componente drawer (#16577 by @JeremyWuuuuu) + +#### Corrección de errores + +- Checkbox + - Mejora del selector css (#16006 by @Hazlank) +- Tree + - Establecido el el-tree como genérico (#15934 by @JeremyWuuuuu) + - Establecido la prop isCurrent como False (#15870 by @kkkisme) +- Dropdown + - Corregido el color predeterminado de los split-button (#15931 by @JuniorTour) +- Cascader + - Corregido un problema de actualización cuando el nivel 1 de children estaba vació (#16399 by @luckyCao) + - Ahora se muestra correctamente header cuando range esta especificado (#16354 by @ziyoung) + - Agregados valores por defecto cuando lazy es true (#16420 by @luckyCao) + - Solucionado problemas de visualización (#15935 by @junyiz) + - Expuestos los getCheckedNodes y corrección de errores en el cambio de opciones (#16709 by @SimonaliaChen) +- Submenu + - Corregida la prop append-to-body (#16289 by @a631807682) +- Table + - Arreglado un fallo en la actualizacion de los datos de tree table (#16481 by @island205) +- Select + - Arreglado un problema de fuga de memoria (#16463 by @island205) +- InfiniteScroll + - Actualizada la nomenclatura y la documentacion (#16698 by @iamkun) +- Avatar + - Arreglado que la imagen no se centraba verticalmente (#16489 by @luckyCao) +- Dialog + - Agregado el atributo destroyOnClosee (#16455 by @ziyoung) +- Image + - Agregada la función de vista previa grande de imágenes (#16333 by @luckyCao) + +#### Optimización + +- Documentación + - Arreglada la demo de dropdown (#16193 by @webxmsj) + - Corrección de errores tipográficos en las tablas de documentos (#15971 by @howiefh) +- I18n + - Actualizada la traduccion del lenguage Thai (#16689 by @ponkrit) +- Tareas + - Actualizada la api base del tema (#16607 by @iamkun) + - Añadido token del formulario del tema (#16699 by @iamkun) + - Marcar todos los accesos internos del usuario (#16609 by @iamkun) + - Corrección del error de anclaje del documento (#16692 by @iamkun) + +### 2.10.1 + +*2019-07-02* + +#### Corrección de errores + + +- Table + - Corregido el icono de ordenación (#15439 by @bezany) + - Corregidas las rupturas del layout cuando existía un slot (#16332 by @ziyoung) + - Corregido showOverflowTooltip no era reactivo (#16295 by @a631807682) + - Registrada la scrollbar en el panel de filtro (#16246 by @ziyoung) +- Tareas + - Arreglada la documentación 2.9 (#16233 by @ziyoung) + - Corregido el índice de la página de introducción del tema en inglés que tenia un error en los estilos css (#16254 by @iamkun) + +#### Optimización + +- Tag + - Compatible con IE (#16334 by @ziyoung) +- Tarea + - Actualizada la imagen QR de Dingtalk Group (#16236 by @iamkun) +- Doc + - Actualizada la documentación online del theme roller (#16244 by @iamkun) + +### 2.10.0 + +*2019-06-25* + +#### Nuevas características + +- I18n + - Añadido idioma Uzbeko (#15796 by @ogabek96) +- Calendar + - Añadido el atributo del primer día de la semana (#16047 by @ziyoung) +- Avatar + - Agregado componente Avatar (#16144 by @luckyCao) +- Upload: + - Añade capacidad para personalizar la plantilla de miniaturas (#13192 by @victorzhuk) + +#### Corrección de errores + +- Tree + - No resaltar el nodo de árbol cuando currentKey es nulo (#15668 by @yyjjqq94) + - Solucionado el problema #15538 causado por dos Tree que compartian los mismos datos.(#15615 by @VanMess) +- Upload + - Actualizado el tipo del parámetro `fileList` (#15716 by @underfin) +- Table + - Solucionado que el icono de loading no se mostraba (#15868 by @ziyoung) + - Corregido el color de fondo de una tabla compleja cuando se desplaza el cursor (#15504 by @cnlon) + - Corregido current-row-key y el bug del evento select (#15983 by @ziyoung) + - Height acepta más unidades (#16013 by @ziyoung) + - Solucionado reserve-selection no funcionaba (#16135 by @ziyoung) +- Docs + - Corregido el tipo de atributo Divider en zh-cn (#15889 by @haoranyu) + - Se elimina una etiqueta html de cierre incorrecta y el código de bloque vacío (#16194 por @Alexeykhr) +- Menu + - Corregido un error oculto en el submenú después de añadir popper-append-to-body (#15391 by @PanJiaChen) +- Select + - Arreglado initialInputHeight (#15989 by @yyjjqq94) + - Corregido el comportamiento de default-first-option cuando se escribe chino (#15431 by @VanMess) + - Corregido el problema de importación doble (#16215 by @lengband) +- Message + - Añadida la opción type def para offset (#16027 by @matjaz) +- Timeline + - Arreglado reverso roto (#16091 by @ziyoung) +- Slider + - Corregido #15545 agregando explicaciones sobre el evento "input" en chino (#15588 by @VanMess) +- InfiniteScroll + - Actualización del nombre del paquete (#16125 by @iamkun) +- MessageBox + - Arreglado el bug de distinguishCancelAndClose, la acción no era la misma que la documentada (#15438 by @qingdengyue) +- PopupManager + - Arreglado que el z-index no podía ser reescrito la primera vez que se usaba (#15738 by @luckyCao) +- Tarea + - Actualizado el test del api host (#15807 by @iamkun) + +#### Optimizacion + +- Tree + - Modificar las condiciones del bucle para mejorar el rendimiento (#15699 by @KingJeason) +- Theme + - Refinado GA track & actualizado el link del pie que lleva al theme roller online (#16007 by @island205) +- Badge + - Actualizado el check del prop badge (#16198 by @iamkun) +- Avatar + - Actualizado el var del config del theme (#16202 by @luckyCao) +- I18n + - Actualizada la traducción del portugués (#15776 by @gigioSouza) + - Actualizada la traducción del idioma Farsi (#15881 by @pamenary) +- Docs + - Agregado componentes faltantes en el quick start (#16063 by @pape2016) + - Actualizada la traducción al francés (#16208 by @blombard) + - Agregada descripción $slots.default (#15444 by @Alexeykhr) + - Actualizada la Doc en Español 2.9.1 (#15840 by @Gonzalo2310) + - Corrección de errores ortográficos en fr (#15837 by @blombard) + - Actualizado el changelog 2.9.2 en español (#16185 by @Gonzalo2310) + +#### Breaking changes + +- Form + - Eliminado el estado success (#16159 by @ziyoung) + +### 2.9.2 + +*2019-06-21* + +#### Corrección de errores + +- Tareas + - Solucionadas las definiciones de archivos TS (#15805 by @NateScarlet) + +### 2.9.1 + +*2019-05-30* + +#### Nuevas características + +- Table + - Los metodos tree-props,default-expand-all, expand-row-keys, toggle-row-expansion y el evento expand-change son compatibles con Tree Table (#15709 by @ziyoung) + +#### Corrección de errores + +- Table + - Corrección de algunos errores (#15709 by @ziyoung) +- Theme + - Actualización del host de la api (#15784 by @iamkun) + +#### Optimización + +- Tarea + - Una actualización del tipo InfiniteScroll (#15794 by @iamkun) + +### 2.9.0 + +*2019-05-30* + +#### Nuevas características + +- Backtop + - Añadido componente Backtop (#15541 by @iamkun) +- PageHeader + - Añadido el componente PageHeader (#15714 by @ziyoung) +- InfiniteScroll + - Añadida la directiva InfiniteScroll (#15567 by @iamkun) +- Cascader + - Agregado modo múltiple y método de filtro (#15611 by @SimonaliaChen) +- Message + - Visualización en modo stack (#15639 by @island205) +- Tag + - Añadido prop effect (#15725 by @SimonaliaChen) +- Tabs + - Alinea el título a la izquierda cuando el tipo es card (#15695 by @luckyCao) +- DatePicker + - Soporta cadenas literales (#15525 by island205) +- Image + - Añadido soporte para transmitir attrs y listeners (#15578 by @VanMess) +- Theme + - Añadido fondo al popup (#15412 by @iamkun) +- Tarea + - Actualizada la nueva página de índice 2.9.0 (#15682 by @iamkun) + +#### Corrección de errores + +- Table + - Corregido el comportamiento de cambio de orden cuando la condición de orden es nula (#15012 by @joelxr) +- Image + - Corregido ssr y compatibilidad de ajuste de objetos (#15346 by @SimonaliaChen) +- Input + - Corregido estilo show-word-count en el-form (#15359 by @lvjiaxuan) + - Corregido el icono de borrar que no estaba centrado (#15354 by @YiiGuxing) +- Calendar + - Corregido día de la semana no correcto cuando el día es domingo (#15399 by @qingdengyue) + - Corregido error de desaparición de octubre (#15394 by @qingdengyue) +- Tabs + - Corrección de la pestaña básica anidada en el error de relleno de la pestaña de la tarjeta (#15461 by @SimonaliaChen) +- Tag + - Corregido problema de propagación de stop (#15150 by @infjer) +- Form + - Corregido el error de grupo de entrada dentro de la altura del elemento de formulario (#15457 by @SimonaliaChen) + - Solucionado el problema de resetFields (15181 by @luckyCao) +- Tooltip + - Corregido tabindex personalizado no funcionaba (#15619 by @SimonaliaChen ) +- Link + - Arreglada la clase de estilo del icono de enlace (#15752 by @iamkun) +- Select + - Revertir el valor establecido a nulo cuando se borra (#15447 by @iamkun) +- Loading + - Corregido dom no cambia cuando el estado de carga cambia rápidamente (#15123 by @FAKER-A) +- Switch + - Etiqueta con el evento de repetición del interruptor (#15178 by @FAKER-A) +- Slider + - Arreglado el problema de estilo al hacer clic en la barra deslizante (#15561 by @luckyCao) +- Radio + - Solucionado el problema 14808 (#14809 by @OverTree) +- Form + - Solucionado el problema de resetFields (15181 by @luckyCao) +- Tarea + - Se actualizaron las dependencias y se corrigió el error de demostración (#15324 by ziyoung) + - Type + - Corregida la definición del tipo de carga (#15635 by @iamkun) + - Corregido tipo Icono (#15634 by @iamkun) + - Corregida la definición del tipo de enlace (#15402 by @iamkun) + +#### Optimización + +- Cascader + - Refractorización (#15611 by @SimonaliaChen) +- Tarea + - Actualización hacer nueva lógica de componentes (by @iamkun) +- Documentación + - Renombrar variable en docs (#15185 by @liupl) + - Corregido el atributo type de imagen y el valor por defecto (#15423 by @haoranyu) + - Corregido error en la doc de form (#15228 by @SHERlocked93) + +### 2.8.2 + +*2019-04-25* + +#### Corrección de errores + +- Icon + - Actualizado icon (#15272 by @iamkun) +- Docs + - Arreglada la documentacion de Form e Input (#15273 by @ziyoung) + +### 2.8.1 + +*2019-04-25* + +#### Corrección de errores + +- Icon + - Actualizado el icono de cascader y select (#15264 by @SimonaliaChen) + - Actualizado icon (#15258 #15268 by @iamkun) + +#### Optimización + +- Chore + - Actualizado build script (#15267 by @ziyoung) +- Docs + - Arreglado el color underline de link (#15265 by @iamkun) +- Other + - Arreglada la migracion de la configuracion no compatible con camel case props y eventos (#15260 by @SimonaliaChen) + +### 2.8.0 + +*2019-04-25* + +#### Nuevas características + +- Divider + - Agregado el componente Divider (#15055 by @island205) +- Rate + - Agregados colores personalizados y clases de iconos pasando un objeto (#15051 by @SimonaliaChen) +- Link + - Agregado componente Link (#15052 by @iamkun) +- Calendar + - Agregado el componente Calendar (#14908 by @ziyoung) +- Icon + - Agregado Icon (#15214 by @iamkun) +- Alert + - Agregado tema dark (#15041 by @island205) +- Image + - Agregado componente image (#15117 by @SimonaliaChen) +- Collapse + - CollapseItem puede ser disabled (#15076 by @ziyoung) +- Carousel + - Agregado atributo direction y soporte para la direccion vertical (#15122 by @ziyoung) +- Pagination + - Agregado atributo hide-on-single-page (#15096 by @ziyoung) +- Slider + - Agregado atributo marks (#15133 by @luckyCao) +- Input + - Agregado attributo show-word-count (#15075 by @luckyCao) +- InputNumber + - Agregado atributo step-strictly (#15050 by @luckyCao) +- Tooltip, Dropdown, Popover + - Soporte para el atributo tabindex (#15167 by @ziyoung) + +#### Corrección de errores + +- Notification + - Arreglado el word break del titulo (#15008 by @iamkun) +- Form + - Arreglado que cuando se cambiaban las reglas en el-form no funcionaba (#14985 by @luckyCao) + - Arreglado el estilo del label (#14969 by @ziyoung) + - Los FormItem requeridos muestran astericos cuando el label es auto (#15144 by @ziyoung) +- Pagination + - Arreglado que el slot no se actualizaba (#14711 by @lucyhao) +- Table + - Arreglado un bug del load en el modo lazy (#15101 by @ziyoung) + - Arreglado el ancho de la celda cuando colspan es mayor que 1 (#15196 by @ziyoung) + - Mejora en el rendimiento (#14868 by @ziyoung) + - No se emiten disparadores del evento sort-change durante la inicializacion (#14625 by @PeanutWatson) + - Igual comportamiento para height y max-height (#14660 by @arthurdenner) +- Dialog + - Arreglado que el cuerpo del dialog quiebre las palabras correctamente en las palabras largas (#15027 by @iamkun) +- Alert + - Actualizada la definicion de type (#15186 by @ziyoung) +- Tabs + - Solucionado el problema por el que el rechazo de la promesa estaba afectando a la aplicación (#14816 by @ffxsam) + - Rerender cuando hay cambios en el slot (#15238 by @ziyoung) +- Message + - Actualizada la definicion de type (#14968 by @agoni1212) +- Select + - Solucionado el error cuando value es undefined o null (#15022 by @luckyCao) +- Tree + - Eliminar el nodo actual despues de removido (#14604 by @sinchang) + - Mejora en el rendimiento (#14881 by @ChenZhuoSteve) +- Dropdown + - Estilo arreglado (#14907 by @doing123) +- Slider + - Corrección de un fallo en el teclado a11y (#14792 by @erezsob) +- Menu + - El valor de ActiveIndex será nulo si el defaultIndex no existe (#14074 by @hoythan) +- Directive + - RepeatClick: usa Date.now() en lugar de new Date() (#14776 by @pavelmash) +- Upload + - Arreglado el estilo para mostrar imagenes transparentes (#15039 by @iamkun) +- Theme + - Agregado zero border (#15256 by @iamkun) + +#### Optimización + +- Tareas + - Actualizado changelog zh-cn (#14965 by @iamkun) + + - Ocultar la descripcion de la demo cuando esta vacia (#15014 by @ziyoung) + + - Muestra la info dev del server por defecto @iamkun) + + - Arreglado un error del changelog v2.6.0 (#15026 by @iamkun) + + - Actualizado build config (#14821 by @abc3660170) + + - Agregado hmr (#15221 by @SimonaliaChen) + + - Uso de sourcemap en entorno dev (#15087 by @ibufu) Docs + + - Cambio de nombre de variable en docs (#14602 #15003 #15094 #15105 by @liupl) + + - Arreglado un error en la documentacion de upload (#15023 by @iamkun) + + - Actualizada la documentacion del custom validator del Form (#15040 by @iamkun) + + - Actualizada la documentacion de Tabs de como mostrar tabs verticales (#15053 by @iamkun) + + - Uso del dominio eleme.cn (#15139 by @ziyoung) + + - Arreglado el nombre de la ruta de imágenes (#15194 by @iamkun) + + - Eliminada la traducción duplicada en francés (#15207 by @iamkun) + + + +#### Breaking changes + +- Rate + - Arreglado Fix decimal display support in disabled mode (#15089 by @haoranyu) +- Select + - Se usa la opcion placeholder del label para poner el placeholder en el modo filter (#14989 by @ibufu) + +### 2.7.2 + +*2019-04-03* + +#### Corrección de errores + +- Form + - Arreglado el estilo auto `label-width` (#14955 by @ziyoung) + +#### Optimización +- Docs + - Arreglado un error de link de una imagen (#14957 by @iamkun) +- Chore + - Arreglado un error de mkdir en el deploy (#14952 by @iamkun) + +### 2.7.1 + +*2019-04-03* + +#### Corrección de errores + +- Select + - Se asigna null a value cuando se limpia (#14322 by @aaronfulkerson) +- Input + - Actualiza los valores dependientes en el DOM cuando el tipo cambia (#14889 by @wacky6) +- Table + - Hacer que defaultExpandAll funcione cuando exista una columna expandida (#14935 by @ziyoung) +- Dialog + - El color de fondo puede ser configurado (#14939 by @ziyoung) +- Form + - `label-width` soporta auto width (#14944 by @ziyoung) + +#### Optimización +- Docs + - Actualización de la documentación en español (#14913 by @Gonzalo2310) + - Agregada documentación en francés para el nuevo componente (#14924 by @ziyoung) + - Documentación de los Tabs optimizada (#14938 by @ziyoung) + +### 2.7.0 + +*2019-03-28* + +#### Nuevas características + +- Table + - Agregado soporte de datos con estructura tree (#14632 by @ziyoung) + +#### Corrección de errores + +- Tabs + - Uso de color primario como boxShadow color (#14558 by @Richard-Choooou) + - Renderización cuando cambia la etiqueta (#14496 by @akki-jat) +- Table + - El pie de página sigue la alineación de las celdas del body (#14730 by @ziyoung) +- NavMenu + - Se ha corregido que al hacer click en el el-submenu se disparaba childMenu nuevamente (#14443 by @PanJiaChen) +- Dropdown + - Compatible con la nueva sintaxis de v-slot en V 2.6 (#14832 by @ziyoung) +- ColorPicker + - Corregido el manejo de error de string en hex color (#14793 by @iamkun) +- Tree + - Revertido pr #13349 (#14847 by @ziyoung) +- Tooltip + - Muestra cuando el valor inicial es verdadero (#14826 by @ziyoung) +- Docs + - Actualización de documentos de cascader (#14442 by @panhezeng) +- Style + - Corrección de la media query en sm-only, md-only, lg-only (#14611 by @sinchang) + +#### Optimización + +- Chore + - Añadido descripción de la página web (#14802 by @iamkun) + +### 2.6.3 + +*2019-03-21* + +#### Corrección de errores + +- Corrección del estilo de demostración de Cascader (#14789 by @ziyoung) +- Eliminación de la operación DOM innecesaria (#14788 by @ziyoung) +- Corrección del valor predeterminado del DST de DatePicker (#14562 by @wacky6) + +### 2.6.2 + +*2019-03-21* + +#### Nuevas características + +- DatePicker + - Añadido monthrange para el atributo type (#14487 by @zxyRealm) +- i18n + - Añadido Locale Croata (#14360 by @danijelh) +- Docs + - Actualización del documento en francés para 2.6.1 y corrección de errores tipográficos (#14555 by @smalesys) + - Actualización de la traducción al francés (#14643 by @smalesys) + +#### Corrección de errores + +- Input + - Corregida regresión (#14572 by @wacky6) +- DatePicker + - Corrección del cálculo del primer día de la semana (#14523 by @sinchang) + - Corregido el formato de valor del selector de semana (#13754 by @wacky6) +- Steps + - Corregida issue #14502 (#14596 by @sinchang) + - Arreglado estilo con tema simple (#14610 by @sinchang) +- Docs + - Renombrada variable en documentos de Table (#14587 by @likwotsing) + - Añadido índice de búsqueda en francés (#14565 by @iamkun) + - Corrección del estilo de página TimePicker (#14579 by @ziyoung) + - Renombrada variable en Upload docs (#14593 by @liupl) + - Actualización de los documentos del Form async validator (#14694 by @iamkun) + - Solucionado el error de tooltip doc (#14748 by @iamkun) + - Corregido error tipográfico (#14751 by @2bj) + - Corregido los elementos de control de resaltado para Webkit touch (#14703 by @VladG0r) + + +#### Optimización + +- Chore + - Actualización del script de construcción de ci (#14600 by @ziyoung) + - Actualización ga tracking (#14560 por @iamkun) + - Añadido más evento ga (#14633 by @iamkun) + - Actualización del grupo de discusión (#14741 por @iamkun) + - Actualización de los deps y conf de las pruebas (#14735 by @wacky6) + - Actualización gulp (#14745 by @ziyoung) + - Uso de codepen para mostrar la demo y corregir el error doc (#14747 por @ziyoung) + +### 2.6.1 + +*2019-03-03* + +#### Corrección de errores + +- **Don't specify node version** (by @iamkun in #14546) +- Corrección del directorio doc en `deloy-faas.sh` (by @ziyoung in #14553) +- Arreglado el estilo de date en changelog para 2.6.0 (by @island205 in #14547) +- Corregido error tipográfico en doc (by @wack6 in #14552) + +### 2.6.0 + +*2019-03-01* + +#### Nuevas características +- Timeline + - Agregado componente timeline (by @jikkai in #14248) +- DropdownItem + - Añadida la prop icon a `el-dropdown-item` (by @gabrielboliveira in #14088) +- Input + - Añadida la prop show-password (by @phshy0607 in #13966) +- Select + - Añadido el slot `empty` (by @elfman in #13785) +- Autocomplete + - Añadida la prop highlight-first-item (by @YamenSharaf in #14269) +- I18n + - Locale Armenio creado (by @hamletbarsamyan in #14214) +- Docs + - Traducción al francés (by @smalesys in #12153, #14418, #14434) + +#### Optimización +- Alert + - Actualizada la descripción de Alert (by @iamkun in #14488) +- Input + - Actualizado input password (by @iamkun in #14480) +- InputNumber + - Removido parseFloat innecesario (by @JuniorTour in #14172) +- Menu + - Añadido soporte para `el-menu-item` sin índice (by @georgyfarniev in #13298) +- Table + - Eliminadas algunas operaciones DOM html (by @elfman in #13643) +- Upload + - Optimizado el código (by @elfman in #13973) +- Popup + - Optimizado el código (by @KAionro in #14413) +- Docs + - Se han agregado más detalles sobre cómo ejecutar el modo de play para contribuir (by @island205 in #14355) + - Warn input como componente de control. (by @wacky6 in #14463) + - Actualizacion de la documentacion de Table (by @luguokong in #14329) + - Actualizacion de la documentacion de input (by @iamkun in #14437) + - Actualizacion de la documentacion de custom-theme (by @wangguohao in #14297) + - Se ha hecho que el icono cambie de estilo en hover (by @tuxinghuan in #14295) +- Build + - Minimización de css y js para la doc del sitio de Element (by @iamkun in #14430) + - Aceleración de webpack (by @hetech in #14484) + - Uso de cli para seleccionar la versión de lanzamiento (by @hetech in #14354) +- Instalación de stale para el manejo de issues (by @island205 in #14392) + +#### Corrección de errores +- Menu + - Corregido el error de focus del submenú cuando se cambiaba la pestaña del navegador (by @liupl in #13976) +- MessageBox + - Corregida la definicion de type (by @NateScarlet in #14278) +- ScrollBar + - Prevenido el clic del botón derecho en la miniatura (by @xifeiwu in #14196) +- Switch + - Activación de la validación de formularios si el valor cambia (by @hetech in #14426) +- Table + - Se ha convertido el método toggleAllSelection en un método de instancia (by @letanure in #14075) +- Tabs & Dropdown + - Estilo arreglado (by @hetech in #14452) +- Tree + - Los tips de texto vacío son diferentes de las tablas (by @ColinCll in #14331) +- Docs + - Corregido el error de formato de la documentacion de DatetimePicker (by @iamkun in #14290) + - Problema de ortografía en la documentación de datepicker (by @helmut in #14481) + - Arreglado estilo doc de paginación (by @liuchuzhang in #14451) + +#### Breaking changes +- Table + - Cambiar el orden de los parámetros enviados en los eventos de las filas (by @jikkai in #12086) + +### 2.5.4 + +*2019-02-01* + +#### Corrección de errores + +- Build: Se ha solucionado el problema de configuración de babel que provocaba que el efecto de transicion de collpase se rompiera (por @island205 en #14282) + +### 2.5.3 + +*2019-01-31* + +#### Optimización + +- Optimización del código de Message (por @vok123 en #14029) +- Retirada de gh-pages (por @ziyoung en #14266) +- Añadido enlace IssueHunt (por @island205 en #14261) + +#### Corrección de errores + +- Corregido el error del módulo UMD en el lado del servidor (por @island205 en #14242) +- Corregido el estilo activo de TabBar (por @iamkun en #14240) +- Corregido el error de código de demo de la tabla (por @xunmeng en #14253) + + +### 2.5.2 + +*2019-01-27* + +#### Optimización +- Docs: + - Actualizacion ChangeLog ES 2.5.1 (by @Gonzalo2310 in #14231) + +#### Corrección de errores +- Build: + - Eliminar comentarios no borrados en el módulo umd `lib/index.js` (por @island205 en #14233) + - Corregido el error de exportación disparado en el módulo commonjs usado en nuxt.js (por @island205 en #14232) + - Corrección de problemas de compilación de 2.5.1 (por @iamkun en #14228) + +### 2.5.1 + +*2019-01-26* + +#### Optimización +- DatePicker: resalta el mes y año actual (por @Debiancc en #14211) +- Actualizacion del changelog 2.5.0 (por @wacky6 en #14217) + +#### Corrección de errores +- Arreglado el problema de exportación generado por la actualización de webpack (por @island205 en #14220) +- Guardados los documentos 2.4.11 y la nueva subcarpeta para 2.5+ (por @iamkun en #14222) + +### 2.5.0 + +*2019-01-25* + +#### Corrección de errores +- Autocompletar + - Corregida la última línea del menú desplegable que comenzaba recortada (#13597) (por @ziyoung) + - Arreglada la popper arrow que faltaba (#13762) (por @liuchuzhang) +- Carrusel + - Contador de limpieza cuando el componente es destruido (#13820) (por @elfman) +- Cascader + - Retirada de los props computados obsoletos (#13737) (por @iamkun) + - Se corrigió la definición de tipo de las opciónes de Cascader en TypeScript (#13613) (por @NateScarlet) + - Corregido icono que cubre el texto (#13596) (por @ziyoung) +- Checkbox + - Refinado el estilo (por @PanJiaChen) +- DatePicker + - Añade el `key` en v-for de TimeSpinner (#13547) (por @Ende93) + - Corregido el resaltado de la semana en el límite del año (#13883) (por @suyi91) +- Input + - Corregida la referencia del nodo DOM del textarea (#13803) (por @laomu1988 @island205) +- Pagination + - El valor de entrada no será menor que 1 (#13727) (por @elfman) +- Popover + - Corrección de problemas de popover con el disparador de hover (#13104) (por @goldengecko) + - Corregido el fallo de memoria de instancia de popper (#13988) (por @qpxtWhite) +- Radio + - Refinado el estilo (por @ohhoney1) +- Table + - Mejorada la ordenación de tablas al hacer clic en la flecha de ordenación (#12890) (por @ohhoney1) + - Solucionado el problema de alineación vertical de texto vacío en IE10+ (#13638) (por @imzjjy) + - Corregida la documentación del tipo de índice (#13628) (por @ilovefafa) + - Corrección del problema de visualización de `show-summary` cuando el encabezado multinivel tiene el attr fixed (#13914) (por @luckyCao) +- Tabs + - Corregido error de autodesplazamiento (#13696) (por @iamkun) + - Obtener la tab correcta a través del nombre de tab (#13705) (por @iamkun) + - Uso de paneName en lugar de name para determinar el estilo del panel (#13733) (por @iamkun) +- Tree + - Corregido que `showCheckbox` prop en `Tree` no puede afectar a los hijos `tree-node` (por @KidneyFlower) + - Actualizado documento y archivo de definición (#13540) (por @ziyoung) +- Upload + - Agregada la prop `url` para subir el archivo cuando `list-type` cambia (#13771) (por @elfman) +- Slider + - Corrección de la sangría del código fuente (#13955) (por @wacky6) +- I18n + - Añadidas las traducciones de catalán que faltaban (por @jaumesala) + - Añadidas las traducciónes de ruso que faltaban (#13658) (por @justlp) + - Corrección de las traducciones al finés (#14137) (por @jenkrisu) +- Doc + - Actualización del documento 2.4.11 (#13522) (por @Gonzalo2310) +- Otros + - Eliminar scripts innecesarios (por @ziyoung) + - Corregido el error de anchor link (#13753) (por @iamkun) + - Corrección de la capitalización inconsistente en la documentación (por @wonderjar) + - Añadido código qr del grupo de chat DingDing al readme (by @iamkun in #13957) + - Añadido logs de hilo a .gitignore (#13922) (por @mimimi) + - Eliminada la cuota de patrocinadores (#14156) (por @island205) + - Actualizado readme qr code src (#13960) (por @iamkun) + - Actualizado enlace CDN, corregido error tipográfico (por @ziyoung) + +### 2.4.11 + +*2018-11-21* + +- Revertido pr #13296. Arreglado que al hacer clic fuera del Menú causaba que el Submenú colapsara, #13478 +- Ajustados los media query breakpoints de las pantallas pequeñas (xs), #13468 (por @alekoshen712) + +### 2.4.10 + +*2018-11-16* + +- Se corrigio que se necesitaban varios clics en Select para mostrar la lista desplegable, #13268 +- El icono de limpiado para el input no se muestraba cuando Form estaba deshabilitado, #13208 +- Ajustados los estilos de Select, Progress, Autocomplete, Tooltip, Collaspe, TimePicker, #13188 (by @porcelainHeart) #13210 #13266 #13257 #13290 #13347 (by @PanJiaChen) +- Se agregó el atributo `loop` al componente carrusel, #13217 +- Cuando los datos de Table cambian, la línea resaltada permanecerá, #13200 +- Table header scoped slot puede recibir parámetros, #13263 +- El método `clearFilter` de la tabla soporta argumentos, #13176 +- El tooltip ya no se crea cuando no hay contenido en la celda de Table, #13152 (por @rongxingsun) +- El contenido del input del panel ColorPicker se muestra correctamente, #13278 +- ColorPicker ya no activa la validación de formularios al arrastrar, #13299 +- InputNumber se le ha añadido el método `select`, #13286 (por @st-sloth) +- Autocompletar agregó el evento `clear`, #12171(by arthurdenner) #13326 +- Puede cerrar Menú haciendo clic fuera del Menú, #13296 +- El método `validateField` de Form puede recibir argumentos, #13319 +- Cascader añadió el evento `visible-change`, #13415 +- DatePicker agregó slot para separador de rango, #13272 (por @milworm) +- Tree añade las propiedades `iconClass` y `currentNodeKey`, #13337 #13197 (por @isnifer) +- Progress permite texto en el atributo `status` #13198 (por @ali-master) +- Corregidas las `defaultCheckedKeys` de Tree que causaba un error, #13349 (por @dive2Pro) + + +### 2.4.9 + +*2018-10-26* + +- El parámetro de Form's `clearValidate` soporta cadenas, #12990 (by @codinglobster) +- Se agregó el atributo `type` para Badge, #12991 +- Ser puede usar scoped-slot para personalizar el encabezado de la columna de Table #13012 (por @ivanseidel) +- Arreglado que el input box de Select no se podia escrbir en IE, #13034 (by @GaliMU) +- La opción Seleccionar no se cerraba cuando el espacio era insuficiente, #12329 (by @akki-jat) +- Cuando se expande la lista desplegable de Seleccionar, el icono de flecha también se mostrará correctamente, #12353 (by @firesh) +- Arreglado que el atributo size de Select no funcionaba, #13070 +- Select multiple values pueden ser limpiado en lote, #13049 (by @ZSkycat) +- Arreglado el último TabNav que no se podía borrar, #13039 +- Arreglado que la etiqueta del TabNav no se mostraba correctamente, #13178 +- Añadido title slot para Alert, #13082 (by @Kingwl) +- Corregido un problema por el cual el contenido del tooltip en Table era incorrecto, #13159 (by @elfman) +- Optimizada la animación de Upload cuando el archivo es eliminado, #12987 +- Ajustado el estilo de InputNumber cuando no se muestra el botón de control, #13052 + +### 2.4.8 + +- No se muestra el contorno cuando Switch está enfocado, #12771 +- Arreglado el estilo del Dropdown en ButtonGroup, #12819 (por @bluejfox) +- Añadido evento opened para Dialog, #12828 +- Corregido el orden incorrecto de visualización de TabNav, #12846 +- Corregido el problema de que Tabs no se desplazaba a la pestaña seleccionada, #12948 +- Corregido el problema de que el identificador no se mostraba cuando se arrastraba el Tree node, #12854 +- El parámetro validar evento de Form contiene el mensaje de validación, #12860 (por @YamenSharaf) +- Se ha corregido el DatePicker que no verificaba la validez de la hora de entrada del usuario, #12898 +- Arreglado el problema de que el atributo `render-header` del encabezado de Table no funcionaba, #12914 + +### 2.4.7 + +*2018-09-14* + +- Corregido que DatePicker no activaba la validación del Form, #12328 #12348 +- Corregidos el lanzamiento de errores del DatePicker en modo múltiple, #12347 +- Corregida la posición incorrecta del spinner del DatePicker, #12415 (por @rang-ali) +- Se ha corregido el llenado automático del input del DatePicker, #12521 (por @abdallanayer) +- Corregida el input no resaltada en Cascader, #12341 +- Corregido el orden incorrecto de Tabpane, #12346 +- Corregida la posición incorrecta del cursor de ColorPicker, #12376 (por @cnwhy) +- Corregido el estilo del Submenú, #2457 +- Corregido el resaltado después de seleccionar el Submenú, #12479 +- Corregidos los valores incorrectos seleccionados por Cascader, #12508 (por @huangjinqiang) +- Corregido el valor incorrecto del input de Paginación, #12525 +- Se ha corregido el orden en que la paginación desencadena los eventos, #12530 +- Corregido que no se mostraba el Table Filter, #12539 +- Corregido Tree que era incapaz de borrar nodos, #12684 +- Corregida la altura de los Select Input que cambiaba en modo simple, #12719 +- Arreglado el estilo de la etiqueta FormItem en Form anidado, #12748 +- Añadido el atributo `autocomplete` para Input, obsoleto `auto-complete`, #12514 (por @axetroy) +- Añadido el slots-scope de Form para mostrar la información de validación, #12715 (por @YamenSharaf) + +### 2.4.6 + +*2018-08-09* + +- Arreglada la tabla que no mostraba el ícono del filtro cuando a `filter` se les asignaba un array vacío, #12165 +- Arreglado Menu que no guardaba el estado activo cuando cambiaba `collapse` #12178 (por @elfman) +- Se ha corregido que Cascader no escapaba a los caracteres especiales para Regexp, #12248 +- Se ha corregido que el RadioBotón deshabilitado mostraba la sombra de la caja cuando se hacía clic, #12262 +- Arreglado el efecto de la tecla de flecha en Select cuando el valor por defecto es `undefined`,#12322 +- Corregida la función de consulta de Select not debounced en modo multi, #12181 +- Corregida que la palabra clave de consulta de Select desaparecía en modo multi, #12304 +- Corregido el ancho incorrecto de Dialog cuando se muestra a pantalla completa, #12203 +- Corregida la visualización incorrecta de Main en IE, #12237 +- Corregido el trigger de Input con dos validaciones de Form, #12260 +- Arreglado el añadir un nuevo nodo de árbol que causaba que los nodos desaparecieran, #12256 +- Arreglado el nodo Tree no se borraba después de arrastrar, #12279 +- Popover corregido porque no era visible cuando InputNumber no enfocaba, #12284 +- Añadido el atributo `popper-append-to-body` para Autocompletar, #12241 +- Añadido el modificador `sync` para el atributo `page-size` de Pagination, #12281 + +### 2.4.5 + +*2018-07-26* + +- Se ha corregido en Table que `class-name` no funcionaba para las columnas `expand`, #12006 +- Se ha añadido el método `toggleAllSelection` para Table, #12047 +- Corregida la posición incorrecta del `suffix slot` cuando Input contiene Select, #12108 +- Corregido que el `line-height` de Option no se establecia, #12120 +- Corregido que TimeSelect con valor por defecto `null` no podia ser asignado después de ejecutar `resetField`, #12010 +- Arreglado el evento `keydown` que cuando no era una tecla de flecha no funciona en Tree, #12008 +- Corregido nodo padre checked en modo lazy, #12106 +- Añadido el parámetro `includeHalfChecked` para getCheckedNodes de Tree, #12014 + +### 2.4.4 + +*2018-07-13* + +- Corregido que se disparaba la validacion del Select después de reajustar el formulario, #11837 +- Corregida la posición incorrecta del slot Input `suffix` cuando se usaba el slot `suffix` con el slot `append` , #11951 +- Corregido el clearable Input que muestraba el icono de borrado cuando era readonly, #11967 +- Arreglado el nodo Tree checked cuando estaba disabled, #11847 +- Corregido que `default-checked-keys` no funcionaba en Tree, #11971 +- Corregido que el `empty-text` no era visible cuando el nodo Tree se filtraba, #11971 +- Arreglada la posición de texto vacío sobredimensionado en Table, #11965 +- Corregido que la fila de la tabla no se modificado el resaltado cuando `current-row-key` era asignada a null, #11866 +- Arreglado que mostraba el filtro del dropdown cuando los filtros eran un array vacío, #11864 +- Corregido que el cambio de label de Radio no detenia propagacion de eventos, #11912 + +### 2.4.3 + +*2018-07-03* + +- Corregido `allow-drop` que no funcionaba correctamente cuando los nodos de árbol tenian una altura personalizada, #11797 +- Ahora puede pasar un parámetro al método `clearValidate` de Form, especificando qué resultados de validación de `FormItems` necesita borrar, #11821 +- Añadido el atributo `distinguishCancelAndClose` para MessageBox, #11831 + +### 2.4.2 + +*2018-06-26* + +- Ahora el `class-name` y el `label-class-name` de la tabla son reactivos, #11626 +- Arreglado que Table seguia resaltando la fila en la que se había hecho clic cuando `highlight-current-row` era `false`, #11646 +- Corregido un error de estilo de ButtonGroup cuando sólo habia un botón `round` o `circle`, #11605 +- Arreglado estilo del tamaño de página del Select de Pagination, #11622 +- Corregido un error del método `open` de los Menús cuando se cambiaba dinámicamente `collapse`, #11646 +- Añadidos los parámetros `activeName` y `oldActiveName` al gancho before-leave de Tabs, #11713 +- Arreglado el focus en Cascader después de hacer clic fuera, #11588 +- Arreglado que Cascader no se cerraba cuando se hacia clic en la opción estando `change-on-select` como `true`, #11623 +- Ahora la actualización del valor de Select programáticamente activará la validación de formulario, #11672 + +### 2.4.1 + +*2018-06-08* + +- Removida la declaración duplicada de type en Autocompletar, #11388 +- Corregido el estilo de flecha en el dropdown de Select en FireFox cuando se anidaba en el formulario, #11427 +- Corregido que el ícono `clear` de Select seguia apareciendo cuando el valor inicial era `null`, #11460 +- Arreglado que cuando el radio estaba `disabled` mostraba el box-shadow al hacer click, #11462 +- Añadido el atributo `iconClass` para MessageBox, #11499 +- Añadido el atributo `stretch` para Tabs, #11476 +- Arreglado el problema de orden de renderizado de TabPane cuando Tabs es `lazy`, #11461 +- Arreglado que Table no retenia la fila actual de resaltados cuando se expandia, #11464 +- Arreglado que focusing state cuando `before-leave` devolvia una promesa resuelta, #11386 +- Arreglado que Popover deshabilitado seguia creando poppers, #11426 +- Arreglado el bucle sin fin de Tree cuando se añadia un nuevo nodo en modo `lazy`, #11430 (por @wangjingf) +- Añadido el evento `closed` para Dialog, #11490 + +### 2.4.0 Fullerene + +*2018-05-28* + +#### Nuevas características +- Generalidades + - La herramienta de desarrollo y el empaquetador se cambiaron a webpack nativo, #11216 + - Ahora puede configurar globalmente el z-index inicial de los popups, #11257 +- Autocomplete + - Añadido el atributo `hide-loading`, #11260 +- Button + - Ahora se puede usar el atributo `size` en los botones circulares para controlar sus tamaños, #11275 +- InputNumber + - Añadido el atributo `precision`, #11281 +- Tabs + - Añadido el atributo `before-leave`, #11259 + - Añadido el atributo `lazy`, #11167(by @Kingwl) +- Table + - Añadido el método `sort` para ordenar manualmente la tabla, #11311 + +#### Corrección de errores +- Input + - Se ha corregido un problema que provocaba que se volviera a procesar al utilizar el IME chino para introducir texto rápidamente, #11235 (por @STLighter). +- Popover + - Corregido el error de la consola cuando el elemento disparador es Radio o Checkbox, #11265 +- Breadcrumb + - Arreglado el atributo `to` que no soportaba la actualización dinámica, #11286 +- Upload + - Corregido el error de la consola cuando se resolvia el Archivo en la Promesa devuelta del método `beforeUpload`, #11297 (por @qusiba) +- Tooltip + - Solucionado que la flecha no se posicionaba correctamente cuando el contenido estaba vacío, #11335 +- Autocompletar + - Corregido que las sugerencias de entrada eran incorrectas después de eliminar la palabra clave rápidamente, #11323 +- ColorPicker + - Corregido el evento `active-change` que se disparaba incorrectamente cuando el menú desplegable del picker estaba cerrado, #11304 +- Table + - Corregido el error de estilo del panel de filtro cuando se sobredimensionaba, #11314 + - Corregida que la fila seleccionada actualmente no se retenia cuando se ordenaba la tabla, #11348 +- CheckBox + - Arreglado que cuando el checkbox era único no soportaba validación, #11271 +- Radio + - Arreglado que el Radio desactivado seguia estando seleccionada cuando se pulsaba la tecla espaciadora, #11303 +- MessageBox + - Corregida la clase `el-popup-parent--hidden` que no se eliminaba al abrir MessageBox sucesivamente, #11371 + +### 2.3.9 + +*2018-05-18* + +- Corregido que cuando los datos de origen no tenian el campo especificado por el atributo `prop` de una TableColumn, se producía un error al moverse el ratón dentro de las celdas de esa columna, #11137. +- El atributo `lockScroll` de los componentes pop-up ya no añade un inline style al elemento padre, sino que añade un nombre de clase, #1111114. +- Arreglado el icono de Progreso que no se mostraba cuando su `status` era `exception`, #11172 +- El atributo `disabled` no funcionaba en la lista de resultados del filtro de Cascader, #11185 +- Se ha corregido un problema por el que la fila expandida de la Tabla no se podía contraer si los datos de origen se actualizaban después de su expansión, #11186. +- `setCurrentKey` de Tree ahora acepta `null` como parámetro para cancelar el nodo actualmente resaltado, #11205 + +### 2.3.8 + +*2018-05-11* + +- Corregido que el panel DatePicker saltaba al mes actual después de escoger una fecha en un mes diferente cuando el tipo era `dates`, #10973 +- Arreglado que el `clearable Input` seguía mostrando el icono de borrado cuando era sólo de lectura, #10912 +- Arreglado que al cerrar el panel DatePicker sin modificar el valor se desencadenaba incorrectamente el evento `change`, #11017 +- Arreglado que la navegación por el teclado no funcionaba correctamente cuando Select tenia opciones agrupadas, #11058 +- Agregado el `slot named` `prefix` para Select, #11063 +- Agregado el metodo `clearValidate` para FormItem, #11076 +- Agregado el atributo `checkOnClickNode` para Tree, #11111 + +### 2.3.7 + +*2018-04-29* + +- Corregido que Table no actualizaba el ancho de encabezado cuando la barra de desplazamiento desaparecia debido al filtrado, #10834 +- Corregido input borrable que mostraba el icono de borrado cuando su valor inicial era `nulo`, #10912 +- Corregido el disparador incorrecto del evento `active-change` después de cambiar el valor enlazado de ColorPicker programáticamente, #10903 (por @zhangbobell) +- Corregido filterable Select que causaba un bucle infinito al navegar por las opciones usando el teclado si todas las opciones estában deshabilitadas, #10945 + +### 2.3.6 + +*2018-04-21* + +- Corregido el comportamiento incorrecto del callback `allow-drop` de Tree cuando se usaba el parámetro `type`, #10821 +- Ahora puede introducir correctamente las palabras clave en filterable Single Select en IE11, #10822 +- Corregido Single Select activaba incorrectamente el evento `blur` después de hacer clic en una opción, #10822 + +### 2.3.5 + +*2018-04-20* + +- Arreglado los incorrectos realces en el panel de DatePicker cuando `type` es week, #10712 +- Arreglado que InputNumber comenzaba vacio cuando el valor inicial era 0, #10714 +- Agregado el atributo `automatic-dropdown` para Select, #10042 (by @Seebiscuit) +- Arreglado que el valor del Rate pasaba a `disabled` cuando se comenzaba a actualizar con las teclas de navegacion, #10726 (by @Richard-Choooou) +- Ahora el atributo `type` de DatePicker's puede ser `'dates'`, donde puede elegir varias fechas en un solo picker, #10650 (by @Mini256) +- Agregados los eventos `prev-click` y `next-click` para Pagination, #10755 +- Agregado el atributo `pager-count` para Pagination, #10493 (by @chongjohn716) +- Agregado `type` como 3rd parametro del atributo `allow-drop` de Tree, #10792 +- Ahora usamos ResizeObserver para detectar el redimensionamiento de elementos DOM, #10779 + +### 2.3.4 + +*2018-04-12* + +- Eliminado el atributo duplicado `showTimeout` en SubMenu's en la declaracion TypeScript, #10566 (by @kimond) +- Ahora se puede personalizar los datos de los items de Transfer usando scoped slot, #10577 +- Arreglado que los click de los botones `next` y `prev` en Pagination se deshabilitaban cuando se disparaba el evento `current-change`, #10628 +- Arreglado que Textarea mostraba `undefined` en SSR cuando el valor no era asignado, #10630 +- Arreglado que se deshabilitaba el estilo del TabItem cuando `type` era border-card, #10640 +- Agregado `$index` como cuarto parametro en el atributo de las columnas de Table `formatter` , #10645 +- Arreglado que CheckboxButton no se exportaba en la declaracion de TypeScript, #10666 + +### 2.3.3 + +*2018-04-04* + +- Agregar atributo `shadow` para Card, #10418 (by @YunYouJun) +- Se ha corregido el error de ocultar Badge cuando `value` es `0`, #10470 +- Arreglados algunos bugs del draggable Tree, #10474 #10494 +- Agregado `placement` para Autocomplete, #10475 +- Ahora el atributo `default-time` también funciona en un rango que no es el rango DateTimePicker, #10321 (by @RickMacTurk) +- Eliminado el contorno azul de TabItem después de que el navegador se desdibuja o se minimiza, #10503 +- Agregado el atributo `popper-append-to-body` para SubMenu, #10515 +- Eliminado el feedback visual cuando se desplaza sobre non-link BreadcrumbItem, #10551 +- Se ha corregido el evento `change` de InputNumber para garantizar que el valor de ligado del componente se actualiza en el control de eventos, #10553 + +### 2.3.2 + +*2018-03-29* + +- Arreglada una regresión de Autocompletar, #10442 + +### 2.3.1 + +*2018-03-29* + +- Se ha corregido una regresión por la que el `type` de input no se transmitia al elemento de entrada nativo, #10415 +- Agregado el metodo `blur` para Select, #10416 + +### 2.3.0 Diamond + +*2018-03-28* + +#### Nuevas características +- Table + - Ahora `formatter` de TableColumn puede ser actualizado dinámicamente, #10184 (by @elfman) + - Agregado el atributo `select-on-indeterminate`, #9924 (by @syn-zeta) +- Menu + - Agregado el atributo `collapse-transition`, #8809 (by @limichange) +- Input + - Agregado el metodo `select` , #10229 + - Agregado el metodo `blur`, #10356 +- ColorPicker + - Agregado el atributo `predefine`, #10170 (by @elfman) +- Tree + - Agregados los atributos `draggable`, `allow-drop` y `allow-drag`, y los eventos `node-drag-start`, `node-drag-enter`, `node-drag-leave`, `node-drag-over`, `node-drag-end` y `node-drop`, #9251 #10372 (by @elfman) +- Form + - El metodo `validate` ahora acepta un segundo parametro, que contiene información de los ítems del formulario que no superaron la validación, #10279 + - Agregado el evento `validate`, #10351 +- Progress + - Agregado el atributo `color`, #10352 (by @YunYouJun) +- Button + - Agregado el atributo `circle`, #10359 (by @YunYouJun) + +#### Bug's arreglados +- Form + - Solucionado: Label del FormItem no se alineaba adecuadamente con Input mixto, #10189 +- Menu + - Ahora collapsed Menu sólo mostrará el Tooltip cuando el slot `title` de MenuItem esté configurado, #10193 (by @PanJiaChen) +- Pagination + - Corregido el evento `current-change` que se disparaba erróneamente sin interacción del usuario, #10247 +- DatePicker + - Ahora la fecha y la hora en el panel desplegable están correctamente formateadas según el atributo `format`, #10174(by @remizovvv) +- Upload + - Solucionado el atributo `accept` no trabajaba cuando `drag` era true, #10278 + +### 2.2.2 + +*2018-03-14* + +- Agregado el evento `clear` para Input, #9988 (by @blackmiaool) +- Ahora la entrada manual de ColorPicker soporta los modos `hsl`, `hsv` y `rgb`, #9991 +- Arreglado DatePicker no desencadenaba el evento `change` cuando se borraba su valor inicial, #9986 +- Ahora la clase de iconos relacionadas con los atributos de Rate soporta actualizaciones dinamicas, #10003 +- Arreglado Table que con columnas `fixed` no actualizaban correctamente su altura si se fijaba `max-height`, #10034 +- Ahora DatePicker en modo rango admite la selección inversa (haciendo clic en la fecha final y, a continuación, haciendo clic en la fecha de inicio), #8156 (by @earlymeme) +- Agregado el atributo `disabled` para Pagination, #10006 +- Agregados los eventos `after-enter` y ` after-leave` para Popover, #10047 +- Arreglado Select no disparaba validación cuando el usuario seleccionaba una opción después de ejecutar `resetFields` de Form, #10105 +- Arreglado anchos incorrectos de columnas fijas de Table en algunos casos, #10130 +- Corregido MessageBox heredaba el atributo `title` de su instancia anterior cuando se llamaba sin `title`, #10126 (by @Pochodaydayup) +- Agregado el atributo `input-size` para Slider, #10154 +- Agregados los eventos `left-check-change` y `right-check-change` para Transfer, #10156 + +### 2.2.1 + +*2018-03-02* + +- Corregido Aside, Header y Footer que se contraia en algunos layout, #9812 +- Corregido Table con un atributo `height` no renderizaba en SSR, #9876 +- Corregido Table con fila expandible no calculaba la altura cuando la fila era expandida, #9484 +- Corregido que cuando se escribia la fecha de forma manual en DateTimePicker no se disparaba el evento `change`, #9913 +- Corregido que Select mostraba sus opciones cuando se hacia click con el botón derecho del mouse en el Input, #9894 (by @openks) +- Agregado el atributo `tooltip-class` para Slider, #9957 +- Ahora Select permanecera enfocado despues de la selección, #9857 (by @Seebiscuit) +- Agregado el atributo `target-order` para Transfer, #9960 + +### 2.2.0 Graphite + +*2018-02-12* + +#### New features +- Menu + - Agregados los atributos `popper-class` y `disabled` para SubMenu, #9604 #9771 + - Menu Horizontal ahora soporta SubMenu multi-capas, #9741 +- Tree + - Agregado el evento `node-contextmenu`, #9678 + - Ahora se puede personalizar el template del nodo usando scoped slot, #9686 + - Agregados los metodos `getNode`, `remove`, `append`, `insertBefore`, `insertAfter`, `getCheckedKeys`, `getHalfCheckedNodes`, `getHalfCheckedKeys` y el evento `check`, #9718 #9730 +- Transfer + - Agregado el metodo `clearQuery`, #9753 +- Select + - Agregado el atributo `popper-append-to-body`, #9782 + +#### Bug fixes +- Table + - Corregido el icono de expansión de una fila expandible que al hacer click activaba el evento `row-click`, #9654 + - Corregido el layout que no se actualizaba cuando el ancho de columna era cambiado por el usuario arrastrando, #9668 + - Corregido problema de estilo cuando la fila de resumen coexistia con columnas fijas, #9667 +- Container + + - Corregido componentes del Container que no se estiraban en IE11, #9655 +- Loading + + - Corregido Loading no se mostraba cuando el valor de `v-loading` era cambiado a true en el `hook` `mounted`, #9722 +- Switch + - Corregido se disparaban los dos eventos nativos de click cuando se hacia click en el Switch, #9760 + + + +### 2.1.0 Charcoal + +*2018-01-31* + +#### New features +- Cascader + - Agregados los eventos `focus` y `blur`, #9184 (by @viewweiwu) +- Table + - El `filter-method` ahora tiene un tercer parámetro `column`, #9196 (by @liyanlong) +- DatePicker + - Agregados los atributos `prefix-icon` y `clear-icon`, #9237 (by @AdamSGit) + - Agregado el atributo `default-time`, #9094 (by @nighca) + - `value-format` ahora soporta `timestamp`, #9319 (by @wacky6) +- InputNumber + - Ahora el valor vinculado puede ser `undefined`, #9361 +- Select + - Agregado el atributo `auto-complete`, #9388 +- Form + - Agregado el atributo `disabled`, #9529 + - Agregado el atributo `validateOnRuleChange`, #8141 +- Notification + - Agregado el metodo `closeAll`, #9514 + +#### Bug fixes +- InputNumber + - Arreglado el reseteo del valor cuando tiene punto decimal, #9116 +- Dropdown + - Arreglado el dropdown menu que tenia un posicionamiento incorrecto cuando la página sólo tiene una barra de desplazamiento horizontal en algunos navegadores, #9138 (by @banzhuanmei) +- Table + - Corregido un error en el cálculo del número de columnas fijas después de que los datos de la columna cambian, #9188(by @kolesoffac) + - Corregido el borde de la última columna de la cabecera agrupada que no se visualizaba correctamente., #9326 + - Corregido el posicionamiento incorrecto del header de la tabla en Safari, #9327 + - Corregido fila expandida colapsaba cuando cambiaban los datos de la tabla, #9462 + - Corregido renders múltiples innecesarios en algunas condiciones, #9426 + - Corregido un error de calculo en el ancho de la columna cuando `width` cambiaba en TableColumn, #9426 +- Loading + - Corregido que en algunas ocasiones el loading no se ocultaba correctamente, #9313 +- DatePicker + - Corregido el metodo `focus` que no funcionaba en modo `range`, #9437 + - Corregido si se hacia clic en el botón "now" seguia seleccionando la fecha actual aunque estuviera desactivado, #9470 (by @wacky6) + - Corregido fijación de fechas al navegar, #9577 (by @wacky6) +- Steps + - Corregido error de estilos en IE 11, #9454 + +#### Breaking changes +- Menu + - El menú desplegable en modo `collapse` ahora se agrega directamente al `body`, de modo que es visible cuando está anidado en Aside, #9263 +- Table + - Ahora, al marcar los checkboxes en la Tabla de selección múltiple no se activa el evento `row-click`, #9467 +- Loading + - El `z-index` de la máscara de carga non-fullscreen se cambia a 2000. El `z-index` de la máscara de carga fullscreen se actualiza dinámicamente con los componentes emergentes, #9522 +- Dropdown + - Los atributos `show-timeout` y `hide-timeout` ahora solo trabajan si se dispara `hover`, #9573 + +### 2.0.11 + +*2018-01-08* + +- Corregido el problema de color del borde del Select cuando está el slot `prepend` o `append` del Input, #9089 +- Corregido el parámetro `remove-tag` de Select, #9090 +- Añadido los atributos `show-timeout` y `hide-timeout` para SubMenu, #8934 (por @HugoLew) +- Corregido el estilo de Tooltip de `show-overflow-tooltip` que faltaba cuando Table era importada bajo demanda, #9130 +- Se ha corregido el mal funcionamiento de ordenación de la columna de Table despues que `clearSort` era ejecutado en esa columna, #9100 (por @zEmily) +- El fichero de configuración i18n para el checo se renombra de `cz` a `cs-CZ`, #9164 + +### 2.0.10 + +*2017-12-29* + +- Corregido el calculo incorrecto de la altura máxima de Table cuando fixed column y summary row coexisten, #9026 +- Solucionado el estilo de color que no lo compilaba para textos vacíos en Table, #9028 +- Ahora DatePicker sólo emite el evento `change` cuando el valor cambia verdaderamente, #9029 (by @remizovvv) +- Añadido atributo `tabindex` para Input, #9041 (by @dicklwm) + +### 2.0.9🎄 + +*2017-12-24* + +- Añadida la función de enganche (hook) `before-remove` para Upload, #8788 (by @firesh) +- Arreglado el valor inicial de error que no funcionaba para FormItem, #8840 +- Ahora la directiva Loading soporta nombre de clase personalizado asignando el atributo `element-loading-custom-class`, #8826 (por @earlymeme) +- Arreglado CarouselItem que se ponía invisible cuando los datos eran actualizados asincrónicamente, #8921 +- Añadido el atributo `renderAfterExpand` para Tree, #8972 + +### 2.0.8 + +*2017-12-12* + +- Agregada la documentacion en español +- Arreglado `show-timeout` de Dropdown que no funcionaba cuando se disparaba el click, #8734 (por @presidenten) +- Arreglado el tiempo de validacion del Form cuando se disparaba el blur, #8776 +- Arreglado el evento de perdida de foco (blur) del DatePicker por rangos, #8784 +- `format` de TimePicker ahora soporta AM/PM, #8620 (por @firesh) + +### 2.0.7 + +*2017-11-29* + +- Solucionado el estilo disabled en el texto de button, #8570 + +### 2.0.6 + +*2017-11-29* + +- Corregido error de estilo de los iconos de ordenación de Table, #8405 +- Corregido activacion para Popover cuando `trigger` es manual, #8467 +- Añadidos los atributos `prefix-icon` y `suffix-icon` para Autocomplete, #8446 (por @liyanlong) +- Añadido el atributo `separator` para Cascader, #8501 +- Añadido atributo `clearable` para Input, #8509 (por @lbogdan) +- Añadido atributo `background` para Pagination, #8553 + +### 2.0.5 + +*2017-11-17* + +- Solucionado regresion en 2.0.4 de Popover, Tree, Breadcrumb and Cascader, #8188 #8217 #8283 +- Solucionado Fuga de memoria de la directiva clickoutside, #8168 #8225 (por @badpunman @STLighter) +- Solucionada la altura en multiple Select cuando se borra su valor, #8317 (por @luciy) +- Añadido el atributo `collapse-tags` para multiple Select para reemplazar las tags con una línea de texto, #8190 +- Solucionado el alto consumo de CPU causado por Table cuando esta oculta, #8351 +- Ahora puede usar el método `doLayout` de Table para actualizar su diseño, #8351 + +### 2.0.4 + +*2017-11-10* + +- Accesibilidad mejorada para Cascader, Dropdown, Message, Notification, Popover, Tooltip y Tree +- Arreglado el cambio de tamaño del Container cuando el ancho de la vista disminuye, #8042 +- Arreglado Tree's `updateKeyChildren` borraba incorrectamente los nodos hijos, #8100 +- Arreglado la altura de los bordes de CheckboxBotón's cuando esta anidado en un Form, #8100 +- Arreglado error de análisis de los Menu's para los colores personalizados, #8153 (por @zhouyixiang) + +### 2.0.3 + +*2017-11-03* + +- Solucionado atributos `editable` and `readonly` de DatePicker de los rangos, #7922 +- Corregido error de estilo de los Tabs anidados, #7941 +- Corregido error de estilo del último Step de Steps verticales, #7980 +- Corregido el tiempo de activación del evento `current-change` para Pagination, #7995 +- Corregido Tooltip no registrado en el Menu, #7995 + +### 2.0.2 + +*2017-10-31* + +- Ahora haciendo clic con el botón derecho del ratón en los botones de InputNumber no cambiará su valor, #7817 +- El metodo `validate` de Form ahora puede esperar por validaciones asíncronas antes de ejecutar su devolución de llamada, #7774 (por @Allenice) +- Corregido la selección de rango de DatePicker no funcionaba en los navegadores Chromium 53-57, #7838 +- Corregido la perdida de previsualización e iconos de eliminar de Upload cuando su `list-type` es picture-card, #7857 +- Añadido el atributo `sort-by` para TableColumn, #7828 (por @wangfengming) +- Corregido que a veces DatePicker muestra un número de año incorrecto al seleccionar la primera semana en modo week, #7860 (por @hh23485) +- Corregido error de estilo de icono de Step vertical, #7891 +- El área hot para las flechas de nodo en Tree se expandia, #7891 + +### 2.0.1 + +*2017-10-28* + +- Corregido error de estilo de RadioButton y CheckboxButton, #7793 +- Corregido TimePicker no responde al desplazamiento del ratón en algunas condiciones, #7811 +- Corregido estilos incompletos de algunos componentes cuando se importan bajo demanda, #7811 + +### 2.0.0 Carbon + +*2017-10-27* + +#### New features + +- General + - Un nuevo tema: `theme-chalk` + - Se ha mejorado la accesibilidad de los siguientes componentes: Alert, AutoComplete, Breadcrumb, Button, Checkbox, Collapse, Input, InputNumber, Menu, Progress, Radio, Rate, Slider, Switch, Upload + - Añadido tipografías TypeScript + - Todos los iconos existentes son rediseñados. Se han añadido algunos iconos nuevos + - Añadida una serie de clases de utilidades basadas en puntos de ruptura que ocultan elementos cuando el tamaño del viewport cumple ciertas condiciones + - Componentes de diseño añadidos: Container, Header, Aside, Main, Footer. + - Ahora puede configurar los tamaños de componentes a nivel global. Al importar Element, puede añadir un objeto de configuración global con un prop `size` para configurar tamaños predeterminados para todos los componentes. +- Button + - Atributo `round` añadido. Se usa para botones de esquinas redondas #6643 +- TimeSelect + - Ahora puede ser navegado por `Up` y `Down`, y presionando `Enter` selecciona la hora #6023 +- TimePicker + - Ahora puede ser navegado por `Up` y `Down`, y presionando `Enter` selecciona la hora #6050 + - Añadido `start-placeholder` y `end-placeholder`. Son placeholder's para las dos casillas de input en modo range #7169 + - Añadido el atributo `arrow-control` para hacer girar el tiempo con las flechas #7438 +- Tree + - Ahora los nodos hijo no se renderizan antes de la primera expansión #6257 + - Añadido el atributo `check-descendants`. Determina si los nodos hijo se seleccionan al seleccionar su nodo padre en modo `lazy` #6235 +- Tag + - Atributo `size` añadido #7203 +- Datepicker + - Ahora `timeFormat` puede dar formato al TimePicker cuando type está configurado en `datetimerange` #6052 + - Añadido `start-placeholder` y `end-placeholder`. Son placeholder's para las dos casillas de input en modo range #7169 + - Atributo `value-format` añadido para personalizar el formato del valor enlazado, #7367 + - Añadido el atributo `unlink-panels` para desacoplar los dos paneles de fechas al seleccionar un rango. +- MessageBox + - Añadido el atributo `closeOnHashChange` #6043 + - Atributo `center` agregado para que el contenido pueda ser centrado #7029 + - Añadido atributo `roundButton` para mostrar Botones redondeados #7029 + - Añadido atributo `dangerouslyUseHTMLString`. Cuando está configurado en true, el mensaje será analizado como cadena HTML* #6043 + - Añadido atributo `inputType` para asignar el tipo para el input interno, #7651 +- Dialog + - Añadidos los atributos `width`, `fullscreen`, `append-to-body`. Ahora Dialog puede ser anidado + - Atributo `center` agregado para que el contenido pueda ser centrado #7042 + - Añadidos `focus-after-closed`, `focus-after-open` para mejorar la accesibilidad #6511 +- ColorPicker + - Ahora puede escribir colores en el input #6167 + - Añadidos atributos `size` y `disabled` #7026 + - Añadido atributo `popper-class` #7351 +- Message + - Ahora el color de los iconos puede ser sustituido por CSS #6207 + - Añadido atributo `dangerouslyUseHTMLString`. Cuando está configurado en true, el mensaje será analizado como cadena HTML* #6207 + - Atributo `center` agregado para que el contenido pueda ser centrado #6875 +- Notification + - Añadido atributo `position` para configurar donde aparece Notification #6231 + - Añadido atributo `dangerouslyUseHTMLString` . Cuando está configurado en true, el mensaje será analizado como cadena HTML* #6231 + - Añadido el atributo `showClose` para ocultar el botón de cierre #6402 +- Rate + - Añadido el atributo `show-score` para determinar si la puntuación actual se muestra #6295 +- Tabs + - Añadido el atributo `tab-position` #6096 +- Radio + - Añadidos los atributos `border` y `size` #6690 +- Checkbox + - Añadidos los atributos `border` y `size` #6690 +- Alert + - Atributo `center` agregado para que el contenido pueda ser centrado #6876 +- Menu + - Añadidos los atributos `background-color`, `text-color` y `active-text-color` #7064 + - Añadidos los methods `open` and `close` para abrir y cerrar los SubMenu con programación, #7412 +- Form + - Añadido el atributo `inline-message` para determinar si el mensaje de validación se muestra inline #7032 + - Añadido el atributo `status-icon` para mostrar un icono de retroalimentación cuando se valida #7032 + - Form y FormItem ahora tienen un atributo `size`. Los componentes internos heredarán este tamaño si no se especifica en ellos mismos, #7428 + - Método `validate` devolverá ahora una promesa si se omite la llamada de retorno, #7405 + - Añadido método `clearValidate` para limpiar los resultados de las validaciones de todos los form items, #7623 +- Input + - Añadido slots con nombres `suffix` y `prefix` y atributos `suffixIcon` y `prefixIcon` para añadir contenido dentro del input #7032 +- Breadcrumb + - Añadido el atributo `separator-class` para dar soporte a los iconos como separadores de items #7203 +- Steps + - Añadido atributo `simple` para activar Steps de estilo sencillo #7274 +- Pagination + - Añadidos los atributos `prev-text` y `next-text` para personalizar los textos de la página anterior y de la página siguiente #7005 +- Loading + - Ahora usted puede personalizar el ícono del spinner y el color de fondo con los props `spinner` y `background` , #7390 +- Autocomplete + - Añadido atributo `debounce`, #7413 +- Upload + - Añadidos los atributos `limit` and `on-exceed` para limitar la cantidad de archivos, #7405 +- DateTimePicker + - Añadido el atributo `time-arrow-control` para activar `arrow-control` del TimePicker anidado, #7438 +- Layout + - Añadido un nuevo breakpoint `xl` para viewport más ancho que 1920px +- Table + - Añadido el atributo `span-method` para combinar celdas + - Añadido el método `clearSort` para borrar la clasificación programáticamente + - Añadido el método `clearFilter` para limpiar el filtro de forma programática + - Para las filas ampliables, cuando se amplía una fila, se añadirá una clase `.expanded` a su lista de clases, para que pueda personalizar su estilo. + - Atributo de `size` añadido + - Añadido el método `toggleRowExpansion` para expandir o contraer filas expandibles programáticamente. + - Añadido el atributo `cell-class-name` para asignar el nombre de la clase para las celdas + - Añadido atributo `cell-style` para dar estilo a las celdas + - Añadido atributo `header-row-class-name` para asignar el nombre de clase para las filas de encabezado. + - Añadido un atributo `header-row-style` para el estilo de encabezado + - Añadido el atributo `header-cell-class-name` para asignar el nombre de la clase para las celdas de encabezado. + - Añadido el atributo `header-cell-style` a las celdas de encabezado de estilo + - El atributo prop de TableColumn ahora acepta las notaciones `object[key]` + - Atributo de `index` añadido para TableColumn para personalizar índices de filas +- Select + - Añadido el atributo `reserve-keyword` para reservar la palabra clave de búsqueda actual después de seleccionar una opción. + +#### Bug fixes + +- DatePicker + - Arreglado `v-model` que devolvia el segundo día de la semana seleccionada en modo week #6038 + - Arreglado el primer input comenzaba borrado con el type `daterange` #6021 +- DateTimePicker + - Arreglado DateTimePicker y TimePicker que se afectaban entre sí cuando se seleccionaban #6090 + - Arreglado la hora y el segundo podian estar más allá del límite al seleccionar el tiempo #6076 +- TimePicker + - Arreglado `v-model` que no se actualizaba correctamente cuando no tenia el foco #6023 +- Dialog + - Arreglado textos que tenian bordes borrosos al abrir y cerrar dropdowns anidados #6088 +- Select + - Rendimiento mejorado. Ahora Vue dev-tool no se bloqueará cuando un gran número de Selects sean destruidos #6151 +- Table + - Corregido un bug de Table permanecía oculto cuando su elemento padre tenia el atributo `display: none` + - Arreglado Table ahora amplia su ancho cuando el elemento padre tiene `display: flex` + - Arreglado un bug que corregía las columnas de una tabla con slot con nombre `append` que desaparecia cuando los datos eran recuperados dinámicamente. + - Arreglado el atributo `expand-row-keys` que no funcionan con el valor inicial + - Fallo del filtro corregido al actualizar los datos + - Se ha corregido un error de cálculo de la disposición de columnas fijas con cabeceras agrupadas. + - Corregido un error de `max-height` dinámico + - Corregidos algunos errores de cálculo de estilo + +#### Breaking changes + +- General + - Eliminado `theme-default` + - Compatible con Vue 2.5.2+ e IE 10+ + - Evento `change` de componentes del formulario y evento `current-change` de Pagination ahora sólo se activa en la interacción del usuario. + - El atributo `size` del botón y los componentes del formulario aceptan ahora los tamaños `medium`, `small` y `mini`. + - Para facilitar el uso de iconos de terceros, los atributos `icon` de Button y Steps y los atributos `prefix-icon` y `suffix-icon` del input ahora requieren un nombre de clase completo. +- Dialog + - Atributo `size` eliminado. Ahora el tamaño de Dialog se puede configurar con `width` y `fullscreen` + - Ahora la visibilidad del Diálogo no puede ser controlada por `v-model` +- Rate + - `text-template` a sido renombrado a `score-template` +- Dropdown + - `menu-align` a sido renombrado a `placement`. Ahora soporta más posiciones +- Transfer + - `footer-format` a sido renombrado a `format` +- Switch + - Los atributos que comienzan con `on*` serán analizados en eventos en JSX, haciendo que todos los atributos `on*` de Switch no puedan trabajar en JSX. Por lo tanto, los atributos `on*` se renombran a `active-*`, y por consiguiente los atributos `off-*` se renombran a `inactivado-*`. Este cambio afecta a los siguientes atributos: `on-icon-class`, `off-icon-class`, `on-text`, `off-text`, `on-color`, `off-color`, `on-value`, `off-value`. + - Los atributos `active-text` y `inactive-text` ahora no tienen valores por defecto. +- Tag + - El atributo type acepta ahora `success`, `info`, `warning` y `danger` +- Menu + - Atributo `theme` eliminado. El color de Menu se puede configurar utilizando `background-color`, `text-color` y `active-text-color` +- Input + - Atributo `icon` eliminado. Ahora el icono del sufijo puede configurarse usando el atributo `suffix-icon` o el slot con nombre `suffix`. + - Eliminado el atributo `on-icon-click` y el evento `click`. Ahora para añadir el manejador de clics en los iconos, por favor use los slots con nombre. + - El evento `change` se comporta ahora como el nativo, que se activa sólo en la perdida del foco o presionando enter. Si necesita responder a las entradas de usuario en tiempo real, puede utilizar el evento `input`. +- Autocomplete + - Atributo `custom-item` eliminado. Ahora la plantilla de sugerencias del input se puede personalizar utilizando `scoped slot` + - Atributo `props` eliminado. Ahora puede utilizar el atributo `value-key` para designar el nombre de la clave del objeto de sugerencia del input para su visualización. +- Steps + - Atributo `center` eliminado + - Ahora Steps llenara su contenedor padre por defecto +- DatePicker + - Los parámetros del evento `change` de DatePicker son ahora el valor vinculante en sí mismo. Su formato es controlado por `value-format` +- Table + - Soporte eliminado para personalizar la plantilla de columnas mediante `inline-template` + - `sort-method` ahora se alinea con `Array.sort`. Debería devolver un número en lugar de un booleano + - El slot `append` se desplazo fuera del elemento `tbody` para evitar múltiples renderizados. + - Evento `expand` se renombro a `expand-change` + - Los parametros de los métodos `row-class-name` y `row-style` son ahora un objeto + +# # + +* El procesamiento dinámico de HTML arbitrario en su sitio web puede ser muy peligroso porque puede conducir fácilmente a [ataques XSS](https://en.wikipedia.org/wiki/Cross-site_scripting). Por lo tanto, cuando `dangerouslyUseHTMLString` está encendido, por favor asegúrese de que el contenido de `message` es confiable, y **nunca** asigne el `message` al contenido proporcionado por el usuario.`` \ No newline at end of file diff --git a/CHANGELOG.fr-FR.md b/CHANGELOG.fr-FR.md new file mode 100644 index 0000000..9177920 --- /dev/null +++ b/CHANGELOG.fr-FR.md @@ -0,0 +1,1774 @@ +## Changelog + +### 2.15.1 + +*2021-02-23* + +#### Bug fixes + +- Drawer + - bugfix (by @cs1707) +- Image + - fix incorrect image object fit ratio in IE (#19583 by @charlie0228) +- Cascader + - fix cascader panel active path (#20730 by @cs1707) +- Calendar + - fix calendar component i18n bug (#20758 by @iamkun) +- ColorPicker + - fix bugs (by @UxieVerity) + +#### Optimization + +- Doc + - update Axure resource v2.1.0 (by @iamkun) + +### 2.15.0 + +*2021-01-15* + +#### Bug fixes + +- Select + - Fix placeholder i18n bug (#17644 by @nzh63) +- Popconfirm + - Popconfirm i18n bug by @iamkun +- Drawer + - Fix focus bug (#20626 by @cs1707) +- Image + - Preview optimization (#20652 by @cs1707) + +#### Optimization + +- Doc + - Fix typo in french translation of datetime-picker.md (#20543 by @lonk) + - Add format attribute description to the progress component (#20641 by @cs1707) + +### 2.14.1 + +*2020-11-11* + +#### Bug fixes + +- Popover + - Compatible with Vue 2.6 new v-slot syntax (#20424 by @iamkun) + +#### Optimization + +- I18n + - Update Arabic translation (#20202 by @elkattan) + - Update Uighur translation (#20177 by @IlhamTahir) + +### 2.14.0 + +*2020-10-29* + +#### Breaking changes + +- Popconfirm + - Rename event name to `confirm`, `cancel` (#20240 by @hugiron) + +#### Bug fixes + +- Progress + - Fix attribute error (#19985 by @Caaalabash) + +#### Optimization + +- I18n + - Update Russian translation (#19451 by @yangirov) + - Update Khmer translation (#20077 by @Sovai) + - Update Ukrainian translation (#20344 by @MammutAlex) + +### 2.13.2 + +*2020-05-18* + +#### Bug fixes + +- Autocomplete + - Fix change event bug (#19200 by @sxzz) +- Image + - Update error status (#19194 by @lhx6538665) + +#### Optimization + +- I18n + - Update ru-RU popconfirm translation (#19220 by @Opppex) + - Update vi translation (#19244 by @quangln2810) + - Update Catalan and Spanish translations (#19296 by @Ismaaa) + - Update Indonesia translation (#19320) by @therour) + - Update Brazilian Portuguese translation (#19374 by @diegomengarda) + + +### 2.13.1 + +*2020-04-13* + +#### New features +- Autocomplete + - Add change event (#17913 by @sxzz) + +#### Bug fixes + +- Autocomplete + - Fix suggestion error when textarea (#18478 by @Roojay) +- Carousel + - Fix console typo bug (#18264 by @IceFox) +- Image + - Fix preview dose not show when preview list not contain src issue (#18975) (#19130 by @luckyCao) + - Fix shortcut key not work at second time issue (#18983) (#19156 by @luckyCao) + - Don't show image-viewer when preview is false (#18967 by @inooNgt) +- Transfer + - Fix incorrect line-height of el-transfer's first list item when it was used with el-form-item (#18917 by @Hanx) +- InputNumber + - Correctly compute inputNumberDisabled (#18439 by @ashuser-pendo) +- Chore + - Remove index intro (#19155 by @iamkun) +- Doc + - Popconfirm doc update (#18324 by @iamkun) + - Fix step-strictly docs typo (#18705 by @dream2023) + - Fix a type error in document of steps component (#17555 by @haoranyu) + +### 2.13.0 + +*2019-11-26* + +#### New features + +- Popconfirm + - Add popconfirm component (#17548 by @iamkun) + +#### Bug fixes + +- BackTop + - Use cubic bezier scrolling (by @lon) +- DatePicker + - Fix bug of only select min date of date range problem (#17191 by @smk0621) +- Select + - Fix select test cases (by @msidolphin) +- Tree + - Add font-size for the style of tree empty-text (#17094 by @spengjie) +- Table + - Column header can be costumed (#17291 by @ziyoung) + - Update table header cell style (#17284 by @ziyoung) + - Fix table header height after filter (#17348 by @ziyoung) + - Fixed row-style with display not work (#17002 by @a631807682) + - Fix header table not display (#17341 by @ziyoung) +- Calendar + - Import el-button and el-button-group (#17376 by @masongzhi) +- MessageBox + - Fix icon position error (#17410 by @nullptru) +- TimePicker + - Set the selection range after scrolling up or down (#16868 by @mattheyan) +- Message + - Fix close instace offsetHeight(#17564) (#17852 by @gzwgq222) +- Form + - Callback of validateField should be optional (#17314 by @CarterLi) +- Cascader + - Fix TypeScript 3.7 compatibility (#17881 by @CarterLi) +- Menu + - Fix router NavigationDuplicated error when using vue-router@^3.1.0 (#17269 by @iamkun) +- Dropdown + - Update type file (#17550 by @iamkun) +- Progress + - Add strokeLinecap prop (#17552 by @iamkun) +- InfiniteScroll + - Skip trigger event on invisible element (#17553 by @iamkun) +- Image + - Perfect picture preview behavior (#16985 by @luckyCao) + - Fix shield the page when preview big image (#16796 by @luckyCao) +- Drawer + - Bugfix drawer-append-to-body-not-working (#16953 by @JeremyWuuuuu) +- Select + - Fix tag show value or empty issue (17199 by @luckyCao) +- Scrollbar + - Fix FireFox scroll bar width (#18091 by @iamkun) + +#### Optimization + +- I18n + - Update sv-SE.js (#17926 by @FOLLGAD) + - Update avatar component fr doc (#17762 by @blombard) +- Docs + - Fix time-select typo (#17250 by @wacky6) + - Fix Drawer attribute accepted value typo in es (#17122 by @haoranyu) + - Update Spanish changelog 2.12.0 (#17364 by @Gonzalo2310) + - Fix Changelog typo (#17874 by @renlixin) + - Fix Loading demo (#17862 by @MBearo) + - Add input event in input Events Table (#18061 by @zhouxinyong) + - Delete Input repeat change event (#18085 by @zhouxinyong) + +### 2.12.0 + +*2019-08-29* + +#### New features + +- Popover + - Add close-delay prop (#16671 by @LachlanStuart) +- Theme + - Add Chrome Extension: Element Theme Extension (#16686 by @iamkun) +- Icon + - Add font-display to @font-face declaration (#16805 by @iamfaizalandyka) + +#### Bug fixes + +- Carousel + - Fix onChange emit value (#16705 by @iamkun) +- Notification + - Fix modifying incoming option object (#16704 by @iamkun) +- DatePicker + - Add className for picker option (#16632 by @iamkun) +- DateTimePicker + - Fix time-spinner not scroll to right position (#16854 by @jesse-li) +- Table + - Prevent click handler after drag (#16850 by @ziyoung) + - Fix chrome crash when set thead css display to none (#16956 by @luckyCao) + - Fix wrong empty block height (#16861 by @ziyoung) + - Not throw error when calling toggleExpansion (#16304 by @yyjjqq94) + - Not trigger sort-change event when mounted (#17113 by @a631807682) + - Fix setCurrentRow unable to clear highlight row (#16879 by @ziyoung) + - Fix expand-row-keys not work when data is loaded asynchronously (#16899 by @ziyoung) + - set toggleAllSelection as instance property (#17137 by @ziyoung) +- Tree + - Fix distance between label and checkbox (#16799 by @Hazlank) +- Tabs + - Fix incorrect TabItem's position (#16520 by @victorting) + - Fix activated tab is out of visual range bug (#17033 by @nullptru) +- Calendar + - Fix weekdays i18n issue (#16772 by @ubitoffee) + - fix locale error by (#17208 by @iamkun) +- Cascader + - Fix CascaderPanel display error (#16716 by @zhangHongEn) + - Fix disable status and close button issue (#16224 by @yyjjqq94) +- Input + - Fix Korean composition event (#15069 by @MoonHyuk) + - Fix click event of clear button not trigger when using v-loading (#16576 by @a631807682) +- Select + - Not toggle dropdown when filtering (#17205 by @luckyCao) +- Transfer + - Fix style error (#17206 by @iamkun) +- Dialog + - update sass var (#16365 by @haoranyu) +- RadioGroup + - Not produce invalid HTML in table if "is" attribute is specify (#17070 by @nullptru) +- Divider + - Support custom classes (#17078 by @island205) + +#### Optimization + +- Checkbox + - Improve screen reader experience (#16575 by @tylertrotter) +- Docs + - Update changelog (#16773 by @SimonaliaChen) + - Update contributing guide (#14800 by @sinchang) + - Fix typo in Drawer docs (#16848 by @winkay) + - Update custom theme (#16983 by @iamkun) + - Add Esperanto translation (#16955 by @maxkoryukov) + - Update input-number document about change event (#16316 by @luckyCao) + - Update spanish doc 2.11.1 (#16961 by @Gonzalo2310) +- I18n + - Remove translation of 'year' in catalan language as in the other languages (#14722 by @oscaralbareda) + - Update spanish changelog 2.10.0 and 2.10.1 (#16548 by @Gonzalo2310) + - Update ar.js (#16653 by @l3op) +- Test + - Correct spelling error (#16672 by @boomler) + - Refactor unit test to use data-uri (#16847 by @a631807682) +- Types + - Fix httprequest type (#16633 by @luckyCao) + +### 2.11.1 + +*2019-07-26* + +#### Bug fixes + +- Image + - Fix Image component SSR compatibility (#16737 by @luckyCao) +- Chore + - Update dart-sass compatibility (#16744 by @LewisChennnnn) + +### 2.11.0 + +*2019-07-25* + +#### New features + +- Drawer + - Add drawer component (#16577 by @JeremyWuuuuu) + +#### Bug fixes + +- Checkbox + - Enhance css selector (#16006 by @Hazlank) +- Tree + - Make el-tree generic (#15934 by @JeremyWuuuuu) + - Set isCurrent prop to False (#15870 by @kkkisme) +- Dropdown + - Fix split-button caret default color (#15931 by @JuniorTour) +- Cascader + - Fix level 1 children is empty update problem (#16399 by @luckyCao) + - Add sets default values when lazy is true (#16420 by @luckyCao) + - Fix display errors when node value is duplicate (#15935 by @junyiz) + - Expose getCheckedNodes and fix options change bug (#16709 by @SimonaliaChen) +- Calendar + - Display correct header when range is specified (#16354 by @ziyoung) +- Submenu + - Fix prop append-to-body (#16289 by @a631807682) +- Table + - Fix tree table when updating data (#16481 by @island205) +- Select + - Fix memory leak issue (#16463 by @island205) +- InfiniteScroll + - Update naming & doc (#16698 by @iamkun) +- Avatar + - Fix image not center vertically issue (#16489 by @luckyCao) +- Dialog + - Add destroyOnClose attribute (#16455 by @ziyoung) +- Image + - Add big Image preview feature (#16333 by @luckyCao) + +#### Optimization + +- Docs + - Fix dropdown demo (#16193 by @webxmsj) + - Fix typo in table documents (#15971 by @howiefh) +- I18n + - Update translation of Thai language (#16689 by @ponkrit) +- Chore + - Update theme base api (#16607 by @iamkun) + - Add form theme token (#16699 by @iamkun) + - Mark ali inner user's access (#16609 by @iamkun) + - Fix doc anchor bug (#16692 by @iamkun) + +### 2.10.1 + +*2019-07-02* + +#### Bug fixes + +- Table + - Fix sort icon (#15439 by @bezany) + - Fix layout breaks when append slot exists (#16332 by @ziyoung) + - Fix showOverflowTooltip not reactive (#16295 by @a631807682) + - Register scrollbar in filter-panel (#16246 by @ziyoung) +- Chore + - Fix 2.9 docs (#16233 by @ziyoung) + - Fix index page theme intro english css style issue (#16254 by @iamkun) + +#### Optimization + +- Tag + - Compatible with IE (#16334 by @ziyoung) +- Chore + - Update Dingtalk Group QR image (#16236 by @iamkun) +- Doc + - Update online theme roller doc (#16244 by @iamkun) + +### 2.10.0 + +*2019-06-25* + +#### New features + +- I18n + - Added Uzbek language (#15796 by @ogabek96) +- Calendar + - Add first-day-of-week attribute (#16047 by @ziyoung) +- Avatar + - Add avatar component (#16144 by @luckyCao) +- Upload: + - Add capability to customize thumbnail template (#13192 by @victorzhuk) + +#### Bug fixes + +- Tree + - Not highlight tree node when currentKey is null (#15668 by @yyjjqq94) + - Fix issue #15538 caused by two Tree sharing the same data. (#15615 by @VanMess) +- Upload + - Update the parameter `fileList` type (#15716 by @underfin) +- Table + - Fix loading icon not display (#15868 by @ziyoung) + - Fix background color of complex table when hovering (#15504 by @cnlon) + - Fix current-row-key and select event bug (#15983 by @ziyoung) + - Height accepts more units (#16013 by @ziyoung) + - Fix reserve-selection not work (#16135 by @ziyoung) +- Docs + - Fix Divider attribute type in zh-cn (#15889 by @haoranyu) +- Menu + - Fixed submenu hidden bug after adding popper-append-to-body (#15391 by @PanJiaChen) +- Select + - Fix initialInputHeight (#15989 by @yyjjqq94) + - Fix default-first-option behavior when typing Chinese (#15431 by @VanMess) + - fix double import problem (#16215 by @lengband) +- Message + - Add type def for offset option (#16027 by @matjaz) +- Timeline + - Fix reverse broken (#16091 by @ziyoung) +- Slider + - Fix #15545 by adding explains about "input" event in Chinese (#15588 by @VanMess) +- InfiniteScroll + - Update package name (#16125 by @iamkun) +- MessageBox + - Fix  distinguishCancelAndClose action not same as docs bug (#15438 by @qingdengyue) +- PopupManager + - Fix z-index cannot be rewritten at first using (#15738 by @luckyCao) +- Docs + - Delete an incorrect closing html tag and empty block code (#16194 by @Alexeykhr) +- Chore + - Update test api host (#15807 by @iamkun) + +#### Optimization + +- Tree + - Modify loop conditions to improve performance (#15699 by @KingJeason) +- Theme + - Refine GA track & Update footer link forward to online theme roller (#16007 by @island205) +- Badge + - Update badge prop check (#16198 by @iamkun) +- Avatar + - Update theme config var (#16202 by @luckyCao) +- I18n + - Update pt-br.js (#15776 by @gigioSouza) + - Update Farsi translation (#15881 by @pamenary) +- Docs + - Add missing components in quickstart (#16063 by @pape2016) + - Update french translation (#16208 by @blombard) + - Add description $slots.default (#15444 by @Alexeykhr) + - Update Spanish Doc 2.9.1 (#15840 by @Gonzalo2310) + - Fix spelling mistakes in fr (#15837 by @blombard) + - Update changelog 2.9.2 Spanish (#16185 by @Gonzalo2310) + +#### Breaking changes + +- Form + - Remove success status (#16159 by @ziyoung) + +### 2.9.2 + +*2019-06-21* + +#### Correction de bugs + +- Chore + - Correction du fichier de définitions TS (#15805 by @NateScarlet) + +### 2.9.1 + +*2019-05-30* + +#### Nouvelles fonctionnalités + +- Table + - les événements tree-props,default-expand-all, expand-row-keys, toggle-row-expansion method and expand-change sont pris en charge dans Tree Table (#15709 by @ziyoung) + +#### Correction de bugs + +- Table + - Correction de quelques bugs (#15709 by @ziyoung) +- Theme + - Mise à jour de l'hôte api (#15784 by @iamkun) + +#### Optimisation + +- Chore + - Mise à jour de InfiniteScroll type (#15794 by @iamkun) + +### 2.9.0 + +*2019-05-30* + +#### Nouvelles fonctionnalités + +- Backtop + - Ajout du composant Backtop (#15541 by @iamkun) +- PageHeader + - Ajout du composant PageHeader (#15714 by @ziyoung) +- InfiniteScroll + - Ajout de la directive InfiniteScroll (#15567 by @iamkun) +- Cascader + - Ajouter plusieurs mode et filter-method (#15611 by @SimonaliaChen) +- Message + - Affichage en mode pile (#15639 by @island205) +- Tag + - Ajout d'un effet de prop (#15725 by @SimonaliaChen) +- Tabs + - Aligner le titre à gauche lorsque le type est carte (#15695 by @luckyCao) +- DatePicker + - Supporte les chaînes de caractères littérales (#15525 by island205) +- Image + - Ajout du support pour les attributs de transmission et listeners (#15578 by @VanMess) +- Theme + - Ajout d'un popup en arrière plan (#15412 by @iamkun) +- Chore + - Mise à jour de la nouvelle page d'index 2.9.0 (#15682 by @iamkun) + +#### Correction de bugs + +- Table + - Correction du comportement de sort-change lorsque la condition de tri est nulle (#15012 by @joelxr) +- Image + - Correction de la compatibilité ssr et object-fit (#15346 by @SimonaliaChen) +- Input + - Correction du style de show-word-count dans el-form (#15359 by @lvjiaxuan) + - Correction de l'icône d'erreur pas centrée (#15354 by @YiiGuxing) +- Calendar + - Correction du mauvais jour de la semaine quand le jour est dimanche (#15399 by @qingdengyue) + - Correction du bug de disparition d'octobre (#15394 by @qingdengyue) +- Tabs + - Correction de l'onglet de base imbriqué dans l'erreur de remplissage de card (#15461 by @SimonaliaChen) +- Tag + - Correction du problème de propagation d'arrêt (#15150 by @infjer) +- Form + - Correction de input-group dans l'erreur de hauteur de form-item (#15457 by @SimonaliaChen) + - Résolution de l'issue de resetFields (15181 by @luckyCao) +- Tooltip + - Correction de tabindex personnalisé ne fonctionnant pas (#15619 by @SimonaliaChen ) +- Link + - Correction de la classe de style d'icône (#15752 by @iamkun) +- Select + - Revert définit la valeur à null une fois effacée (#15447 by @iamkun) +- Loading + - Résolution du problème de mise à jour de dom lorsque l'état de chargement change rapidement (#15123 by @FAKER-A) +- Switch + - Label avec les événements récurrents el-switch (#15178 by @FAKER-A) +- Slider + - Correction d'un problème de style lorsque la barre de défilement est cliquée (#15561 by @luckyCao) +- Radio + - Résolution de l'issue 14808 (#14809 by @OverTree) +- Form + - Résolution du problème de resetFields (15181 by @luckyCao) +- Chore + - Mise à jour des dépendances et corrige le bug de démonstration (#15324 by ziyoung) +- Type + - Correction du type de chargement (#15635 by @iamkun) + - Correction du type d'icône (#15634 by @iamkun) + - Fixe la définition du type de lien (#15402 by @iamkun) + +#### Optimisation + +- Cascader + - Refactor (#15611 by @SimonaliaChen) +- Chore + - Mise à jour de la logique du nouveau composant (by @iamkun) +- Docs + - Renommage de variables dans la documentation (#15185 by @liupl) + - Correction du type d'attribut d'image et de la valeur par défaut (#15423 by @haoranyu) + - Correction d'un bug de formulaire (#15228 by @SHERlocked93) + +### 2.8.2 + +*2019-04-25* + +#### Corrections de bugs + +- Icon + - Mise à jour (#15272 par @iamkun) +- Docs + - Correction du style de Form et Input (#15273 par @ziyoung) + +### 2.8.1 + +*2019-04-25* + +#### Corrections de bugs + +- Icon + - Mise à jour de l'icône du cascadeur et du select (#15264 par @SimonaliaChen) + - Mise à jour (#15258 #15268 par @iamkun) + +#### Optimisation + +- Chore + - Mise à jour du script de build (#15267 par @ziyoung) +- Docs + - Correction de la couleur de souslignage d'un lien (#15265 par @iamkun) +- Autre + - Correction d'une configuration de migration non compatible avec les propriétés et évènements en camelCase (#15260 par @SimonaliaChen) + +### 2.8.0 + +*2019-04-25* + +#### Nouvelles fonctionnalités + +- Divider + - Ajout du composant divider (#15055 par @island205) +- Rate + - Ajout des couleurs et des classes d'icônes personnalisées en passant un objet (#15051 par @SimonaliaChen) +- Link + - Ajout du composant Link (#15052 par @iamkun) +- Calendar + - Ajout du composant calendar (#14908 by @ziyoung) +- Icon + - Ajout d'une icône (#15214 par @iamkun) +- Alert + - Ajout d'un thème sombre (#15041 par @island205) +- Image + - Ajout du composant image (#15117 par @SimonaliaChen) +- Collapse + - CollapseItem peut être désactivé (#15076 par @ziyoung) +- Carousel + - Ajout d'un attribut de direction et support de la direction verticale (#15122 by @ziyoung) +- Pagination + - Ajout d'un attribut caché sur une seule page (#15096 par @ziyoung) +- Slider + - Ajout des marqueurs (#15133 par @luckyCao) +- Input + - Ajout de l'attribut show-word-count (#15075 par @luckyCao) +- InputNumber + - Ajout de l'attribut step-strictly (#15050 par @luckyCao) +- Tooltip, Dropdown, Popover + - Support de l'attribut tabindex (#15167 by @ziyoung) + +#### Corrections de bugs + +- Notification + - Correction du word-break du titre (#15008 par @iamkun) +- Form + - Correction d'une erreur dans les règles de validation (#14985 par @luckyCao) + - Correction du style du label (#14969 par @ziyoung) + - Les FormItem requis affiche un astérisque lorsque le label est auto (#15144 by @ziyoung) +- Pagination + - Fix du slot non mis à jour (#14711 par @lucyhao) +- Table + - Correction d'un bug de chargement en mode lazy (#15101 by @ziyoung) + - Correction de la largeur des cellules lorsque colspan est supérieur à 1 (#15196 by @ziyoung) + - Amélioration des performances (#14868 by @ziyoung) + - Ne pas émettre de déclencheurs de changement de tri pendant l'initialisation (#14625 by @PeanutWatson) + - Comportement égal pour height et max-height (#14660 by @arthurdenner) +- Dialog + - Correction de la casse des longs mots (#15027 par @iamkun) +- Alert + - Mise à jour (#15186 par @ziyoung) +- Tabs + - Correction d'un problème où le rejet d'une promesse touchait l'application (#14816 par @ffxsam) + - Rerendu lors d'un changement de slots (#1523238 by @ziyoung) +- Message + - Mise à jour (#14968 par @agoni121212) +- Select + - Correction d'une erreur lorsque la valeur est indéfinie ou nulle (#15022 par @luckyCao) +- Tree + - Détruire le noeud courant après sa suppression (#14604 par @sinchang) + - Amélioration des performances (#14881 par @ChenZhuoSteve) +- Dropdown + - Correction de style (#14907 par @doing123) +- Slider + - Correction d'un bug clavier a11y cassé (#14792 by @erezsob) +- Menu + - La valeur ActiveIndex sera nulle si defaultIndex n'existe pas (#14074 par @hoythan) +- Directive + - RepeatClick : utilisation de Date.now() au lieu de Date() (#14776 par @pavelmash) +- Upload + - Correction du style d'affichage des images transparentes (#15039 par @iamkun) +- Thème + - Ajout d'une bordure (#1525256 par @iamkun) + +#### Optimisation + +- Chore + - Mise à jour du changelog zh-cn (#14965 par @iamkun) + - Masquer la description de la démo quand elle est vide (#15014 par @ziyoung) + - Afficher les informations du serveur de développement par défaut par @iamkun) + - Correction d'une erreur de changelog 2.6.0 (#15026 par @iamkun) + - Mise à jour de la configuration de compilation (#14821 par @abc3660170) + - Ajout d'hmr (#15221 par @SimonaliaChen) + - Utilisation de sourcemap dans l'environnement dev (#15087 par @ibufu) +Docs + - Renommage de la variable dans docs (#14602 #15003 #15094 #15105 par @liupl) + - Correction d'une erreur de téléchargement de doc (#15023 par @iamkun) + - Mise à jour du validateur de formulaire personnalisé doc (#15040 par @iamkun) + - Mise à jour des onglets docs pour afficher les onglets verticaux (#15053 par @iamkun) + - Utiliser eleme.cn comme domaine (#15139 par @ziyoung) + - Correction du nom de route Image (#15194 par @iamkun) + - Suppression de la traduction en double (#15207 par @iamkun) + +#### Breaking changes + +- Rate + - Correction du support de l'affichage décimal en mode désactivé (#15089 par @haoranyu) +- Select + - Utiliser le label de l'option pour régler le placeholder en mode filtre (#14989 par @ibufu) + +### 2.7.2 + +*2019-04-03* + +#### Corrections de bugs + +- Form + - Correction du style de `label-width` auto (#14955 par @ziyoung) + +#### Optimisation +- Docs + - Correction d'une erreur de lien img (#14957 par @iamkun) +- Chore + - Correction d'une erreur de déploiement mkdir (#14952 par @iamkun) + +### 2.7.1 + +*2019-04-03* + +#### Corrections de bugs + +- Select + - Définir la valeur à null lorsqu'elle est effacée (#14322 par @aaronfulkerson) +- Input + - Mise à jour des valeurs dépendantes du DOM lors d'un changement de type (#14889 par @wacky6) +- Table + - Faire fonctionner `defaultExpandAll' lorsqu'une colonne étendue existe (#14935 par @ziyoung) +- Dialog + - Couleur d'arrière-plan configurable (#14939 par @ziyoung) +- Form + - `label-width` supporte la largeur automatique (#14944 by @ziyoung) + +#### Optimisation +- Docs + - Mise à jour de la documentation en espagnol (#14913 par @Gonzalo2310) + - Ajout d'un document en français pour le nouveau composant (#14924 by @ziyoung) + - Optimiser la documentation des onglets (#14938 by @ziyoung) + +### 2.7.0 + +*2019-03-28* + +#### Nouvelles fonctionnalités + +- Table + - Ajout du support de l'arborescence des données (#14632 by @ziyoung) + +#### Corrections de bugs + +- Tabs + - Utilise la couleur primaire comme couleur de l'ombre (#14558 par @Richard-Choooou) + - Rerendu lorsque label change (#14496 par @akki-jat) +- Table + - Le pied de page suit l'alignement des cellules du corps (#14730 by @ziyoung) +- NavMenu + - Correction d'un bug de clic sur el-submenu (#14443 par @PanJiaChen) +- Dropdown + - Compatible avec la nouvelle syntaxe v-slot 2.6 (#14832 by @ziyoung) +- ColorPicker + - Correction d'une erreur de couleur hexadécimale (#14793 par @iamkun) +- Tree + - Revert pr #13349 (#14847 par @ziyoung) +- Tooltip + - Affichage lorsque la valeur initiale est vraie (#14826 by @ziyoung) +- Docs + - Mise à jour de la documentation du cascader (#14442 par @panhezeng) +- Style + - Correction des media queries dans sm-only, md-only, lg-only (#14611 by @sinchang) + +#### Optimisation + +- Chore + - Ajouter la description de la page web (#14802 par @iamkun) + +### 2.6.3 + +*2019-03-21* + +#### Corrections de bugs + +- Correction du style de la démo de Cascader (#14789 par @ziyoung) +- Suppression des opérations DOM inutiles (#14788 by @ziyoung) +- Correction DatePicker valeur par défaut DST (#14562 par @wacky6) + +### 2.6.2 + +*2019-03-21* + +##### Nouvelles fonctionnalités + +- DatePicker + - Ajout d'une plage de mois pour l'attribut type (#14487 par @zxyRealm) +- i18n + - Ajout de la locale croate (#14360 par @danijelh) + +##### Corrections de bugs + +- Input + - Correction d'un régression (#14572 par @wacky6) +- DatePicker + - Correction du calcul du premier jour de la semaine (#14523 par @sinchang) + - Correction du format de valeur du sélecteur de semaine (#13754 par @wacky6) +- Steps + - Correction du problème #14502 (#14596 par @sinchang) + - Correction du style avec le thème simple (#14610 par @sinchang) +- Docs + - Mise à jour de la doc française pour la 2.6.1 et correction de fautes de frappe (#1455555 par @smalesys) + - Renommage d'une variable dans la documentation de la table (#14587 par @likwotsing) + - Ajout de l'index de recherche en français (#14565 par @iamkun) + - Correction du style de la page TimePicker (#14579 par @ziyoung) + - Renommage d'une variable dans la page Upload (#14593 par @liupl) + - Mise à jour de la traduction française (#14643 par @smalesys) + - Mise à jour de la documentation du validateur de formulaire asynchrone (#14694 par @iamkun) + - Correction d'une erreur de doc tooltip (#14748 par @iamkun) + - Correction d'une coquille (#14751 par @2bj) + - Correction de la surbrillance pour Webkit touch (#14703 by @VladG0r) + +##### Optimisation + +- Tâche + - Mise à jour du script de build dans le ci (#14600 par @ziyoung) + - Mise à jour du tracking ga (#14560 par @iamkun) + - Ajout d'un événement ga supplémentaire (#14633 par @iamkun) + - Mise à jour du groupe de discussion (#14741 par @iamkun) + - Mise à jour des deps de test et conf (#14735 par @wacky6) + - Mise à jour de Gulp (#14745 by @ziyoung) + - Utilisez le codepen pour afficher les démos et correction d'une erreur de doc (#14747 by @ziyoung) + +### 2.6.1 + +*2019-03-03* + +#### Corrections de bugs + +- **Ne pas spécifier la version de node** (par @iamkun dans #14546) +- Correction du répertoire doc dans `deloy-faas.sh` (par @ziyoung dans #14553) +- Correction d'un problème de style de date dans le changelog de la 2.6.0 (par @island205 dans #14547) +- Correction d'une typo dans la doc (par @wack6 dans #14552) + +### 2.6.0 + +*2019-03-01* + +#### Nouvelles fonctionnalités +- Timeline + - Ajout d'un composant timeline (par @jikkai dans #14248) +- DropdownItem + - Ajout de la propriété `icon` à `el-dropdown-item` (par @gabrielboliveira dans #14088) +- Input + - Ajout de propriétés pour afficher les mots de passe (par @phshy0607 dans #13966) +- Select + - Ajout du slot `empty` (par @elfman au #13785) +- Autocomplete + - Ajout de la propriété `highlight-first-item` (par @YamenSharaf dans #14269) +- I18n + - Création de la locale Arménienne (par @hamletbarsamyan dans #14214) +- Docs + - Traduction française (par @smalesys dans #12153, #14418, #14434) + +#### Optimisation +- Alert + - Mise à jour de la classe du slot par défaut de la description de Alert (par @iamkun dans #14488) +- Input + - Mise à jour de l'input de type password (par @iamkun dans #14480) +- InputNumber + - Retrait d'un parseFloat inutile (par @JuniorTour au #14172) +- Menu + - Ajout du support de `el-menu-item` sans index (par @georgyfarniev dans #13298) +- Table + - Suppression de certaines opérations du DOM (par @elfman dans #13643) +- Upload + - Optimisation du code (par @elfman dans #13973) +- Popup + - Optimisation du code (par @KAionro dans #14413) +- Docs + - Ajout de détails sur la façon d'exécuter le mode play pour les contributeurs (par @island205 dans #14355) + - Ajout d'un avertissement concernant Input (par @wacky6 dans #14463) + - Mise à jour de la doc de Table (par @luguokong dans #14329) + - Mise à jour de la doc d'Input (par @iamkun dans #14437) + - Mise à jour de la doc sur le thème (par @wangguohaohao dans #14297) + - Le style de l'icône change lorsque vous passez dessus (par @tuxinghuan dans #14295) +- Build + - Minification du CSS et du JS pour le site d'Element (par @iamkun dans #14430) + - Accélération de webpack (par @hetech dans #14484) + - Utilisation du cli pour sélectionner la version de publication (par @hetech dans #14354) +- Installation de stale pour la gestion des issues (par @island205 dans #14392) + +#### Corrections de bugs +- Menu + - Correction d'un bug de focus des sous-menus lors du changement d'onglet du navigateur (par @liupl dans #13976) +- MessageBox + - Correction de la définition du type (par @NateScarlet dans #14278) +- ScrollBar + - Empêche le clic droit sur le bouton du pouce (par @xifeiwu dans #14196) +- Switch + - Déclenchement de la validation du formulaire si la valeur change (par @hetech dans #14426) +- Table + - La méthode toggleAllSelection est maintenant une méthode d'instance (par @letanure dans #14075) +- Tabs & Dropdown + - Correction du style (par @hetech dans #14452) +- Tree + - Les tips sont différents des tableaux (par @ColinCll dans #14331) +- Docs + - Correction d'une erreur de doc du DatetimePicker (par @iamkun dans #14290) + - Problème d'orthographe dans la documentation du DatePicker (par @helmut dans #14481) + - Correction du style de la doc de Pagination(par @liuchuzhang dans #14451) + +#### Breaking changes +- Table + - Fix params order of row events (by @jikkai in #12086) + +### 2.5.4 + +*2019-02-01* + +#### Corrections de bugs + +- Build: Correction d'un problème de configuration de babel qui cassait la transition collapse (par @island205 dans #14282) + +### 2.5.3 + +*2019-01-31* + +#### Optimisation + +- Optimisation du code de Message (par @vok123 dans #14029) +- Suppression des gh-pages (par @ziyoung dans #14266) +- Ajout du lien IssueHunt (par @island205 dans #14261) + +#### Corrections de bugs + +- Correction d'une erreur du module UMD côté serveur (par @island205 dans #14242) +- Correction du style du TabBar actif (par @iamkun dans #14240) +- Correction d'une erreur de code dans la démo de Table (par @xunmeng dans #14253) + +### 2.5.2 + +*2019-01-27* + +#### Optimisation +- Docs: + - Mise à jour du ChangeLog ES 2.5.1 (par @Gonzalo2310 dans #14231) + +#### Corrections de bugs +- Build: + - Suppression des commentaires non supprimés dans le module umd `lib/index.js` (par @island205 dans #14233) + - Correction d'une erreur d'exportation dans le module commonjs utilisé dans nuxt.js (par @island205 dans #14232) + - Correction des problèmes de build 2.5.1 (par @iamkun dans #14228) + +### 2.5.1 + +*2019-01-26* + +#### Optimisation +- DatePicker: surbrillance du mois et de l'année courants (par @Debiancc dans #14211) +- Mise à jour du changelog 2.5.0 (par @wacky6 dans #14217) + +#### Corrections de bugs +- Correction d'un problème d'exportation due par la mise à jour du webpack (par @island205 dans #14220) +- Conservation de la docs 2.4.11 && nouveau sous-dossier pour 2.5+ (par @iamkun dans #14222) + +### 2.5.0 + +*2019-01-25* + +#### Nouvelles fonctionnalités +- DatePicker + - Ajout de l'attribut `validate-event` (par @ziyoung dans #13531) +- DateTimePicker + - `pickerOptions` supporte l'option `selectableRange` (par @eeeeeeeeeeeason) +- Tag + - Ajout de l'événement `click` (par @licdream dans #14106) +- I18n + - Support de la langue kirghize (par @zzjframework dans #14174) + +#### Optimisation +- Mise à niveau vers webpack@4 (par @jikkai dans #14173) +- Input + - Simplification de l'implémentation, suivant un flux de données à sens unique. Correction de plusieurs bugs liés. (par @wacky6 dans #13471) +- Mise à jour du fichier Axure avec de nouveaux composants (par @ziyoung dans #13773) + +#### Corrections de bugs +- Autocomplete + - Correction de la dernière ligne du menu déroulant qui était coupée (#13597) (par @ziyoung) + - Correction d'une flèche de popper manquante (#13762) (par @liuchuzhang) +- Carrousel + - Nettoyage du timer lorsque le composant est détruit (#13820) (par @elfman) +- Cascader + - Suppression de la propriété obsolète des props calculées (#13737) (par @iamkun) + - Correction de la définition du type CascaderOption dans TypeScript (#13613) (par @NateScarlet) + - Correction de l'icône couvrant le texte (#13596) (par @ziyoung) +- Checkbox + - Refonte du style (par @PanJiaChen) +- DatePicker + - Ajout d'un `key` de v-for manquant dans TimeSpinner (#13547) (par @Ende93) + - Correction du surlignage de la semaine dans la bordure de l'année (#13883) (par @suyi91) +- Input + - Correction de la référence de textarea dans le DOM (#13803) (par @laomu1988 @island205) +- Pagination + - La valeur d'entrée ne sera pas inférieure à 1 (#13727) (par @elfman) +- Popover + - Correction d'un problème de popover avec le déclencheur de hover (#13104) (par @goldengecko) + - Correction d'une fuite de mémoire de l'instance popper (#13988) (par @qpxtWhite) +- Radio + - Refonte du style (par @ohhhoney1) +- Table + - Amélioration du tri des tables en cliquant sur la flèche de tri (#12890) (par @ohhoney1) + - Correction d'un problème d'alignement vertical du texte vide sur IE10+ (#13638) (par @imzjy) + - Correction de la documentation sur le type d'index (#13628) (par @ilovefafafa) + - Correction du problème d'affichage `show-summary` lorsque le header multi-niveaux est fixe (#13914) (par @luckyCao) +- Tabs + - Correction d'un bug de défilement automatique (#13696) (par @iamkun) + - Obtenir l'onglet correct par le nom de l'onglet (#13705) (par @iamkun) + - Utilisez paneName au lieu de name pour déterminer le style du panneau (#13733) (par @iamkun) +- Tree + - Correction de la propriété `showCheckbox` sur `Tree` qui ne pouvait pas affecter leurs `tree-node` enfants(par @KidneyFlower) + - Mise à jour des fichiers de doc et de définition (#13540) (par @ziyoung) +- Upload + - Ajout de le propriété `url` au fichier uploadé lorsque `list-type` est modifié (#13771) (par @elfman) +- Slider + - Correction de l'indentation du code source (#13955) (par @wacky6) +- I18n + - Ajout des traductions manquantes en catalan (par @jaumesala) + - Ajout de la traduction russe manquante (#13658) (par @justlp) + - Correction des traductions en finnois (#14137) (par @jenkrisu) +- Doc + - Mise à jour de la documentation espagnol depuis la 2.4.11 (#13522) (par @Gonzalo2310) +- Autres + - Suppression d'un script inutile (par @ziyoung) + - Correction des ancres (#13753) (par @iamkun) + - Correction de l'incohérence des majuscules dans la documentation (par @wonderjar) + - Ajout du QR code du chat DingDing au readme (#13957) (par @iamkun) + - Ajout des logs yarn au .gitignore (#13922) (par @mimimi) + - Suppression du sponsor duotai (#14156) (par @island205) + - Mise à jour du QR code dans le readme (#13960) (par @iamkun) + - Mise à jour du lien CDN, correction d'une typo (par @ziyoung) + +### 2.4.11 + +*2018-11-21* + +- Revert pr #13296. Correction d'un clic sur Menu externe causant l'effondrement du SubMenu, #13478 +- Ajustement des points de rupture media query sur petit écran (xs), #13468 (par @alekoshen712) + +### 2.4.10 + +*2018-11-16* + +- Correction des clics multiples sur Select pour afficher la liste déroulante, #13268 +- L'icône d'effacement des champs n'est pas affichée lorsque Form est désactivé, #13208 +- Ajustement des styles de Select, Progress, Autocomplete, Tooltip, Collaspe, TimePicker, #13188 (par @porcelainHeart) #13210 #13266 #13266 #13257 #13290 #13347 (par @PanJiaChen) +- Ajout de l'attribut `loop` dans le composant Carrousel, #13217 +- Lorsque les données de Table changent, la ligne en surbrillance reste, #13200 +- Le slot du header de Table peut recevoir des paramètres, #13263 +- La méthode `clearFilter` de Table peut recevoir des arguments, #13176 +- La bulle d'aide n'est plus créée lorsqu'il n'y a pas de contenu dans la cellule de Table, #13152 (par @rongxingsun) +- Le contenu de la zone de saisie du panneau ColorPicker peut être affiché correctement, #13278 +- ColorPicker ne déclenche plus la validation des formulaires lors du glisser-déposer, #13299 +- InputNumber: ajout de la méthode `select`, #13286 (par @st-sloth) +- AutoComplete: ajout de l'événement `clear`, #12171(par arthurdenner) #13326 +- Vous pouvez fermer Menu en cliquant à l'extérieur, #13296 +- La méthode `validateField` du formulaire peut recevoir des arguments, #13319 +- Cascader: ajout de l'événement `visible-change`, #13415 +- DatePicker: a ajout d'un slot pour les séparateurs d'intervalle, #13272 (par @milworm) +- Tree: ajout des propriétés `iconClass` et `currentNodeKey`, #13337 #13197 (par @isnifer) +- Progress: ajout du texte de statut #13198 (par @ali-master) +- Correction de `defaultCheckedKeys` de Tree, #13349 (par @dive2Pro) + +### 2.4.9 + +*2018-10-26* + +- Le paramètre `clearValidate` de Form supporte les strings #12990 (par @codinglobster) +- Ajout de l'attribut `type` pour Badge, #12991 +- Les utilisateurs peuvent utiliser scoped-slot pour personnaliser l'en-tête de colonne de Table #13012 (par @ivanseidel) +- Correction du champ de Select incapable d'entrer du texte sous IE, #13034 (par @GaliMU) +- Les options Select ne s'enroule pas lorsque l'espace est suffisant, #12329 (par @akki-jat) +- Lorsque la liste déroulante de Select est ouverte, l'icône de la flèche s'affichera également correctement, #12353 (par @firesh) +- Correction de l'attribut de taille de Select qui ne fonctionnait pas, #13070 +- La sélection de plusieurs valeurs peut aussi être effacée, #13049 (par @ZSkycat) +- Correction du dernier TabNav qui ne pouvait pas être supprimé, #13039 +- Correction d'un problème d'affichage du label TabNav, #13178 +- Ajout d'un slot de titre pour Alert, #13082 (par @Kingwl) +- Correction d'un problème où le contenu de l'infobulle de Table était incorrect, #13159 (par @elfman) +- Optimisation de l'animation de Upload lorsque le fichier est supprimé, #12987 +- Style ajusté pour InputNumber lorsque le bouton de commande n'est pas affiché, #13052 + +### 2.4.8 + +- Ne pas afficher le contour lorsque le Switch est focus, #12771 +- Correction du style de Dropdown dans ButtonGroup, #12819 (par @bluejfox) +- Ajout d'un événement d'ouverture pour Dialog, #12828 +- Correction de l'ordre d'affichage incorrect de TabNav, #12846 +- Correction d'un problème qui empêchait les Tabs de défiler jusqu'à l'onglet sélectionné, #12948 +- Correction d'un problème de l'identificateur qui ne s'affiche pas lorsque le noeud de Tree est glissé, #12854 +- Le paramètre de l'événement validation du formulaire contient le message de validation #12860 (par @YamenSharaf). +- Correction de DatePicker pour ne pas vérifier la validité du temps d'entrée de l'utilisateur, #12898 +- Correction d'un problème avec l'attribut `render-header` de l'en-tête de table qui ne fonctionnait pas, #12914 + +### 2.4.7 + +*2018-09-14* + +- Correction de DatePicker ne déclenchant pas la validation du formulaire, #12328 #12348 +- Correction des erreurs lancées par DatePicker en mode multiple, #12347 +- Correction d'une position incorrecte du spinner de DatePicker, #12415 (par @rang-ali) +- Correction du remplissage automatique de la zone de saisie de DatePicker, #12521 (par @abdallanayer) +- Correction du champ non-subrillant dans Cascader, #12341 +- Correction d'un mauvais ordre de Tabpane, #12346 +- Correction d'une position incorrecte du curseur ColorPicker, #12376 (par @cnwhy) +- Correction du style de SubMenu, #2457 +- Correction de la surbrillance après la sélection de SubMenu, #12479 +- Correction des valeurs incorrectes sélectionnées par Cascader, #12508 (par @huangjinqiang) +- Correction d'une valeur incorrecte dans le champ d'entrée Pagination, #12525 +- Correction de l'ordre dans lequel la Pagination déclenche les événements, #12530 +- Correction des filtres de table non-affichés, #12539 +- Correction de l'arbre incapable de supprimer des nœuds, #12684 +- Correction de la hauteur de Select Input changeant en mode simple, #12719 +- Correction d'un style du label de FormItem sous forme imbriquée, #12748 +- Ajout de l'attribut `autocomplete` pour Input, `auto-complete` devenant obsolète, #12514 (par @axetroy) +- Ajout des slots-scope pour Form pour afficher les informations de validation, #12715 (par @YamenSharaf) + +### 2.4.6 + +*2018-08-09* + +- Correction de Table n'affichant pas l'icône de filtre lorsque `filters` est un tableau vide, #12165 +- Correction de Menu ne sauvegardant pas l'état actif lorsque `collapse` change, #12178 (par @elfman) +- Correction du Cascader n'échappant pas les caractères spéciaux poue les Regexp, #12248 +- Correction d'un bouton Radio désactivé affichant l'ombre d'une case lorsqu'on clique dessus, #12262 +- Correction de arrow key qui n'a pas d'effet lorsque la valeur par défaut est `undefined`, #12322 +- Correction de la fonction de requête de Select non-stabilisée en mode multi, #12181 +- Correction du mot-clé de la requête Select disparaissant en mode multi, #12304 +- Correction d'une largeur incorrecte de Dialog lorsqu'il est affiché en plein écran, #12203 +- Correction de l'affichage incorrect de Main sur IE, #12237 +- Correction de Input déclenchant deux validations de formulaire, #12260 +- Correction de l'ajout d'un nouveau nœud d'arborescence provoquant la disparition des nœuds, #12256 +- Correction d'un nœud d'arborescence non supprimé après avoir glissé, #12279 +- Correction du Popover non-visible quand InputNumber a le focus, #12284 +- Ajout de l'attribut `popper-append-to-body` pour Autocomplete, #12241 +- Ajout du support du modificateur `sync` pour l'attribut `page-size` de Pagination, #12281 + +### 2.4.5 + +*2018-07-26* + +- Correction du réglage de Table `class-name` qui ne fonctionne pas pour les colonnes `expand`, #12006 +- Ajout de la méthode `toggleAllSelection` pour Table, #12047 +- Correction d'une mauvaise position du slot de suffixe lorsque Input contient Select, #12108 +- Correction de `line-height` de l'option impossible à régler, #12120 +- Correction de TimeSelect avec la valeur par défaut `null` ne pouvant être assigné après avoir exécuté `resetField`, #12010 +- Correction d'un événement keydown qui n'étant pas arrow key ne fonctionne pas dans Tree, #12008 +- Correction d'un nœud parent vérifié en mode lazy, #12106 +- Ajout du paramètre `includeHalfChecked` pour getCheckedNodes de Tree, #12014 + +### 2.4.4 + +*2018-07-13* + +- Correction du déclenchement de la validation de Select après la réinitialisation du formulaire, #11837 +- Correction d'une mauvaise position du slot `suffix` de Input lorsque le slot `suffixe` est avec le slot `append`, #11951 +- Correction de Input affichant toujours l'icône clear même en lecture seule, #11967 +- Correction d'un nœud d'arborescence coché lorsqu'il est désactivé, #11847 +- Correction des `default-checked-keys` qui ne fonctionnait pas, #11971 +- Correction de `empty-text` non visible lorsque le noeud de Tree est filtré, #11971 +- Correction de la position du `empty-text` surdimensionné dans Table, #11965 +- Correction de la surbrillance de la ligne de Table lorsque `current-row-key` est assignée à `null`, #11866 +- Correction de l'affichage de la liste déroulante des filtres lorsque `filters` est un tableau vide, #11864 +- Correction du label de Radio qui n'arrête pas la propagation des événements, #11912 + +### 2.4.3 + +*2018-07-03* + +- Correction de `allow-drop` qui ne fonctionnait pas correctement lorsque les nœuds de Tree avaient une hauteur personnalisée, #11797 +- Maintenant vous pouvez passer un paramètre à la méthode `clearValidate` du formulaire, en spécifiant quels résultats de validation FormItems doivent être effacés, #11821 +- Ajout de l'attribut `distinguishCancelAndClose` pour MessageBox, #11831 + +### 2.4.2 + +*2018-06-26* + +- Maintenant `class-name` et `label-class-name` de Table sont réactifs, #11626 +- Correction de Table qui mettait toujours en surbrillance la ligne cliquée lorsque `highlight-current-row` était `false`, #11646 +- Correction d'un bug de style de ButtonGroup lorsqu'il n'a qu'un seul bouton `round` ou `circle`, #11605 +- Correction du style du Select de Pagination, #11622 +- Correction de la méthode `open` du menu quand `collapse` est dynamiquement changé, #11646 +- Ajout des paramètres `activeName` et `oldActiveName` au hook before-leave de Tabs, #11713 +- Correction de Cascader ayant le focus après avoir cliqué à l'extérieur, #11588 +- Correction de Cascader ne se fermant pas quand l'option est cliquée quand `change-on-select` est `true`, #11623 +- La mise à jour programmatique de la valeur de Select déclenchera la validation du formulaire, #11672 + +### 2.4.1 + +*2018-06-08* + +- Suppression du duplicata de la déclaration de type pour Autocomplete, #11388 +- Correction du style de flèche déroulante de Select dans FireFox lorsqu'il est imbriqué dans Form, #11427 +- Correction de l'icône de l'option de Select qui s'affiche toujours lorsque la valeur initiale est `null`, #11460 +- Correction d'un Radio désactivé affichant l'ombre de la boîte quand on clique dessus, #11462 +- Ajout de l'attribut `iconClass` pour MessageBox, #11499 +- Ajout de l'attribut `stretch` pour Tabs, #11476 +- Correction d'un problème d'ordre de rendu de TabPane lorsque Tabs est `lazy`, #11461 +- Correction de Table ne conservant pas la surbrillance de la ligne actuelle lors de son ouverture, #11464 +- Correction de l'état de la mise au point lorsque `before-leave` renvoie une promesse résolue, #11386 +- Correction de la désactivation du Popover qui créait encore des poppers, #11426 +- Correction de la boucle sans fin de Tree lorsqu'un nouveau noeud est ajouté en mode lazy, #11430 (par @wangjingf) +- Ajout de l'événement `closed` pour Dialog, #11490 + +### 2.4.0 Fullerene + +*2018-05-28* + +#### Nouvelles fonctionnalités +- Général + - L'outil de développement et le bundler sont basculés vers le webpack natif, #11216 + - Vous pouvez maintenant définir globalement l'index z initial des popups, #11257 +- Autocomplete + - Ajout de l'attribut `hide-loading`, #11260 +- Button + - Vous pouvez maintenant utiliser l'attribut `size` sur les boutons circulaires pour contrôler leur taille, #11275 +- InputNumber + - Ajout de l'attribut `precision`, #11281 +- Tabs + - Ajout de l'attribut `before-leave`, #11259 + - Ajout de l'attribut `lazy`, #11167(by @Kingwl) +- Table + - Ajout de la méthode `sort` pour trier manuellement la table, #11311 + +#### Corrections de bugs +- Input + - Correction d'un problème qui provoquait un re-rendu lors de l'utilisation de l'IME chinois pour saisir rapidement du texte, #11235 (par @STLighter) +- Popover + - Correction de l'erreur de console lorsque l'élément déclencheur est Radio ou Checkbox, #11265 +- Breadcrumb + - Correction de l'attribut `to` ne supportant pas la mise à jour dynamique, #11286 +- Upload + - Correction de l'erreur de console lorsqu'un fichier est résolu dans la promesse retournée de la méthode `beforeUpload`, #11297 (par @qusiba) +- Infobulle + - Correction d'une flèche mal positionnée lorsque le contenu est vide, #11335 +- Autocomplete + - Correction de suggestions d'entrée incorrectes après la suppression rapide d'un mot-clé, #11323 +- ColorPicker + - Correction d'un événement `active-change` se déclenchant incorrectement lorsque le menu déroulant du picker est fermé, #11304 +- Table + - Correction d'une erreur de style du panneau de filtre surdimensionné, #11314 + - Correction de la ligne actuellement sélectionnée qui n'était pas conservée lors du tri de la table, #11348 +- Checkbox + - Correction d'une checkbox unique ne supportant pas la validation, #11271 +- Radio + - Correction du Radio désactivé quand même sélectionné en appuyant sur la touche espace, #11303 +- MessageBox + - Correction de la classe `el-popup-parent-hidden` qui n'était pas supprimée à l'ouverture successive de MessageBox, #11371 + +### 2.3.9 + +*2018-05-18* + +- Correction d'une erreur lorsque les données source n'ont pas le champ spécifié par l'attribut `prop` d'une TableColumn, lorsque la souris se déplace dans les cellules de cette colonne, #11137 +- L'attribut `lockScroll` des composants popup n'ajoute plus un style en ligne à l'élément parent, mais ajoute un nom de classe, #1111114 +- Correction de l'icône de Progression qui ne s'affichait pas quand son `status` était une exception, #11172 +- Correction de l'attribut `désactivé` qui ne fonctionnait pas dans la liste des résultats de filtrage du Cascader filtrable, #11185 +- Correction d'un problème où la ligne étendue de la table ne peut pas être réduite si la source de données est mise à jour après son extension, #11186 +- `setCurrentKey` de Tree accepte maintenant `null` comme paramètre pour annuler le noeud actuellement mis en surbrillance, #11205 + +### 2.3.8 + +*2018-05-11* + +- Correction du saut du panneau DatePicker au mois courant après avoir choisi une date dans un mois non courant quand `type` est dates, #10973 +- Correction de l'Input effaçable affichant toujours l'icône d'effacement en lecture seule, #10912 +- Correction de la fermeture du panneau DatePicker sans changer la valeur déclenchant incorrectement l'événement `change`, #11017 +- Correction d'un problème de navigation du clavier lorsque Select a regroupé les options, #11058 +- Ajout du slot nommé `préfixe` pour Select, #11063 +- Ajout de la méthode `clearValidate` pour FormItem, #11076 +- Ajout de l'attribut `checkOnClickNode` pour Tree, #1111111 + +### 2.3.7 + +*2018-04-29* + +- Correction d'une table qui ne mettait pas à jour ses largeurs de headers lorsque la barre de défilement disparaissait à cause du filtrage, #10834 +- Correction de l'Input effaçable affichant toujours l'icône d'effacement lorsque sa valeur initiale est `null`, #10912 +- Correction d'un déclencheur incorrect de l'événement `active-change` après avoir changé la valeur liée de ColorPicker par programmation, #10903 (par @zhangbobell) +- Correction du Select filtrable qui provoquait une boucle infinie lors de la navigation dans les options à l'aide du clavier si toutes les options sont désactivées, #10945 + +### 2.3.6 + +*2018-04-21* + +- Correction d'un comportement incorrect du callback `allow-drop` de Tree lorsque le paramètre `type` est utilisé, #10821 +- Maintenant vous pouvez entrer correctement les mots-clés dans le Select simple filtrable dans IE11, #10822 +- Correction d'un Select simple déclenchant incorrectement un événement `blur` après avoir cliqué sur une option, #10822 + +### 2.3.5 + +*2018-04-20* + +- Correction d'une surbrillance incorrecte dans le panneau DatePicker lorsque `type` est la semaine, #10712 +- Correction d'un InputNumber vide lorsque sa valeur initiale est 0, #10714 +- Ajout de l'attribut `automatic-dropdown` pour Select, #10042 (par @Seebiscuit) +- Correction de Rate désactivé quand même mis à jour par les touches de navigation, #10726 (par @Richard-Choooou) +- L'attribut `type` de DatePicker peut être `dates`, où vous pouvez choisir plusieurs dates dans un sélecteur, #10650 (par @Mini256) +- Ajout des événements `prev-click` et `next-click` pour Pagination, #10755 +- Ajout de l'attribut `pager-count` pour Pagination, #10493 (par @chongjohn716) +- Ajout de `type` comme 3ème paramètre de l'attribut `allow-drop` de Tree, #10792 +- Nous utilisons maintenant ResizeObserver pour détecter le redimensionnement des éléments DOM, #10779 + +### 2.3.4 + +*2018-04-12* + +- Suppression du double de l'attribut `showTimeout` dans la déclaration TypeScript de SubMenu, #10566 (par @kimond) +- Vous pouvez maintenant personnaliser les éléments de Transfert en utilisant le scoped slot, #10577 +- Correction d'un clic sur le bouton précédent désactivé et le bouton suivant de la pagination déclenchant toujours l'événement `current-current-change`, #10628 +- Correction de Textarea affichant `undefined` dans le SSR lorsque sa valeur n'est pas définie, #10630 +- Correction de la désactivation du style TabItem lorsque `type` est border-card, #10640 +- Ajout de `$index` comme quatrième paramètre du `formatter` de la Table, #10645 +- Correction de CheckboxButton non exporté dans la déclaration TypeScript, #10666 + +### 2.3.3 + +*2018-04-04* + +- Ajout de l'attribut `shadow` pour Card, #10418 (par @YunYouJun) +- Correction de Badge masqué lorsque `value` est `0`, #10470 +- Correction de quelques bugs de Tree, #10474 #10494 +- Ajout de `placement` pour Autocomplete, #10475 +- L'attribut `default-time` fonctionne également dans DateTimePicker, #10321 (par @RickMacTurk) +- Suppression du contour bleu de TabItem après que le navigateur n'ait plus le focus ou soit minimisé, #10503 +- Ajout de l'attribut `popper-append-to-body` pour SubMenu, #10515 +- Suppression du feedback visuel lors du survol d'un élément BreadcrumbItem non lié, #10551 +- Correction de l'événement `change` d'InputNumber pour s'assurer que la valeur liée du composant est mise à jour dans le gestionnaire d'événements, #10553 + +### 2.3.2 + +*2018-03-29* + +- Correction d'une régression d'Autocomplete, #10442 + +### 2.3.1 + +*2018-03-29* + +- Correction d'une régression de `type` d'Inputqui n'était pas transmis à l'élément natif, #10415 +- Ajout de la méthode `blur` pour Select, #10416 + +#### 2.3.0 Diamant + +*2018-03-28* + +#### Nouvelles fonctionnalités +- Table + - Maintenant le `formatter` de TableColumn peut être mis à jour dynamiquement, #10184 (par @elfman) + - Ajout de l'attribut `select-on-indeterminate`, #9924 (par @syn-zeta) +- Menu + - Ajout de l'attribut `collapse-transition`, #8809 (par @limichange) +- Input + - Ajout de la méthode `select`, #10229 + - Ajout de la méthode `blur`, #10356 +- ColorPicker + - Ajout de l'attribut `predefine`, #10170 (par @elfman) +- Tree + - Ajout des attributs `draggable`, `allow-drop` et `allow-drag`, et `node-drag-start`, `node-drag-enter`, `node-drag-leave`, `node-drag-leave`, `node-drag-over`, `node-drag-end` et `node-drop`, #9251 #10372 (par @elfman) +- Form + - La méthode `validate` a maintenant un deuxième paramètre, contenant l'information des éléments de formulaire qui ont échoué à la validation, #10279 + - Ajout de l'événement `validate`, #10351 +- Progress + - Ajout de l'attribut `color`, #10352 (par @YunYouJun) +- Button + - Ajout de l'attribut `circle`, #10359 (par @YunYouJun) + +#### Corrections de bugs +- Form + - Correction du label de FormItem non aligné avec l'Input mixte, #10189 +- Menu + - Désormais, le menu réduit n'affichera la bulle d'aide que lorsque le slot `title` de l'élément MenuItem est défini, #10193 (par @PanJiaChen). +- Pagination + - Correction d'un événement `current-current-change` qui se déclenchait incorrectement sans interaction de l'utilisateur, #10247 +- DatePicker + - Maintenant, la date et l'heure dans le panneau déroulant sont correctement formatées en fonction de l'attribut `format`, #10174(by @remizovvv) +- Upload + - Correction de l'attribut `accept` qui ne fonctionnait pas quand `drag` est vrai, #10278 + +### 2.2.2 + +*2018-03-14* + +- Ajout de l'événement `clear` pour Input, #9988 (par @blackmiaool) +- Maintenant la saisie manuelle de ColorPicker supporte les modes `hsl`, `hsv` et `rgb`, #9991 +- Correction de DatePicker ne déclenchant pas l'événement `change` lorsque sa valeur initiale est effacée, #9986 +- Maintenant les attributs liés à la classe d'icônes de Rate supportent les mises à jour dynamiques, #10003 +- Correction de Table avec des colonnes fixes dont la hauteur n'est pas mise à jour correctement si `max-height` est réglé, #10034 +- Maintenant le mode plage de DatePicker supporte la sélection inverse (en cliquant sur la date de fin, puis sur la date de début), #8156 (par @earlymeme) +- Ajout de l'attribut `désactivé` pour Pagination, #10006 +- Ajout des événements `after-enter` et `after-leave` pour Popover, #10047 +- Correction de Select ne déclenchant pas la validation lorsque l'utilisateur sélectionne une option après avoir exécuté `resetFields` du formulaire, #10105 +- Correction des largeurs incorrectes des colonnes fixes de Table dans certains cas, #10130 +- Correction de MessageBox héritant de l'attribut `title` de son instance précédente lorsqu'il était appelé sans `title`, #10126 (par @Pochodaydaydayup) +- Ajout de l'attribut `input-size` pour Slider, #10154 +- Ajout des événements `left-check-change` et `right-check-change` pour Transfer, #10156 + +### 2.2.1 + +*2018-03-02* + +- Correction d'un rétrécissement de Aside, Header et Footer dans certaines mises en page, #9812 +- Correction de Table avec un attribut `height` qui ne rendait pas dans SSR, #9876 +- Correction d'une Table extensible ne calculant pas sa hauteur lorsqu'une rangée est agrandie, #9848 +- Correction d'un événement `change` qui ne se déclenchait pas lors de la saisie manuelle de la date dans DateTimePicker, #9913 +- Correction de Select affichant ses options lorsque la boîte de saisie est cliquée avec le bouton droit de la souris, #9894 (par @openks) +- Ajout de l'attribut `tooltip-class` pour Slider, #9957 +- Maintenant Select garde le focus après la sélection, #9857 (par @Seebiscuit) +- Ajout de l'attribut `target-order` pour Transfer, #9960 + +### 2.2.0 Graphite + +*2018-02-12* + +#### Nouvelles fonctionnalités +- Menu + - Ajout des attributs `popper-class` et `disabled` pour le sous-menu, #9604 #9771 + - Le menu horizontal prend maintenant en charge le sous-menu multicouche, #9741 +- Tree + - Ajout de l'évènement `node-contextmenu`, #9678 + - Vous pouvez maintenant personnaliser le modèle de nœud en utilisant un slot avec portée, #9686 + - Ajout des méthodes `getNode`, `remove`, `remove`, `append`, `insertBefore`, `insertAfter`, `getCheckedKeys`, `getHalfCheckedNodes`, `getHalfCheckedNodes`, `getHalfCheckedKeys` et de l'événement `check`, #9718 #9730 +- Transfer + - Ajout de la méthode `clearQuery`, #9753 +- Select + - Ajout de l'attribut `popper-append-to-body`, #9782 + +#### Corrections de bugs +- Table + - Correction d'un clic sur l'icône d'expansion d'une ligne extensible qui déclenche l'événement `row-click`, #9654 + - Correction de la mise en page non mise à jour lorsque la largeur des colonnes est modifiée par glisser-déposer de l'utilisateur, #9668 + - Correction d'un problème de style lorsque la ligne de résumé coexiste avec des colonnes fixes, #9667 +- Container + - Les composants fixes de Container ne s'étirent pas dans IE11, #9655 +- Loading + - Correction du chargement n'apparaissant pas lorsque la valeur de `v-loading` est changée en true dans le hook `mounted`, #9722 +- Switch + - Correction de deux événements de clics natifs déclenchés lorsque Switch est cliqué, #9760 + +### 2.1.0 Charcoal + +*2018-01-31* + +#### Nouvelles fonctionnalités +- Cascader + - Ajout des événements `focus` et `blur`, #9184 (par @viewweiwu) +- Table + - La méthode `filter-method` a maintenant un troisième paramètre `column`, #9196 (par @liyanlong) +- DatePicker + - Ajout des attributs `prefix-icon` et `clear-icon`, #9237 (par @AdamSGit) + - Ajout de l'attribut `default-time`, #9094 (par @nighca) + - Le format `value-format` supporte maintenant `timestamp`, #9319 (par @wacky6) +- InputNumber + - Maintenant la valeur liée peut être `undefined`, #9361 +- Select + - Ajouté l'attribut `auto-complete`, #9388 +- Form + - Ajout de l'attribut `désactivé`, #9529 + - Ajout de l'attribut `validateOnRuleChange`, #8141 +- Notification + - Ajout de la méthode `closeAll`, #9514 + +#### Corrections de bugs +- InputNumber + - Correstion du reset lors de la saisie du point des nombres décimaux, #9116 +- Dropdown + - Correction du mauvais positionnement du menu déroulant lorsque la page n'a qu'une barre de défilement horizontale dans certains navigateurs, #9138 (par @banzhuanmei) +- Table + - Correction d'une erreur dans le calcul du nombre de colonnes fixes après les changements de données des colonnes, #9188(by @kolesoffac) + - Correction de la bordure de la dernière colonne de l'en-tête groupé qui n'était pas correctement affichée, #9326 + - Correction d'un positionnement incorrect de l'en-tête du tableau dans Safari, #9327 + - Correction de la réduction des lignes extensibles lorsque les données de la table changent, #9462 + - Correction de rendus multiples inutiles dans certaines conditions, #9426 + - Correction d'une erreur de calcul de la largeur de colonne lors de la modification de `width` de TableColumn, #9426 +- Loading + - Correction de Loading ne se cachant pas correctement dans certaines conditions, #9313 +- DatePicker + - Correction de la méthode `focus` qui ne fonctionnait pas en mode "range", #9437 + - Correction du clic sur le bouton "now" qui sélectionnait toujours la date actuelle même si elle était désactivée, #9470 (par @wacky6) + - Correction d'une date trop serrée lors de la navigation, #9577 (par @wacky6) +- Steps + - Correction d'une erreur de style dans IE 11, #9454 + +#### Changements +- Menu + - Le menu contextuel en mode `collapse` s'ajoute maintenant directement à `body`, de sorte qu'il est visible lorsqu'il est imbriqué dans Aside, #9263 +- Table + - Maintenant, cocher les cases dans la Table multi-sélection ne déclenche pas l'événement `row-click`, #9467 +- Loading + - Le `z-index` du masque de chargement non plein écran est changé à 2000. Le `z-index` du masque de chargement plein écran se mettra à jour dynamiquement avec les composants popup, #9522 +- Dropdown + - Les attributs `show-timeout` et `hide-timeout` ne fonctionnent maintenant que lorsque le déclencheur est `hover`, #9573 + +### 2.0.11 + +*2018-01-08* + +- Correction d'un problème de couleur de bordure de Select dans les slots `prepend` ou `append` de Input, #9089 +- Correction du paramètre `remove-tag` de l'événement Select, #909090 +- Ajout des attributs `show-timeout` et `hide-timeout` pour le sous-menu, #8934 (par @HugoLew) +- Correction d'un style Tooltip manquant de `show-overflow-tooltip` lors de l'importation de Table sur demande, #9130 +- Correction d'un dysfonctionnement du tri des colonnes de la table après l'exécution de `clearSort` sur cette colonne, #9100 (par @zEmily) +- Le fichier de configuration i18n pour le tchèque est renommé de `cz` en `cs-CZ`, #9164 + +### 2.0.10 + +*2017-12-29* + +- Calcul erroné de la hauteur du tableau lorsque la colonne fixe et la ligne de somme coexistent, #9026 +- Correction d'un style de couleur non compilé du texte vide dans le tableau, #9028 +- Maintenant, DatePicker n'émet que l'événement `change` quand la valeur est vraiment changée, #9029 (par @remizovvvv) +- Ajout de l'attribut `tabindex` pour Input, #9041 (par @dicklwm) + +### 2.0.9🎄 + +*2017-12-24* + +- Ajouté la fonction de hook "avant suppression" pour Upload, #8788 (par @firesh) +- Correction de la valeur initiale de `error` qui ne fonctionnait pas pour FormItem, #8840 +- La directive Loading prend maintenant en charge le nom de classe personnalisé grâce à l'attribut `element-loading-custom-class`, #8826 (par @earlymeme) +- Correction CarouselItem devenant invisible lorsque les données sont mises à jour de manière asynchrone, #8921 +- Ajout de l'attribut `renderAfterExpand` pour Tree, #8972 + +### 2.0.8 + +*2017-12-12* + +- Ajout de la documentation en espagnol +- Correction du `show-timeout` de Dropdown qui ne fonctionnait pas quand le déclencheur est click, #8734 (par @presidenten) +- Correction du temps de validation des formulaires pour les règles dont le déclencheur est blur, #8776 +- Correction d'un événement de blur de DatePicker avec intervalle, #8784 +- L'attribut `format` de TimePicker supporte maintenant AM/PM, #8620 (par @firesh) + +### 2.0.7 + +*2017-11-29* + +- Correction du style du bouton de type texte désactivé, #8570 + +### 2.0.6 + +*2017-11-29* + +- Correction d'un bug de style des icônes de tri de la table, #8405 +- Correction du mécanisme de déclenchement de Popover lorsque son `trigger` est manuel, #8467 +- Ajout des attributs `prefix-icon` et `suffix-icon` pour Autocomplete, #8446 (par @liyanlong) +- Ajout de l'attribut `separator` pour Cascader, #8501 +- Ajout de l'attribut `clearable` pour Input, #8509 (par @lbogdan) +- Ajout de l'attribut `background` pour Pagination, #8553 + +### 2.0.5 + +*2017-11-17* + +- Correction de la régression Popover, Tree, Breadcrumb et Cascader dans 2.0.4, #8188 #8217 #8283 +- Correction d'une fuite de mémoire de la directive `clickoutside`, #8168 #8225 (par @badpunman @STLighter) +- Correction de la hauteur du Select multiple lorsque sa valeur est effacée, #8317 (par @luciy) +- Ajout de l'attribut `collapse-tags` pour plusieurs Sélectionner pour remplacer les balises par une ligne de texte, #8190 +- Correction d'une consommation CPU élevée causée par la table cachée, #8351 +- Maintenant vous pouvez utiliser la méthode `doLayout` de la Table pour mettre à jour sa disposition, #8351 + +### 2.0.4 + +*2017-11-10* + +- Accessibilité améliorée pour Cascader, Dropdown, Message, Notification, Popover, Tooltip et Tree. +- Correction du redimensionnement de Container lorsque la largeur de la fenêtre d'affichage diminue, #8042 +- Correction de la suppression incorrecte de `updateKeyChildren` dans Tree, #8100 +- Correction de la hauteur de la CheckboxButton avec bordure lorsque le bouton est imbriqué dans un formulaire, #8100 +- Correction d'une erreur d'analyse du menu pour les couleurs personnalisées, #8153 (par @zhouyixiang) + +### 2.0.3 + +*2017-11-03* + +- Correction des attributs `éditable` et `readonly` pour DatePicker avec intervalle, #7922 +- Correction d'une erreur de style des Tabs imbriqués, #7941 +- Correction d'une erreur de style de la dernière étape des Steps verticales, #7980 +- Correction de la synchronisation du déclenchement de l'événement `current-current-change` pour Pagination, #7995 +- Correction d'une infobulle non enregistrée dans Menu, #7995 + +### 2.0.2 + +*2017-10-31* + +- Un clic droit sur les boutons de InputNumber ne changera pas sa valeur, #7817 +- La méthode `validate` de Form peut maintenant attendre des validations asynchrones avant d'exécuter son callback, #7774 (par @Allenice) +- Correction de la plage de sélection de DatePicker ne fonctionnant pas dans les navigateurs Chromium 53-57, #7838 +- Correction des icônes manquantes de prévisualisation et de suppression de Upload lorsque son `list-type` est picture-card, #7857 +- Ajout de l'attribut `sort-by` pour TableColumn, #7828 (par @wangfengming) +- Correction de DatePicker affichant parfois un mauvais numéro d'année lors de la sélection de la première semaine en mode semaine, #7860 (par @hhh23485) +- Correction d'une erreur de style d'icône des Steps verticales, #7891 +- La 'hot area' pour les flèches de nœud dans Tree est étendue, #7891 + +### 2.0.1 + +*2017-10-28* + +- Correction d'une erreur de style de RadioButton et CheckboxButton, #7793 +- Correction de TimePicker qui ne répondait pas au défilement de la souris dans certaines conditions, #7811 +- Correction des styles incomplets de certains composants lors de l'importation à la demande, #7811 + +### 2.0.0 Carbon + +*2017-10-27* + +#### Nouvelles fonctionnalités +- Général + - Un nouveau thème : `theme-chalk`. + - L'accessibilité des éléments suivants est améliorée : Alert, AutoComplete, Breadcrumb, Button, Checkbox, Collapse, Input, InputNumber, Menu, Progress, Radio, Rate, Slider, Switch, Upload + - Ajout du typage TypeScript + - Toutes les icônes existantes sont redessinées. De nouvelles icônes sont ajoutées + - Ajout d'une série de classes basées sur les breakpoints qui masquent les éléments lorsque la taille de la fenêtre remplit certaines conditions + - Ajout des composants de mise en page : Container, Header, Aside, Main, Footer + - Vous pouvez maintenant configurer la taille des composants de manière globale. Lors de l'importation d'un élément, vous pouvez ajouter un objet de configuration global avec une propriété `size` pour configurer les tailles par défaut pour tous les composants. +- Button + - Ajout de l'attribut `round`. Il est utilisé pour les boutons à coins ronds #6643 +- TimeSelect + - Vous pouvez maintenant naviguer en appuyant sur les touches `Up` et `Down`, et en appuyant sur `Enter` vous sélectionnez l'heure #6023. +- TimePicker + - Vous pouvez maintenant naviguer à l'aide des touches fléchées, et en appuyant sur `Entrée` vous sélectionnez l'heure #6050. + - Ajout de `start-placeholder` et de `end-placeholder`. Ce sont des placeholders pour les deux champs en mode intervalle #7169 + - Ajout de l'attribut `farrow-control` pour faire tourner le temps avec les flèches #7438 +- Tree + - Maintenant les noeuds enfants ne font pas de rendu avant la première ouverture #6257 + - Ajout de l'attribut `check-descendants`. Il détermine si les nœuds enfants sont vérifiés lors du contrôle de leur nœud parent en mode `lazy` #6235 +- Tag + - Ajouté l'attribut `size` #7203 +- Datepicker + - Maintenant `timeFormat` peut formater le TimePicker quand le type est réglé sur `datetimerange` #6052 + - Ajout de `start-placeholder` et de `end-placeholder`. Ce sont des placeholders pour les deux champs en mode intervalle #7169 + - Ajout de l'attribut `value-format` pour personnaliser le format de la valeur liée, #7367 + - Ajout de l'attribut `unlink-panels` pour dissocier les deux panneaux de date lors de la sélection d'une plage de dates +- MessageBox + - Ajout de l'attribut `closeOnHashChange` #6043 + - Ajout de l'attribut `center` pour que le contenu puisse être centré #7029 + - Ajout de l'attribut `roundButton` pour afficher les boutons ronds #7029 + - Ajout de l'attribut `dangerouslyUseHTMLString`. Lorsqu'il est réglé sur `true`, `message` sera interprété comme une chaîne HTML\* #6043 + - Ajout de l'attribut `inputType` pour assigner le type de l'input intérieur, #7651 +- Dialog + - Ajout des attributs `width`、`fullscreen`、`append-to-body`. La boîte de dialogue peut maintenant être imbriquée + - Ajout de l'attribut `center` pour que le contenu puisse être centré #7042 + - Ajout de `focus-after-closed`、`focus-after-open` pour améliorer l'accessibilité #6511 +- ColorPicker + - Maintenant vous pouvez taper les couleurs dans le champ de saisie #6167 + - Ajout des attributs `size` et `disabled` #7026 + - Ajout de l'attribut `popper-class` #7351 +- Message + - Maintenant la couleur des icônes peut être modifiée par CSS #6207 + - Ajout de l'attribut `dangerouslyUseHTMLString`. Lorsqu'il est réglé sur `true`, `message` sera interprété comme une chaîne HTML\* #6207 + - Ajout de l'attribut `center` pour que le contenu puisse être centré #6875 +- Notification + - Ajout de l'attribut `position` pour configurer où Notification apparaît #6231 + - Ajout de l'attribut `dangerouslyUseHTMLString`. Lorsqu'il est réglé sur `true`, `message` sera interprété comme une chaîne HTML\* #6231 + - Ajout de l'attribut `showClose` pour cacher le bouton de fermeture #6402 +- Rate + - Ajout de l'attribut `show-score` pour déterminer si le score actuel est affiché #6295 +- Tabs + - Ajout de l'attribut `tab-position` #6096 +- Radio + - Ajout des attributs `border` et `size` #6690 +- Checkbox + - Ajout des attributs `border` et `size` #6690 +- Alert + - Ajout de l'attribut `center` pour que le contenu puisse être centré #6876 +- Menu + - Ajout des attributs `background-color`, `text-color` et `active-text-color` #7064 + - Ajout des méthodes `open` et `close` pour ouvrir et fermer les sous-menus par programmation, #7412 +- Form + - Ajout de l'attribut `inline-message` pour déterminer si le message de validation est affiché en ligne #7032 + - Ajout de l'attribut `status-icon` pour afficher une icône de feedback après validation #7032 + - Form et FormItem ont maintenant un attribut `size`. Les composants internes hériteront de cette taille s'ils ne sont pas spécifiés sur eux-mêmes, #7428 + - La méthode `validate` retournera maintenant une promesse si le rappel est omis, #7405 + - Ajout de la méthode `clearValidate` pour la validation des résultats pour tous les éléments de formulaire, #7623 +- Input + - Ajout des attributs `suffixe` et `préfixe` des slots nommés, `suffixIcon` et `prefixIcon` pour ajouter du contenu dans la zone de saisie #7032 +- Breadcrumb + - Ajout de l'attribut `separator-class` pour supporter les icônes comme séparateurs d'éléments #7203 +- Steps + - Ajout de l'attribut `simple` pour activer les étapes de style simple #7274 +- Pagination + - Ajout des attributs `prev-text` et `next-text` pour personnaliser les textes des pages précédente et suivante #7005 +- Loading + - Maintenant vous pouvez personnaliser l'icône et la couleur de fond avec les propriétés `spinner` et `background` #7390 +- Autocomplete + - Ajout de l'attribut `debounce`, #7413 +- Upload + - Ajout des attributs `limit` et `on-exceed` pour limiter le nombre de fichiers, #7405 +- DateTimePicker + - Ajout de l'attribut `time-arrow-control` pour activer `arrow-control` du TimePicker imbriqué, #743838 +- Layout + - Ajout d'un nouveau point d'arrêt `xl` pour les fenêtres plus larges que 1920px +- Table + - Ajout de l'attribut `span-method` pour la fusion de cellules + - Ajout de la méthode `clearSort` pour effacer le tri par programmation + - Ajout de la méthode `clearFilter` pour effacer le filtre par programmation + - Pour les lignes extensibles, lorsqu'une ligne est étendue, une classe `.expanded` sera ajoutée à sa liste de classes, afin que vous puissiez personnaliser son style + - Ajout de l'attribut `size` + - Ajout de la méthode `toggleRowExpansionRowExpansion` pour ouvrir ou réduire les lignes extensibles par programmation + - Ajout de l'attribut `cell-class-name` pour assigner un nom de classe aux cellules + - Ajout de l'attribut `cell-style` pour le style des cellules + - Ajout de l'attribut `header-row-class-name` pour assigner un nom de classe aux lignes d'en-tête + - Ajout de l'attribut `header-row-style` pour le style d'en-tête + - Ajout de l'attribut `header-cell-class-name` pour assigner un nom de classe aux cellules d'en-tête + - Ajout de l'attribut `header-cell-style` pour le style des cellules d'en-tête + - L'attribut `prop` de la tableColumn accepte maintenant les notations `object[key]` + - Ajout de l'attribut `index` pour TableColumn pour personnaliser les index de lignes +- Select + - Ajout de l'attribut `reserve-keyword` pour réserver le mot-clé de la recherche courante après avoir sélectionné une option. + +#### Corrections de bugs +- DatePicker + - Correction de `v-model` retournant le deuxième jour de la semaine sélectionnée en mode semaine #6038 + - Correction de la première entrée effacée dans le type `daterange` #6021 +- DateTimePicker + - Correction de DateTimePicker et TimePicker s'affectant l'un l'autre lors de la sélection #6090 + - Correction de l'heure et de la seconde qui peuvent être au-delà de la limite en sélectionnant l'heure #6076 +- TimePicker + - Correction de `v-model` qui ne se mettait pas à jour correctement lors du blur #6023 +- Dialog + - Correction des textes ayant des bords flous lors de l'ouverture et de la fermeture des listes déroulantes imbriquées #6088 +- Select + - Performances améliorées. Maintenant Vue dev-tool ne crashera pas quand un grand nombre de Select sont détruits #6151 +- Table + - Correction d'un bug ou la table reste masquée lorsque son élément parent apparaît depuis `display : none` + - Correction de l'extension de la largeur de la table lorsque l'élément parent a `display : flex` + - Correction d'un bug qui corrigeait le fait que les colonnes d'une table avec l'emplacement `append` disparaissaient lorsque les données étaient récupérées dynamiquement + - Correction de l'attribut `expand-row-keys` qui ne fonctionnait pas avec la valeur initiale + - Correction d'une défaillance du filtre lors de la mise à jour de `data` + - Correction d'une erreur de calcul dans la mise en page des colonnes fixes avec en-têtes groupés + - Correction d'un bug dynamique de `max-height` + - Correction de quelques erreurs de calcul de style + +#### Breaking changes +- Général + - Suppression de `theme-default`. + - Compatible avec Vue 2.5.2+ et IE 10+ + - L'événement `change` des composants de formulaire et l'événement `current-current-change` de la pagination ne se déclenchent plus que lors de l'interaction de l'utilisateur + - L'attribut `size` de Button et les composants de formulaire acceptent maintenant `medium`, `small` et `mini` + - Pour faciliter l'utilisation d'icônes tierces, les attributs `icon` du bouton et des étapes, `prefix-icon` et `suffix-icon` d'Input nécessitent maintenant un nom de classe complet +- Dialog + - Suppression de l'attribut `taille`. Maintenant la taille de Dialog peut être configurée par `width` et `fullscreen` + - Maintenant la visibilité de Dialog ne peut plus être contrôlée par `v-model` +- Rate + - Le `text-template` est renommé `score-template` +- Dropdown + - `menu-align` est renommé en `placement`. Maintenant il supporte plus de positions +- Transfert + - le `footer-format` est renommé en `format` +- Switch + - Les attributs commençant par `on-**` seront analysés pour les événements dans JSX, ce qui rend tous les attributs `on-*` de Switch incapable de fonctionner en JSX. Ainsi, les attributs `on-**` sont renommés en `active-*`, et par conséquent les attributs `off-*` sont renommés en `inactive-*`. Cette modification affecte les attributs suivants: `on-icon-class`, `off-icon-class`, `on-text`, `off-text`, `off-text`, `on-color`, `off-color`, `on-value`, `off-value` + - Les attributs `active-text` et `inactive-text` n'ont plus de valeurs par défaut +- Tag + - L'attribut `type` accepte maintenant `success`, `info`, ` warning` et `danger` +- Menu + - Suppression de l'attribut `theme`. La couleur du menu peut être configurée en utilisant `background-color`, `text-color` et `active-text-color` +- Input + - Suppression de l'attribut `icon`. L'icône du suffixe peut maintenant être configurée à l'aide de l'attribut `suffix-icon` ou du slot `suffix-icon` + - Suppression de l'attribut `on-icon-click` et de l'événement `click`. Maintenant pour ajouter le gestionnaire de clic sur les icônes, veuillez utiliser les slots nommés + - L'événement `change` se comporte maintenant comme dans l'input natif, qui ne se déclenche qu'en cas de blur ou en appuyant sur Entrée. Si vous avez besoin de répondre à l'entrée de l'utilisateur en temps réel, vous pouvez utiliser l'événement `input` +- Autocomplete + - Suppression de l'attribut `custom-item`. Le template de suggestions d'entrée peut maintenant être personnalisé en utilisant `scoped slot`. + - Suppression de l'attribut `props`. Vous pouvez maintenant utiliser l'attribut `value-key` pour désigner le nom de clé de l'objet de suggestion d'entrée pour l'affichage. +- Steps + - Suppression de l'attribut `center` + - Maintenant le Steps va remplir son conteneur parent par défaut +- DatePicker + - Le paramètre de l'événement `change` de DatePicker est maintenant la valeur liée elle-même. Son format est contrôlé par `value-format` +- Table + - Suppression de la prise en charge de la personnalisation du modèle de colonne à l'aide de `inline-template` + - `sort-method` s'aligne maintenant avec `Array.sort`. Il devrait retourner un nombre au lieu d'un booléen + - L'emplacement `append` est déplacé à l'extérieur de l'élément `tbody` pour éviter les rendus multiples + - L'événement `expand` est renommé en `expand-change` + - Les paramètres de la méthode `row-class-name` et `row-style` sont maintenant un objet + +## +* Rendre du HTML arbitraire de façon dynamique sur votre site Web peut être très dangereux car cela peut facilement mener à[des attaques XSS](https://en.wikipedia.org/wiki/Cross-site_scripting). Donc quand `dangerouslyUseHTMLString' est activé, assurez-vous que le contenu du `message' est fiable, et **ne jamais** assigner `message` au contenu fourni par l'utilisateur.. diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md new file mode 100644 index 0000000..827ed28 --- /dev/null +++ b/CHANGELOG.zh-CN.md @@ -0,0 +1,1775 @@ +## 更新日志 + +### 2.15.1 + +*2021-02-23* + +#### Bug fixes + +- Drawer + - 修复 Drawer bug (by @cs1707) +- Image + - 修复 image object fit ratio 在 IE 下的 bug (#19583 by @charlie0228) +- Cascader + - 修复 cascader panel active path (#20730 by @cs1707) +- Calendar + - 修复 calendar 国际化 bug (#20758 by @iamkun) +- ColorPicker + - 修复 bugs (by @UxieVerity) + +#### Optimization + +- Doc + - 更新 Axure 设计资源 v2.1.0 (by @iamkun) + +### 2.15.0 + +*2021-01-15* + +#### Bug 修复 + +- Select + - 修复 placeholder 国际化 bug (#17644 by @nzh63) +- Popconfirm + - 修复 Popconfirm 国际化 bug by @iamkun +- Drawer + - 修复 focus bug (#20626 by @cs1707) +- Image + - 图片预览优化 (#20652 by @cs1707) + +#### 优化 + +- Doc + - 更新法语文档 datetime-picker.md (#20543 by @lonk) + - 更新 Progress 组件文档 (#20641 by @cs1707) + +### 2.14.1 + +*2020-11-11* + +#### Bug 修复 + +- Popover + - 兼容 Vue 2.6 新 v-slot 语法 (#20424 by @iamkun) + +#### 优化 + +- I18n + - 更新阿拉伯语翻译 (#20202 by @elkattan) + - 更新维吾尔语翻译 (#20177 by @IlhamTahir) + +### 2.14.0 + +*2020-10-29* + +#### 非兼容性更新 + +- Popconfirm + - 事件名称修改为 `confirm`, `cancel` (#20240 by @hugiron) + +#### Bug 修复 + +- Progress + - 修复参数错误的问题 (#19985 by @Caaalabash) + +#### 优化 + +- I18n + - 更新俄语翻译 (#19451 by @yangirov) + - 更新高棉语翻译 (#20077 by @Sovai) + - 更新乌克兰语翻译 (#20344 by @MammutAlex) + +### 2.13.2 + +*2020-05-18* + +#### Bug 修复 + +- Autocomplete + - 修复 'change event' 错误 (#19200 by @sxzz) +- Image + - 更新错误状态 (#19194 by @lhx6538665) + +#### 优化 + +- I18n + - 更新 ru-RU popconfirm 翻译 (#19220 by @Opppex) + - 更新 vi 翻译 (#19244 by @quangln2810) + - 更新 Catalan 和 Spanish 翻译 (#19296 by @Ismaaa) + - 更新 Indonesia 翻译 (#19320) by @therour) + - 更新 Brazilian Portuguese 翻译 (#19374 by @diegomengarda) + + +### 2.13.1 + +*2020-04-13* + +#### 新特性 +- Autocomplete + - 添加 change 事件 (#17913 by @sxzz) + +#### Bug 修复 + +- Autocomplete + - 修复类型为 textarea 时建议错误问题 (#18478 by @Roojay) +- Carousel + - 修复 console.warn 文案拼写错误 (#18264 by @IceFox) +- Image + - 修复当 preview-src-list 属性不包含 src 时图片预览大图展示为空的问题 (#18975) (#19130 by @luckyCao) + - 修复第二次图片预览时快捷键失效问题 (#18983) (#19156 by @luckyCao) + - 修复 preview-src-list 为空时点击图片会给 body 添加 overflow: scroll 的问题 (#18967 by @inooNgt) +- Transfer + - 修复和 Form 组件一起使用时错误的行高问题 (#18917 by @Hanx) +- InputNumber + - 正确计算 inputNumberDisabled (#18439 by @ashuser-pendo) +- Chore + - 更新首页文案 (#19155 by @iamkun) +- Doc + - 更新 Popconfirm 文档 (#18324 by @iamkun) + - 修复 step-strictly 文档拼写问题 (#18705 by @dream2023) + - 修复 Steps 组件文档问题 (#17555 by @haoranyu) + +### 2.13.0 + +*2019-11-26* + +#### 新特性 + +- Popconfirm + - 新增 Popconfirm 组件 (#17548 by @iamkun) + +#### Bug fixes + +- BackTop + - 平滑过渡动画 (by @lon) +- DatePicker + - 修复选择最小日期的 bug (#17191 by @smk0621) +- Select + - 修复测试用例 (by @msidolphin) +- Tree + - 增加 font-size 样式 (#17094 by @spengjie) +- Table + - 头部可自定义 (#17291 by @ziyoung) + - 更新头部样式 (#17284 by @ziyoung) + - 修复时候 filter 之后高度问题 (#17348 by @ziyoung) + - 修复 row-style 失效的 bug (#17002 by @a631807682) + - 修复头部消失的 bug (#17341 by @ziyoung) +- Calendar + - 导入 el-button 和 el-button-group (#17376 by @masongzhi) +- MessageBox + - 修复图表位置 (#17410 by @nullptru) +- TimePicker + - 滚动后设置正确的位置 (#16868 by @mattheyan) +- Message + - 修复关闭的 offsetHeight(#17564) (#17852 by @gzwgq222) +- Form + - ValidateField 的回调应为可选项 (#17314 by @CarterLi) +- Cascader + - 修复 TypeScript 3.7 的兼容问题 (#17881 by @CarterLi) +- Menu + - 修复 NavigationDuplicated 在 vue-router@^3.1.0 的报错 (#17269 by @iamkun) +- Dropdown + - 更新类型文件 (#17550 by @iamkun) +- Progress + - 增加 strokeLinecap 属性 (#17552 by @iamkun) +- InfiniteScroll + - 跳过不可见元素触发 (#17553 by @iamkun) +- Image + - 优化用户体验 (#16985 by @luckyCao) + - 优化大图片展示问题 (#16796 by @luckyCao) +- Drawer + - 修复 drawer-append-to-body 失效的 bug (#16953 by @JeremyWuuuuu) +- Select + - 修复空 tag 的 bug (17199 by @luckyCao) +- Scrollbar + - 修复 FireFox 双滚动条的 bug (#18091 by @iamkun) + +#### Optimization + +- I18n + - 更新 sv-SE.js (#17926 by @FOLLGAD) + - 更新 avatar 组件法语文档 (#17762 by @blombard) +- Docs + - 修复 time-select 文档错误 (#17250 by @wacky6) + - 修复 Drawer 文档错误 (#17122 by @haoranyu) + - 更新 Spanish changelog 2.12.0 (#17364 by @Gonzalo2310) + - 修复 Changelog 文档错误 (#17874 by @renlixin) + - 修复 Loading 示例 (#17862 by @MBearo) + - 增加 input event 相关文档 (#18061 by @zhouxinyong) + - 移除 Input repeat change event 相关文档 (#18085 by @zhouxinyong) + +### 2.12.0 + +*2019-08-29* + +#### 新特性 + +- Popover + - 添加 close-delay 属性 (#16671 by @LachlanStuart) +- Theme + - 增加 Chrome 插件: Element Theme Extension (#16686 by @iamkun) +- Icon + - 支持 font-display 属性的配置 (#16805 by @iamfaizalandyka) + +#### Bug fixes + +- Table + - 在表头拖拽后阻止 click 事件的触发 (#16850 by @ziyoung) + - 修复表头 display 为 none 造成浏览器崩溃的问题 (#16956 by @luckyCao) + - 修复没有数据的时表格高度问题 (#16861 by @ziyoung) + - 调用 toggleExpansion 不再抛出异常 (#16304 by @yyjjqq94) + - 挂载时不再触发 sort-change 事件 (#17113 by @a631807682) + - 修复 setCurrentRow 方法不生效的问题 (#16879 by @ziyoung) + - 修复当数据异步加载时,expand-row-keys 不生效的问题 (#16899 by @ziyoung) + - 把 toggleAllSelection 设置为 Table 示例的属性 (#17137 by @ziyoung) +- Tree + - 修复文字与复选框之间的距离 (#16799 by @Hazlank) +- Tabs + - 修复 TabItem 位置不正确的问题 (#16520 by @victorting) + - 修复高亮的 Tab 不在可视区的问题 (#17033 by @nullptru) +- Calendar + - 修复日期的显示问题 (#16772 by @ubitoffee) + - 修复在夏令时的显示问题 (#17208 by @iamkun) +- Cascader + - 修复 CascaderPanel 的显示问题 (#16716 by @zhangHongEn) + - 禁用状态下,关闭按钮不显示 (#16224 by @yyjjqq94) +- Input + - 修复韩语输入问题 (#15069 by @MoonHyuk) + - 触发清除按钮的点击事件 (#16576 by @a631807682) +- Select + - 过滤时,不收起下拉框 (#17205 by @luckyCao) +- Transfer + - 修复样式问题 (#17206 by @iamkun) +- Dialog + - 添加 SCSS 变量 (#16365 by @haoranyu) +- RadioGroup + - is 指定时,不产生非法的 HTML 片段 (#17070 by @nullptru) +- Divider + - 支持自定义类 (#17078 by @island205) +- Carousel + - 修复 change 的触发时机 (#16705 by @iamkun) +- Notification + - 不修改传入的 option (#16704 by @iamkun) +- DatePicker + - 给 picker-option 添加 className 属性 (#16632 by @iamkun) +- DateTimePicker + - 修复时间选择滚动条的问题 (#16854 by @jesse-li) + +#### Optimization + +- Checkbox + - 提高可访问性 (#16575 by @tylertrotter) +- Docs + - 更新 changelog (#16773 by @SimonaliaChen) + - 更新贡献指南 (#14800 by @sinchang) + - 修复 Drawer 文档中的拼写错误 (#16848 by @winkay) + - 更新自定义主题 (#16983 by @iamkun) + - 新增 Esperanto 翻译 (#16955 by @maxkoryukov) + - 更新 input-number 文档 (#16316 by @luckyCao) + - 更新 Spanish 文档 (#16961 #16548 by @Gonzalo2310) +- I18n + - 更新加泰罗尼亚语翻译 (#14722 by @oscaralbareda) + - 更新阿拉伯语翻译 (#16653 by @l3op) +- Test + - 修复拼写错误 (#16672 by @boomler) + - 优化 image 的单元测试 (#16847 by @a631807682) +- Types + - 修复 httprequest 的类型 (#16633 by @luckyCao) + +### 2.11.1 + +*2019-07-26* + +#### Bug 修复 + +- Image + - 修复 Image 组件 SSR 兼容性 (#16737 by @luckyCao) +- Chore + - 更新 dart-sass 的兼容性 (#16744 by @LewisChennnnn) + +### 2.11.0 + +*2019-07-25* + +#### 新特性 + +- Drawer + - 新增抽屉组件 (#16577 by @JeremyWuuuuu) + +#### Bug 修复 + +- Checkbox + - 修复 CSS 样式问题 (#16006 by @Hazlank) +- Tree + - 更新类型定义为泛类型 (#15934 by @JeremyWuuuuu) + - 修复设置节点 isCurrent 的为 false 的问题 (#15870 by @kkkisme) +- Dropdown + - 更新 split-button 默认颜色 (#15931 by @JuniorTour) +- Cascader + - 修复一级菜单更新问题 (#16399 by @luckyCao) + - 懒加载时设默认值 (#16420 by @luckyCao) + - 修复当节点值重复时的显示问题 (#15935 by @junyiz) + - 对外暴露 getCheckedNodes 和修复 options 改变会影响选中的问题 (#16709 by @SimonaliaChen) +- Calendar + - 更新显示正确的 header 的逻辑 (#16354 by @ziyoung) +- Submenu + - 修复 append-to-body 问题 (#16289 by @a631807682) +- Table + - 修复 tree table 数据更新问题 (#16481 by @island205) +- Select + - 修复内存泄漏问题 (#16463 by @island205) +- InfiniteScroll + - 更新命名和说明 (#16698 by @iamkun) +- Avatar + - 修复图片不居中的问题 (#16489 by @luckyCao) +- Dialog + - 增加 destroyOnClose 属性 (#16455 by @ziyoung) +- Image + - 增加大图预览 (#16333 by @luckyCao) + +#### 优化 + +- Docs + - 修复 dropdown 示例 (#16193 by @webxmsj) + - 修正笔误 (#15971 by @howiefh) +- I18n + - 更新泰文翻译 (#16689 by @ponkrit) +- Chore + - 更新基础 API 地址 (#16607 by @iamkun) + - 增加 Form 的主题 token (#16699 by @iamkun) + - 更新统计 (#16609 by @iamkun) + - 修复文档锚点问题 (#16692 by @iamkun) + +### 2.10.1 + +*2019-07-02* + +#### Bug 修复 + +- Table + - 排序 icon 问题修复 (#15439 by @bezany) + - 修复 `append` slot 存在时布局错位问题 (#16332 by @ziyoung) + - 修复 `showOverflowTooltip` 更新无效的问题 (#16295 by @a631807682) + - 修复 `FilterPanel` 中 `Scrollbar` 未注册问题 (#16246 by @ziyoung) +- Chore + - 更新版本号,修复文档问题 (#16233 by @ziyoung) + - 修复英文首页样式问题 (#16254 by @iamkun) + +#### 优化 + +- Tag + - 兼容 IE (#16334 by @ziyoung) +- Chore + - 更新钉钉3群二维码 (#16236 by @iamkun) +- Doc + - 更新主题编辑器文档 (#16244 by @iamkun) + +### 2.10.0 + +*2019-06-25* + +#### 新特性 + +- I18n + - 支持乌兹别克语 (#15796 by @ogabek96) +- Calendar + - 支持 `first-day-of-week` 配置 (#16047 by @ziyoung) +- Avatar + - 新增 `Avatar` 组件 (#16144 by @luckyCao) +- Upload: + - 支持自定义缩略图模版 (#13192 by @victorzhuk) + + +#### Bug 修复 + +- Tree + - 当 `currentKey` 为 `null` 时取消对树节点的高亮 (#15668 by @yyjjqq94) + - 修复多实例共享数据的问题 #15538 (#15615 by @VanMess) +- Upload + - 更新 `fileList` 的类型定义 (#15716 by @underfin) +- Table + - 修复加载 icon 不显示的问题 (#15868 by @ziyoung) + - 修复复杂表格中 hover 行背景色问题 (#15504 by @cnlon) + - 修复 `current-row-key` 和选择事件的问题 (#15983 by @ziyoung) + - `height` 属性接受更多单位 (#16013 by @ziyoung) + - 修复 `reserve-selection` 无效的问题 (#16135 by @ziyoung) +- Menu + - 修复 `popper-append-to-body` 设置后,子菜单无法收起的问题 (#15391 by @PanJiaChen) +- Select + - 修复 `initialInputHeight` 问题 (#15989 by @yyjjqq94) + - 修复输入中文时 `default-first-option` 的行为问题 (#15431 by @VanMess) + - `import` 重复 (#16215 by @lengband) +- Message + - 类型定义中添加 `offset` 属性 (#16027 by @matjaz) +- Timeline + - 修复逆序问题 (#16091 by @ziyoung) +- Slider + - 补充 `input` 事件文档 (#15588 by @VanMess) +- InfiniteScroll + - 更新包名 (#16125 by @iamkun) +- MessageBox + - 修复 `distinguishCancelAndClose` 行为与文档不符的问题 (#15438 by @qingdengyue) +- PopupManager + - 修复无法复写 `z-index` 的问题 (#15738 by @luckyCao) +- Docs + - 删除不必要的内容 (#16194 by @Alexeykhr) + - 更正 `Divider` 属性类型 (#15889 by @haoranyu) +- Chore + - 更新测试 API 地址 (#15807 by @iamkun) + +#### 优化 + +- Tree + -优化循环性能 (#15699 by @KingJeason) +- Theme + - 更新 GA 打点,修改页底地址链接到主题编辑器 (#16007 by @island205) +- Badge + - 更新类型定义 (#16198 by @iamkun) +- Avatar + - 更新主题变量配置 (#16202 by @luckyCao) +- I18n + - 更新葡萄牙语 (#15776 by @gigioSouza) + - 更新波斯语 (#15881 by @pamenary) +- Docs + - 补充入门文档中的组件列表 (#16063 by @pape2016) + - 更新法语文档 (#16208 by @blombard) + - 为 `Alert` 添加 默认插槽文档 (#15444 by @Alexeykhr) + - 更新西班牙语文档 (#15840 by @Gonzalo2310) + - 更新法语文档中的拼写错误 (#15837 by @blombard) + - 更新 2.9.2 西班牙文档 (#16185 by @Gonzalo2310) + +#### 非兼容性更新 + +- Form + - 移除输入框的成功状态 (#16159 by @ziyoung) + +### 2.9.2 + +*2019-06-21* + +#### Bug 修复 + +- Chore + - 修复 TS 定义文件 (#15805 by @NateScarlet) + +### 2.9.1 + +*2019-05-30* + +#### 新特性 + +- Table + - Tree Table 支持 tree-props,default-expand-all,expand-row-keys 属性, toggle-row-expansion 方法,expand-change 事件 (#15709 by @ziyoung) + +#### Bug 修复 + +- Table + - 修复了一些问题 (#15709 by @ziyoung) +- Theme + - 更新接口域名 (#15784 by @iamkun) + +#### 优化 + +- Chore + - 更新 InfiniteScroll 组件定义文件 (#15794 by @iamkun) + +### 2.9.0 + +*2019-05-30* + +#### 新特性 + +- Backtop + - 新增 Backtop 组件 (#15541 by @iamkun) +- PageHeader + - 新增 PageHeader 组件 (#15714 by @ziyoung) +- InfiniteScroll + - 新增 InfiniteScroll 指令 (#15567 by @iamkun) +- Cascader + - 新增多选模式和 filter-method 方法 (#15611 by @SimonaliaChen) +- Message + - 信息依次展示 (#15639 by @island205) +- Tag + - 新增 effect 属性 (#15725 by @SimonaliaChen) +- Tabs + - 卡片模式下标题左对齐 (#15695 by @luckyCao) +- DatePicker + - 支持字符串常量 (#15525 by island205) +- Image + - 支持 attrs 和 listeners (#15578 by @VanMess) +- Theme + - 新增 popup 背景配置 (#15412 by @iamkun) +- Chore + - 更新文档首页 (#15682 by @iamkun) + +#### Bug 修复 + +- Table + - 修复排序条件为空时的排序问题 (#15012 by @joelxr) +- Image + - 修复 ssr 问题和 object-fit 的兼容性 (#15346 by @SimonaliaChen) +- Input + - 修复 show-word-count 样式问题 (#15359 by @lvjiaxuan) + - 修复删除图标样式 (#15354 by @YiiGuxing) +- Calendar + - 修复星期展示错误 (#15399 by @qingdengyue) + - 修复十月展示问题 (#15394 by @qingdengyue) +- Tabs + - 修复 padding 问题 (#15461 by @SimonaliaChen) +- Tag + - 修复阻止冒泡问题 (#15150 by @infjer) +- Form + - 修复 form-item 的高度错误 (#15457 by @SimonaliaChen) + - 修复 resetFields 问题 (15181 by @luckyCao) +- Tooltip + - 修复自定义 tabindex 不生效问题 (#15619 by @SimonaliaChen) +- Link + - 修复图标 class 问题 (#15752 by @iamkun) +- Select + - 回滚清除时,设置 value 为 null 的修改 (#15447 by @iamkun) +- Loading + - 修复 Dom 不更新的问题 (#15123 by @FAKER-A) +- Switch + - 修复事件重复触发问题 (#15178 by @FAKER-A) +- Slider + - 修复点击时样式问题 (#15561 by @luckyCao) +- Radio + - 修复 value 不更新的问题 (#14809 by @OverTree) +- Form + - 修复 resetFields 问题 (15181 by @luckyCao) +- Chore + - 更新依赖 (#15324 by ziyoung) +- Type + - 修复 Loading 定义文件 (#15635 by @iamkun) + - 修复 Icon 定义文件 (#15634 by @iamkun) + - 修复 Link 定义文件 (#15402 by @iamkun) + +#### 优化 + +- Cascader + - 重构 (#15611 by @SimonaliaChen) +- Chore + - 更新新建组件的脚本 (by @iamkun) +- Docs + - 重新命名文档变量 (#15185 by @liupl) + - 更新 Image 组件文档 (#15423 by @haoranyu) + - 修复 Form 组件文档错误 (#15228 by @SHERlocked93) + +### 2.8.2 + +*2019-04-25* + +#### Bug 修复 + +- Icon + - 更新 icon (#15272 by @iamkun) +- 文档 + - 修复 Form 与 Input 文档样式 (#15273 by @ziyoung) + +### 2.8.1 + +*2019-04-25* + +#### Bug 修复 + +- Icon + - 更新 Select 与 Cascader 的 icon (#15264 by @SimonaliaChen) + - 更新 icon (#15258 by @iamkun) + +#### 优化 + +- Chore + - 更新构建脚本 (#15267 by @ziyoung) +- Docs + - 修复 link 的样式 (#15265 by @iamkun) +- 其他 + - migrating 配置兼容驼峰名称 (#15260 by @SimonaliaChen) + +### 2.8.0 + +*2019-04-25* + +#### 新特性 + +- Divider + - 新增 Divider 组件 (#15055 by @island205) +- Rate + - 支持通过对象自定义 colors 与 icon-classes 属性 (#15051 by @SimonaliaChen) +- Link + - 新增 Link 组件 (#15052 by @iamkun) +- Calendar + - 新增 Calendar 组件 (#14908 by @ziyoung) +- Icon + - 新增图标 (#15214 by @iamkun) +- Alert + - 新增高饱和度主题 (#15041 by @island205) +- Image + - 新增 Image 组件 (#15117 by @SimonaliaChen) +- Collapse + - CollapseItem 支持禁用 (#15076 by @ziyoung) +- Carousel + - 新增 direction 属性,支持垂直方向切换 (#15122 by @ziyoung) +- Pagination + - 新增 hide-on-single-page 属性 (#15096 by @ziyoung) +- Slider + - 新增 marks 属性 (#15133 by @luckyCao) +- Input + - 新增 show-word-count 属性 (#15075 by @luckyCao) +- InputNumber + - 新增 step-strictly 属性 (#15050 by @luckyCao) +- Tooltip, Dropdown, Popover + - 新增 tabindex 属性 (#15167 by @ziyoung) + +#### Bug 修复 + +- Notification + - 修复标题不换行的问题 (#15008 by @iamkun) +- Form + - 修复动态表单校验规则不生效的问题 (#14985 by @luckyCao) + - 修复 label 的样式 (#14969 by @ziyoung) + - 当 required 为 true 时,显示星号 (#15144 by @ziyoung) +- Pagination + - 修复 slot 未更新的问题 (#14711 by @lucyhao) +- Table + - 修复懒加载时加载数据的 bug (#15101 by @ziyoung) + - 在合并单元格时,修复单元格的宽度计算不正确的问题 (#15196 by @ziyoung) + - 提升表格的性能 (#14868 by @ziyoung) + - 初始化时不再触发 sort-change 事件 (#14625 by @PeanutWatson) + - 让 height 与 max-height 属性的行为保持一致 (#14660 by @arthurdenner) +- Dialog + - 修复内容不换行的问题 (#15027 by @iamkun) +- Alert + - 更新 typescript 定义文件 (#15186 by @ziyoung) +- Tabs + - Fix issue where Promise rejection was hitting application (#14816 by @ffxsam) + - slot 改变时,重新渲染 (#15238 by @ziyoung) +- Message + - 修复 typescript 定义文件 (#14968 by @agoni1212) +- Select + - 修复当 value 为 undefined 或者 null 的报错 (#15022 by @luckyCao) +- Tree + - 当前节点被删除后,选中的节点也应该删除 (#14604 by @sinchang) + - 提升性能 (#14881 by @ChenZhuoSteve) +- Dropdown + - 修复样式 (#14907 by @doing123) +- Slider + - 修复可访问性问题 (#14792 by @erezsob) +- Menu + - 如果 defaultIndex 不存在,activeIndex 应该为空 (#14074 by @hoythan) +- Directive + - RepeatClick: 使用 Date.now 提升性能 (#14776 by @pavelmash) +- Upload + - 修复 Upload 的背景颜色 (#15039 by @iamkun) +- Theme + - 添加无圆角变量 (#15256 by @iamkun) + +#### 优化 + +- Chore + - 更新中文 changelog (#14965 by @iamkun) + - 当 demo 描述为空时,不再显示 (#15014 by @ziyoung) + - 显示 DevServer 的信息 (#15028 by @iamkun) + - 修复 2.6 changelog 的 bug (#15026 by @iamkun) + - 更新构建脚本 (#14821 by @abc3660170) + - 本次开发时支持热更新 (#15221 by @SimonaliaChen) + - 本地开发时,加载 sourcemap (#15087 by @ibufu) +Docs + - 重命名 demo 中的变量 (#14602 #15003 #15094 #15105 by @liupl) + - 修复 upload 文档中的错误 (#15023 by @iamkun) + - 更新 Form 文档 (#15040 by @iamkun) + - 更新 Tabs 文档 (#15053 by @iamkun) + - 使用 eleme.cn 作为新域名 (#15139 by @ziyoung) + - 修复 Image 组件的路由名 (#15194 by @iamkun) + - 删除多余的法语翻译 (#15207 by @iamkun) + +#### 非兼容性更新 + +- Rate + - 禁用情况下,显示小位数 (#15089 by @haoranyu) +- Select + - 过滤情况下,placeholder 为选中选项的 label (#14989 by @ibufu) + +### 2.7.2 + +*2019-04-03* + +#### 修复 + +- Form + - 修复 `label-width` 为 `auto` 的样式 (#14955 by @ziyoung) + +#### 优化 +- Docs + - 修复文档内图片链接错误 (#14957 by @iamkun) +- Chore + - 修复发布时 mkdir 异常 (#14952 by @iamkun) + +### 2.7.1 + +*2019-04-03* + +#### 修复 + +- Select + - 清空时设置 value 为 null (#14322 by @aaronfulkerson) +- Input + - 当类型改变时更新 DOM (#14889 by @wacky6) +- Table + - 修复当有展开列时 `defaultExpandAll` 的行为 (#14935 by @ziyoung) +- Dialog + - 可以设置背景色 (#14939 by @ziyoung) +- Form + - `label-width` 支持自动宽度 (#14944 by @ziyoung) + +#### 优化 +- Docs + - 更新西班牙语文档 (#14913 by @Gonzalo2310) + - 新增组件自动生成法语文档 (#14924 by @ziyoung) + - 更新 Tabs 文档 (#14938 by @ziyoung) + +### 2.7.0 + +*2019-03-28* + +#### 新特性 + +- Table + - 增加对树形结构数据的支持 (#14632 by @ziyoung) + +#### 修复 + +- Tabs + - 阴影样式使用全局主颜色 (#14558 by @Richard-Choooou) + - 当 label 改变时触发更新 (#14496 by @akki-jat) +- Table + - Table footer 与 body 的对齐一致 (#14730 by @ziyoung) +- NavMenu + - 修复点击 el-submenu 多次触发 childMenu 问题 (#14443 by @PanJiaChen) +- Dropdown + - 兼容 Vue 2.6 新 v-slot 语法 (#14832 by @ziyoung) +- ColorPicker + - 修复十六进制颜色字符串解析问题 (#14793 by @iamkun) +- Tree + - 恢复 pr #13349 (#14847 by @ziyoung) +- Tooltip + - 当初始值为 true 时默认显示 (#14826 by @ziyoung) +- Docs + - 更新 Cascader 文档 (#14442 by @panhezeng) +- Style + - 修复媒体查询 sm-only, md-only, lg-only 问题 (#14611 by @sinchang) + +#### 优化 + +- Chore + - 增加网页描述信息 (#14802 by @iamkun) + +### 2.6.3 + +*2019-03-21* + +#### 修复 + +- 修复 Cascader 文档页的样式 (#14789 by @ziyoung) +- 移除 Cascader 中多余的 DOM 操作 (#14788 by @ziyoung) +- DateRange 支持夏令时 (#14562 by @wacky6) + +### 2.6.2 + +*2019-03-21* + +#### 新特性 + +- DatePicker + - 支持 monthrange 类型 (#14487 by @zxyRealm) +- i18n + - 添加 Croatian 语言包 (#14360 by @danijelh) +- Docs + - 更新 2.6.1 法语文档,修复笔误 (#14555 by @smalesys) + - 更新法语翻译 (#14643 by @smalesys) + +#### 修复 + +- Input + - Fix regression (#14572 by @wacky6) +- DatePicker + - 修复 first-day-of-week 的计算 (#14523 by @sinchang) + - 修复 WeekPicker value-format 的问题 (#13754 by @wacky6) +- Steps + - 修复 #14502 (#14596 by @sinchang) + - 修复简单模式下的样式 (#14610 by @sinchang) +- Docs + - 重命名 Table 文档中的变量 (#14587 by @likwotsing) + - 添加法语文档索引 (#14565 by @iamkun) + - 修复 TimePicker 文档页的样式 (#14579 by @ziyoung) + - 重命名 Upload 文档中的变量 (#14593 by @liupl) + - 在 Form 文档中 添加的 async-validator 文档 (#14694 by @iamkun) + - 修复 Tooltip 文档的 bug (#14748 by @iamkun) + - 修复笔误 (#14751 by @2bj) + - 修复 Switch 在移动端 Webkit 浏览器的高亮问题 (#14703 by @VladG0r) + +#### 优化 + +- Chore: + - 更新 ci 构建脚本 (#14600 by @ziyoung) + - 更新谷歌统计 (#14560 by @iamkun) + - 添加更多谷歌统计事件 (#14633 by @iamkun) + - 更新聊天组信息 (#14741 by @iamkun) + - 升级测试依赖 (#14735 by @wacky6) + - 升级 gulp (#14745 by @ziyoung) + - 使用 codepen 显示 demo,修复文档中的错误 (#14747 by @ziyoung) + +### 2.6.1 + +*2019-03-03* + +#### 修复 + +- **不再指定 node 版本** (by @iamkun in #14546) +- 调整 `deloy-faas.sh` 中的文档目录 (by @ziyoung in #14553) +- 调整 2.6.0 中 changelog 日期样式 (by @island205 in #14547) +- 修复拼写错误 (by @wack6 in #14552) + +### 2.6.0 + +*2019-03-01* + +#### 新特性 +- Timeline + - 添加 Timeline 组件 (by @jikkai in #14248) +- DropdownItem + - `el-dropdown-item` 支持添加 icon (by @gabrielboliveira in #14088) +- Input + - 添加 `show-password` 属性,支持配置显示密码按钮 (by @phshy0607 in #13966) +- Select + - 添加 slot `empty` (by @elfman in #13785) +- Autocomplete + - 添加 `highlight-first-item` 属性,控制是否默认突出显示远程搜索建议中的第一项 (by @YamenSharaf in #14269) +- I18n + - 添加亚美尼亚语支持 (by @hamletbarsamyan in #14214) +- Docs + - 新增法语文档 (by @smalesys in #12153, #14418, #14434) + +#### 优化 +- Alert + - 组件对通过 slot 传入的 description 也应用默认样式类 (by @iamkun in #14488) +- InputNumber + -移除多余的 `parseFloat` (by @JuniorTour in #14172) +- Menu + - 支持 `el-menu-item` 不添加 index (by @georgyfarniev in #13298) +- Table + - 移除无用的 DOM 操作 (by @elfman in #13643) +- Upload + - 代码优化 (by @elfman in #13973) +- Popup + - 移除无用代码 (by @KAionro in #14413) +- Docs + - 添加更多文档说明如何贡献代码 (by @island205 in #14355) + - 添加 `el-input` 是受控组件的警示 (by @wacky6 in #14463) + - 优化 Table 的文档 (by @luguokong in #14329) + - 更新 Input 文档 (by @iamkun in #14437) + - 优化自定义主题文档 (by @wangguohao in #14297) + - 为 Icon 文档添加 hover 效果 (by @tuxinghuan in #14295) +- Build + - 压缩 Element 文档站的 JS 和 CSS 文件 (by @iamkun in #14430) + - 优化 Webpack 打包速度,从6分钟优化到1分多 (by @hetech in #14484) + - 添加 CLI 工具,选择版本号 (by @hetech in #14354) +- 使用 Stale 来管理过时(暂定1年)的 Issue 和 PR (by @island205 in #14392) + +#### 问题修复 +- Menu + - 修复浏览器标签切换引起的 focus 问题 (by @liupl in #13976) +- MessageBox + - 修复 TS 定义 (by @NateScarlet in #14278) +- ScrollBar + - 修复点击鼠标右键导致拖动的问题 (by @xifeiwu in #14196) +- Switch + - 添加 `validate-event` 属性,设置改变 Switch 状态时是否触发表单的校验 (by @hetech in #14426) +- Table + - 修复多 Table 实例共享 `toggleAllSelection` 方法,造成无法切换问题 (by @letanure in #14075) +- Tabs & Dropdown + - 修复样式问题 (by @hetech in #14452) +- Tree + - 与 Table 统一占位文样式 (by @ColinCll in #14331) +- Docs + - 修复 DatetimePicker 文档问题 (by @iamkun in #14290) + - 修复 DatePicker 文档拼写问题 (by @helmut in #14481) + - 修复分页组件文档样式问题 (by @liuchuzhang in #14451) + +#### 非兼容性更新 +- Table + - 修复 row 事件的参数顺序 (by @jikkai in #12086) + +### 2.5.4 + +*2019-02-01* + +#### 修复 + +- 构建: 修复 `.babelrc` 配置问题——导致 Tree 等组件没有动画 (by @island205 in #14282) + +### 2.5.3 + +*2019-01-31* + +#### 优化 + +- 优化 Message 的代码 (by @vok123 in #14029) +- 移除 gh-pages (by @ziyoung in #14266) +- 添加 IssueHunt 的链接 (by @island205 in #14261) + +#### 修复 + +- 修复 UMD 包在服务器端运行出错的问题 (by @island205 in #14242) +- 修复 Tabbar 高亮时的样式 (by @iamkun in #14240) +- 修复 Table 示例代码的错误 (by @xunmeng in #14253) + +### 2.5.2 + +*2019-01-27* + +#### 优化 +- 文档: + - 2.5.1 版本西班牙语文档更新 (by @Gonzalo2310 in #14231) + +#### 修复 +- 构建: + - 删除 umd 模块 `lib/index.js` 中本没有的注释 (by @island205 in #14233) + - 修复 nuxt.js 中关于 `export` 关键字的报错 (by @island205 in #14232) + - 修复发布 2.5.1 过程中的错误 (by @iamkun in #14228) + +### 2.5.1 + +*2019-01-26* + +#### 优化 +- DatePicker:添加月、年高亮的样式(by @Debiancc in #14211) +- 更新 2.5.0 changelog (by @wacky6 in #14217) + + +#### 修复 +- 修复升级 Webpack 4 产生的问题,无法具名 `import` 组件,`ELEMENT.locale()` 调用报错。(by @island205 in #14220) +- 恢复 2.4.11 文档 (by @iamkun in #14222) + + +### 2.5.0 + +*2019-01-25* + +#### 新特性 +- DatePicker + - 新增 `validate-event` 属性 (by @ziyoung in #13531) +- DateTimePicker + - `pickerOptions` 支持 `selectableRange` 选项 (by @eeeeeeeason) +- Tag + - 新增 `click` 事件 (by @licdream in #14106) +- I18n + - 新增 柯尔克孜语 (Kyrgyz) (by @zzjframework in #14174) + +#### 优化 +- 升级到 webpack@4 (by @jikkai in #14173) +- Input + - 简化内部实现,遵循单向数据流;修复若干相关 Bug (by @wacky6 in #13471) +- 更新 Axure 文件,增加新组件 (by @ziyoung in #13773) + +#### 修复 +- Autocomplete + - 修正下拉框最后一行显示不完整的问题 (by @ziyoung in #13597) + - 修正下拉框箭头 (by @liuchuzhang in #13762) +- Carousel + - 组件销毁时释放内部 Timer (by @elfman in #13820) +- Cascader + - 移除已废弃的计算属性的 cache 属性 (by @iamkun in #13737) + - 修正 TypeScript 中 CascaderOption 类型定义 (by @NateScarlet in #13613) + - 修正图标覆盖文字的问题 (by @ziyoung in #13596) +- Checkbox + - 改进显示样式 (by @PanJiaChen) +- DatePicker + - 修正 TimeSpinner 中缺失的 v-for `key` 属性 (by @Ende93 in #13547) + - 修正周选择器在跨年时的高亮行为 (by @suyi91 in #13883) +- Input + - 修复 textarea 时的 DOM 节点引用 (by @laomu1988 @island205 in #13803) +- Pagination + - 输入框的值不会小于 1 (by @elfman in #13727) +- Popover + - 修正 hover 的触发行为 (by @goldengecko in #13104) + - 修正弹出框的内存泄漏 (by @qpxtWhite in #13988) +- Radio + - 改进显示样式 (by @ohhoney1) +- Table + - 改进点击排序箭头时的行为 (by @ohhoney1 in #12890) + - 修正 IE10+ 中 “暂无数据” 提示的垂直布局 (by @imzjy in #13638) + - 修正文档中 `index` 的类型说明 (by @ilovefafa in #13628) + - 修正多级表头使用 `fixed` 属性时,表尾合计行的显示样式 (by @luckyCao in #13914) +- Tabs + - 修正自动滚动 (by @iamkun in #13696) + - 通过面板名称查找面板 (by @iamkun in #13705) + - 使用 `paneName` 计算面板样式 (by @iamkun in #13733) +- Tree + - 修正 `showCheckbox` 不能影响子节点的问题 (by @KidneyFlower) + - 更新文档和 TypeScript 定义 (by @ziyoung in #13540) +- Upload + - `list-type` 改变时,保留 `url` 属性 (by @elfman in #13771) +- Slider + - 修正源代码缩进 (by @wacky6 in #13955) +- I18n + - 补充加泰罗尼亚语 (Catalan) 翻译 (by @jaumesala) + - 补充俄语 (Russian) 翻译 (by @justlp in #13658) + - 补充芬兰语 (Finnish) 翻译 (by @jenkrisu in #14137) +- Doc + - 更新西班牙语文档至 2.4.11 (by @Gonzalo2310 in #13522) +- 其它 + - 移除多余的构建脚本 (by @ziyoung) + - 修正文档超链接 (by @iamkun in #13753) + - 修正文档中不一致的大小写 (by @wonderjar) + - 增加钉钉群的二维码 (by @iamkun in #13957) + - .gitignore 增加 yarn 日志文件 (by @mimimi in #13922) + - 移除赞助商 多态 (by @island205 in #14156) + - Update readme qr code src (by @iamkun in #13960) + - 更新 CDN 链接,修正错别字 (by @ziyoung) + +### 2.4.11 + +*2018-11-21* + +- 撤销 pr #13296,修复点击 Menu 外部导致 Submenu 收起的问题,#13478 +- 调整小屏幕(xs)媒体查询断点,#13468 (by @alekoshen712) + +### 2.4.10 + +*2018-11-16* + +- 修复多次点击 Select 才显示下拉列表的问题,#13268 +- Form 禁用时不显示 Input 的 clear 图标,#13208 +- 调整 Select,Progress,Autocomplete,Tooltip,Collaspe,TimePicker 的样式,#13188 (by @porcelainHeart) #13210 #13266 #13257 #13290 #13347 (by @PanJiaChen) +- Carousel 组件新增 `loop` 属性,#13217 +- Table 的 data 改变时,高亮行会继续保留,#13200 +- Table 的 header slot 可以接收参数,#13263 +- Table 的 `clearFilter` 方法支持参数,#13176 +- Table 单元格内没有内容时不再创建 Tooltip,#13152 (by @rongxingsun) +- ColorPicker 面板的输入框内容可以正常显示了,#13278 +- 在拖拽时,ColorPicker 不再触发表单校验,#13299 +- InputNumber 新增 `select` 方法,#13286 (by @st-sloth) +- Autocomplete 新增 `clear` 事件,#12171(by arthurdenner) #13326 +- 可以通过点击 Menu 外部来关闭 Menu,#13296 +- Form 的 `validateField` 方法可以接收参数,#13319 +- Cascader 新增 `visible-change` 事件,#13415 +- DatePicker 新增 range-separator slot, #13272 (by @milworm) +- Tree 新增 `iconClass` 与 `currentNodeKey` 属性,#13337 #13197 (by @isnifer) +- Progress 的 `status` 添加了 text #13198 (by @ali-master) +- 修复 Tree 的 `defaultCheckedKeys` 导致显示的错误,#13349 (by @dive2Pro) + +### 2.4.9 + +*2018-10-26* + +- Form 组件 clearValidate 方法参数支持字符串,#12990 (by @codinglobster) +- Badge 新增 type 属性,#12991 +- 用户可以使用 scoped-slot 来自定义表头,#13012(by @ivanseidel) +- 修复 IE 下 Select 输入框不能输入的问题,#13034(by @GaliMU) +- Select 多选时,选项不换行,#12329 (by @akki-jat) +- Select 下拉列表展开后,箭头图标也可以正确显示,#12353(by @firesh) +- 修复 Select 的 size 属性不生效的问题,#13070 +- 多选时可以清除 Select 已选中的值,#13049(by @ZSkycat) +- 修复最后一个 TabNav 不能删除的问题,#13039 +- 修复 TabNav 中 label 显示不正确的问题,#13178 +- Alert 新增 title slot,#13082(by @Kingwl) +- 修复 Table 中的 tooltip 内容不正确的问题,#13159(by @elfman) +- 优化 Upload 文件列表删除时的动画,#12987 +- 当 InputNumber 控制按钮不显示时,调整了边距,#13052 + +### 2.4.8 + +- Switch 聚焦时不显示轮廓,#12771 +- 修复 Dropdown 在 ButtonGroup 中样式问题,#12819 (by @bluejfox) +- Dialog 新增 opened 事件,#12828 +- 修复 TabNav 显示顺序不正确的问题,#12846 +- 修复 Tabs 没有滑动到选中 tab 的问题,#12948 +- 修复 Tree 节点在拖拽时标识符不显示的问题,#12854 +- Form 的 validate 事件参数中包含了校验的信息,#12860 (by @YamenSharaf) +- 修复 DatePicker 没有校验用户输入时间的合法性问题,#12898 +- 修复 Table 表头的 `render-header`属性不生效的问题,#12914 + +### 2.4.7 + +*2018-09-14* + +- 修复 DatePicker 未触发表单检验的问题,#12328,#12348 +- 修复 DatePicker 多选时报错的问题,#12347 +- 修复 DatePicker 选择时间时 spinner 位置不正确的问题,#12415 (by @rang-ali) +- 修复 Datepicker 输入框自动填充的问题,#12521 (by @abdallanayer) +- 修复 Cascader 中 Input 未高亮的问题,#12341 +- 修复 Tabpane 顺序不正确的问题,#12346 +- 修复 ColorPicker 取色光标位置不正确的问题,#12376 (by @cnwhy) +- 调整 Submenu 的样式,#12457 +- 修复 Submenu 选中后没有高亮的问题,#12479 +- 修复 Cascader 选择值不正确的问题,#12508 (by @huangjinqiang) +- 修复 Pagination 输入框值不正确的问题,#12525 +- 调整 Pagination 触发事件的顺序,#12530 +- 修复 Table 的 filter 不显示的问题,#12539 +- 修复 Tree 无法删除节点的问题,#12684 +- 修复 Select 在单选时 Input 高度变化的问题,#12719 +- 修复 Form 在嵌套时 label 显示不正确的问题,#12748 +- 新增 Input 的 autocomplete 属性,废弃 auto-complete 属性,#12514 (by @axetroy) +- 新增 Form 的 slot-scope 展示表单校验信息,#12715 (by @YamenSharaf) + +### 2.4.6 + +*2018-08-09* + +- 修复 Table 的 filter 初始值为空数组时不显示筛选图标的问题,#12165 +- 修复 Menu 在更改 `collapse` 时不保存菜单激活状态的问题,#12178 (by @elfman) +- 修复 Cascader 未转义特殊字符的问题,#12248 +- 修复禁用的 RadioButton 在点击时显示 box-shadow 的问题,#12262 +- 修复 Select 初始值为 `undefined` 时方向键失效的问题,#12322 +- 修复 Select 多选时输入的关键字消失的问题,#12304 +- 修复 Select 多选时查询函数没有去抖的问题,#12181 +- 修复 Dialog 在全屏显示时宽度不正确的问题,#12203 +- 修复 Main 在 IE 下的显示不正确的问题,#12237 +- 修复 Input 触发两次表单校验的问题,#12260 +- 修复 Tree 在懒加载时添加节点导致节点消失的问题,#12256 +- 修复 Tree 节点在拖拽后无法删除的问题,#12279 +- 修复 Popover 在 InputNumber 聚焦时不显示的问题,#12284 +- 添加 Autocomplete 的 popper-append-to-body 属性,#12241 +- 添加 Pagination 的 `page-size` 属性 `sync` 修饰符的支持,#12281 + +### 2.4.5 + +*2018-07-26* + +- 修复 Table 设置 `class-name` 对 `expand` 列不生效的问题,#12006 +- 新增 Table 的 `toggleAllSelection` 方法,#12047 +- 修复 Input 包含 Select 时,suffix 插槽位置显示不正确的问题,#12108 +- 修复 Option 的 `line-height` 无法设置的问题,#12120 +- 修复初始值为 `null` 的 TimeSelect 在执行 `resetField` 后无法再赋值的问题,#12010 +- 修复 Tree 组件中不响应方向键以外 keydown 事件的问题,#12008 +- 修复 Tree 在懒加载情况下选中父节点的问题,#12106 +- Tree 的 `getCheckedNodes` 方法新增 `includeHalfChecked` 参数,#12014 + +### 2.4.4 + +*2018-07-13* + +- 修复重置表单后触发 Select 组件校验问题,#11837 +- 修复 Input 组件 `suffix` 与 `append` 共存时样式错乱问题,#11951 +- 修复可清空的只读 Input 仍会显示清空图标的问题,#11967 +- 修复 Tree 节点禁用时仍可以选中的问题,#11847 +- 修复 Tree `default-checked-keys` 属性不生效的问题,#11971 +- 修复 Tree 在过滤节点时下 `empty-text` 不显示的问题,#11971 +- 修复 Table 的 `empty-text` 过长时的位置样式问题,#11965 +- 修复 Table 的 `current-row-key` 设置为 `null` 时高亮行不清除的问题,#11866 +- 修复当 `filters` 为空数组时显示过滤器下拉列表的问题,#11864 +- 修复 Radio 的 label 不阻止事件冒泡的问题,#11912 + +### 2.4.3 + +*2018-07-03* + +- 修复当自定义 Tree 节点高度时,`allow-drop` 不能正常工作的问题,#11797 +- 现在 Form 的 `clearValidate` 方法支持传入参数,指定需要清空校验结果的 FormItem,#11821 +- 新增 MessageBox 的 `distinguishCancelAndClose` 属性,#11831 + +### 2.4.2 + +*2018-06-26* + +- 修复 Table 的 `class-name` 和 `label-class-name` 属性不支持动态更新的问题,#11626 +- 修复 Table 在 `highlight-current-row` 为 `false` 时点击行也会触发高亮的问题,#11691 #11563 +- 修复 ButtonGroup 中只有一个 `round` 或 `circle` 的 Button 时的样式错误,#11605 +- 修复在某些情况下 Pagination 的条目数选择器的样式错误,#11622 +- 修复 Menu 的 `collapse` 属性变化后无法使用 `open` 方法的问题,#11646 +- Tabs 的 `before-leave` 钩子添加了 `activeName` 和 `oldActiveName` 参数,#11713 +- 修复 Cascader 关闭后的聚焦问题,#11588 +- 修复 Cascader 在 `change-on-select` 状态下点击选项不关闭的问题,#11623 +- 现在通过代码改变 Select 的值后会触发表单校验,与 Input 行为一致,#11672 + +### 2.4.1 + +*2018-06-08* + +- 移除 Autocomplete 的重复类型声明,#11388 +- 修复嵌套在 Form 内的 Select 在 FireFox 浏览器中下拉箭头错位的问题,#11427 +- 修复 Select 的初始值为 `null` 时仍然显示清除图标的问题,#11460 +- 修复禁用的 Radio 在点击时显示 box-shadow 的问题,#11462 +- 新增 MessageBox 的 `iconClass` 属性,#11499 +- 新增 Tabs 的 `stretch` 属性,#11476 +- 修复 Tabs 开启 `lazy` 时渲染顺序异常的问题,#11461 +- 修复 Table 展开行时无法保留选中行样式的问题,#11464 +- 修复 Tabs 调用 `before-leave` 并返回 Promise 的时候,Tabs 会存在 focus 状态的问题,#11386 +- 修复 Popover 禁用状态下创建弹出框的问题,#11426 +- 修复 Tree 在懒加载状态下添加新节点造成无限循环的问题,#11430 (by @wangjingf) +- 新增 Dialog 的 `closed` 事件,#11490 + +### 2.4.0 Fullerene + +*2018-05-28* + +#### 新特性 +- 综合 + - 使用原生 webpack 作为构建和打包工具,#11216 + - 可以全局配置弹出层的初始 z-index,#11257 +- Autocomplete + - 新增 `hide-loading` 属性,#11260 +- Button + - 现在圆形按钮也支持通过 `size` 属性改变其尺寸了,#11275 +- InputNumber + - 新增 `precision` 属性,#11281 +- Tabs + - 新增 `before-leave` 钩子,#11259 + - 新增 `lazy` 属性,#11167(by @Kingwl) +- Table + - 新增 `sort` 方法,支持手动排序,#11311 + +#### 修复 +- Input + - 修复使用中文输入法快速输入文字时会导致视图重新渲染的问题,#11235(by @STLighter) +- Popover + - 修复当触发元素为 Radio 或 Checkbox 时控制台报错的问题,#11265 +- Breadcrumb + - 修复 `to` 属性不支持动态更新的问题,#11286 +- Upload + - 修复在 `beforeUpload` 方法返回的 Promise 中 resolve 一个 File 时控制台报错的问题,#11297(by @qusiba) +- Tooltip + - 修复内容为空时箭头错位的问题,#11335 +- Autocomplete + - 修复在快速删除搜索内容后输入建议不正确的问题,#11323 +- ColorPicker + - 修复关闭选色器时触发 `active-change` 事件的问题,#11304 +- Table + - 修复筛选列表过长导致样式超出的问题,#11314 + - 修复排序后导致无法正常显示选中行样式的问题,#11348 +- Checkbox + - 修复单个 Checkbox 不支持表单验证的问题,#11271 +- Radio + - 修复通过空格可以选中被禁用的 Radio 的问题,#11303 +- MessageBox + - 修复连续打开两个 MessageBox 时 `el-popup-parent--hidden` 无法移除的问题,#11371 + +### 2.3.9 + +*2018-05-18* + +- 修复当 TableColumn 的 `prop` 属性指定的字段在数据源中不存在时,鼠标移入该列单元格会报错的问题,#11137 +- 弹出类组件的 `lockScroll` 属性不再为父元素添加内联样式,而是添加相应类名,#11114 +- 修复 Progress 在 `status` 为 exception 时图标不显示的问题,#11172 +- 修复可搜索的 Cascader 在输入关键词后,选项的 `disabled` 属性失效的问题,#11185 +- 修复可展开的 Table 在展开某一行后更新数据源会造成该行无法收起的问题,#11186 +- Tree 的 `setCurrentKey` 方法支持传入 `null`,可取消当前高亮的节点,#11205 + +### 2.3.8 + +*2018-05-11* + +- 修复 `type` 为 dates 的 DatePicker 在选择非当前月的日期后,面板会跳转至当前月的问题,#10973 +- 修复可清空的只读 Input 仍会显示清空图标的问题,#10912 +- 修复范围选择的 DatePicker 在未改变值的情况下关闭下拉面板仍会触发 `change` 事件的问题,#11017 +- 修复 Select 在有分组选项时不能正确通过键盘导航的问题,#11058 +- 新增 Select 的 `prefix` 具名 slot,#11063 +- 新增 FormItem 的 `clearValidate` 方法,#11076 +- 新增 Tree 的 `checkOnClickNode` 属性,#11111 + +### 2.3.7 + +*2018-04-29* + +- 修复 Table 在由于筛选而使原有的滚动条消失后表头各列宽度未及时更新的问题,#10834 +- 修复可清空的 Input 在初始值为 `null` 时仍然显示清空图标的问题,#10912 +- 修复在通过代码改变 ColorPicker 的绑定值后错误地触发 `active-change` 事件的问题,#10903(by @zhangbobell) +- 修复可搜索的 Select 在备选项均被禁用时,通过键盘导航会造成无限循环的问题,#10945 + +### 2.3.6 + +*2018-04-21* + +- 修复 Tree 的 `allow-drop` 回调在使用 `type` 参数后的错误行为,#10821 +- 修复可搜索的单选 Select 在 IE11 中无法输入搜索关键词的问题,#10822 +- 修复单选 Select 在使用鼠标选中某个选项后错误地触发 `blur` 事件的问题,#10822 + +### 2.3.5 + +*2018-04-20* + +- 修复 DatePicker 的 `type` 为 week 时面板错误高亮的问题,#10712 +- 修复 InputNumber 初始值为 0 时输入框为空的问题,#10714 +- 新增 Select 的 `automatic-dropdown` 属性,#10042(by @Seebiscuit) +- 修复 `disabled` 的 Rate 仍能通过键盘左右键改变组件值的问题,#10726(by @Richard-Choooou) +- 现在 DatePicker 的 `type` 属性可以接收 `'dates'`,用于选择多个日期,#10650(by @Mini256) +- 新增 Pagination 的 `prev-click` 和 `next-click` 事件,#10755 +- 新增 Pagination 的 `pager-count` 属性,#10493(by @chongjohn716) +- 新增 `type` 作为 Tree 的 `allow-drop` 属性回调的第三个参数,#10792 +- 改用 ResizeObserver 对元素的尺寸变化进行监测,#10779 + +### 2.3.4 + +*2018-04-12* + +- 删除 SubMenu 在 TypeScript 类型声明中重复的 `showTimeout` 属性,#10566(by @kimond) +- 现在 Transfer 数据项的渲染支持通过 scoped slot 自定义,#10577 +- 修复点击 Pagination 禁用的上一页、下一页按钮仍会触发 `current-change` 事件的问题,#10628 +- 修复未绑定值的 Textarea 在 SSR 中会显示 `undefined` 的问题,#10630 +- 修复 `type` 为 border-card 的 Tabs 中被禁用标签项的样式,#10640 +- 新增 `$index` 作为 Table 的 `formatter` 属性回调的第四个参数,#10645 +- 修复 TypeScript 类型声明未导出 CheckboxButton 的问题,#10666 + +### 2.3.3 + +*2018-04-04* + +- 新增 Card 的 `shadow` 属性,#10418(by @YunYouJun) +- 修复 Badge 在 `value` 属性为 `0` 时不显示上标的问题,#10470 +- 修复 Tree 节点拖拽相关的问题,#10474 #10494 +- 新增 Autocomplete 的 `placement` 属性,#10475 +- 现在 `default-time` 属性也可用于非范围选择的 DateTimePicker 了,#10321(by @RickMacTurk) +- 修复 TabItem 在浏览器失焦和隐藏后出现蓝色边框的问题,#10503 +- 新增 SubMenu 的 `popper-append-to-body` 属性,#10515 +- 现在非链接的 BreadcrumbItem 在 hover 时不再具有视觉反馈,#10551 +- 调整 InputNumber `change` 事件的触发时机,使得在回调中能够取得最新的组件绑定值,#10553 + +### 2.3.2 + +*2018-03-29* + +- 修复 Autocomplete 报错的问题,#10442 + +### 2.3.1 + +*2018-03-29* + +- 修复 Input 的 `type` 属性未传递至原生 input 元素的问题,#10415 +- 新增 Select 的 `blur` 方法,#10416 + +### 2.3.0 Diamond + +*2018-03-28* + +#### 新特性 +- Table + - 现在 TableColumn 的 `formatter` 属性可以是动态的,#10184(by @elfman) + - 新增 `select-on-indeterminate` 属性,#9924(by @syn-zeta) +- Menu + - 新增 `collapse-transition` 属性,#8809(by @limichange) +- Input + - 新增 `select` 方法,#10229 + - 新增 `blur` 方法,#10356 +- ColorPicker + - 新增 `predefine` 属性,#10170(by @elfman) +- Tree + - 新增 `draggable`、`allow-drop` 和 `allow-drag` 属性,以及 `node-drag-start`、`node-drag-enter`、`node-drag-leave`、`node-drag-over`、`node-drag-end` 和 `node-drop` 事件,#9251 #10372(by @elfman) +- Form + - `validate` 方法新增第二个参数,包含未通过本次校验的表单项信息,#10279 + - 新增 `validate` 事件,#10351 +- Progress + - 新增 `color` 属性,#10352(by @YunYouJun) +- Button + - 新增 `circle` 属性,#10359(by @YunYouJun) + +#### 修复 +- Form + - 修复嵌套复合型 Input 时,FormItem 标签与输入框未对齐的问题,#10189 +- Menu + - 现在折叠状态的菜单项仅在传入 `title` slot 时才显示 Tooltip,#10193(by @PanJiaChen) +- Pagination + - 修复 `current-change` 在未发生用户交互时错误触发的问题,#10247 +- DatePicker + - 现在时间日期选择器下拉面板中的值能够正确地从 `format` 属性中获取对应格式了,#10174(by @remizovvv) +- Upload + - 现在拖拽上传会拦截不在 `accept` 属性范围内的文件,#10278 + +### 2.2.2 + +*2018-03-14* + +- 新增 Input 的 `clear` 事件,#9988(by @blackmiaool) +- 现在 ColorPicker 的手动输入支持 `hsl`、`hsv` 和 `rgb` 格式了,#9991 +- 修复 DatePicker 在清除初始值时不触发 `change` 事件的问题,#9986 +- 现在 Rate 的图标类相关属性支持动态更新了,#10003 +- 修复含有固定列的 Table 在设置 `max-height` 属性后有时不能及时更新布局高度的问题,#10034 +- 现在 DatePicker 的范围选择支持先点选结束日期,再点选开始日期了,#8156(by @earlymeme) +- 新增 Pagination 的 `disabled` 属性,#10006 +- 新增 Popover 的 `after-enter` 和 `after-leave` 事件,#10047 +- 修复重置表单后,用户第一次改变 Select 的值时不触发校验的问题,#10105 +- 修复 Table 的固定列在某些情况下宽度不正确的问题,#10130 +- 修复调用 MessageBox 未传入 `title` 时,打开的 MessageBox 会继承上一个实例的 `title` 属性的问题,#10126(by @Pochodaydayup) +- 新增 Slider 的 `input-size` 属性,#10154 +- 新增 Transfer 的 `left-check-change` 和 `right-check-change` 事件,#10156 + +### 2.2.1 + +*2018-03-02* + +- 修复 Aside、Header 和 Footer 在某些布局中被压缩的问题,#9812 +- 修复设置了 `height` 属性的 Table 在服务端渲染时无法加载的问题,#9876 +- 修复可展开的 Table 在展开某一行后高度未重新计算的问题,#9848 +- 修复在 DateTimePicker 中手动输入日期后不能正确触发 `change` 事件的问题,#9913 +- 修复鼠标右键点击 Select 的输入框会展开选项的问题,#9894(by @openks) +- 新增 Slider 的 `tooltip-class` 属性,#9957 +- 现在的 Select 在选中选项后仍然处于 focus 状态,#9857(by @Seebiscuit) +- 新增 Transfer 的 `target-order` 属性,#9960 + +### 2.2.0 Graphite + +*2018-02-12* + +#### 新特性 +- Menu + - SubMenu 新增 `popper-class` 和 `disabled` 属性,#9604 #9771 + - 现在水平模式下的 Menu 支持多级 SubMenu 了,#9741 +- Tree + - 新增 `node-contextmenu` 事件,#9678 + - 现在可以使用 scoped slot 自定义树节点的模板了,#9686 + - 新增 `getNode`、`remove`、`append`、`insertBefore`、`insertAfter`、`getCheckedKeys`、`getHalfCheckedNodes`、`getHalfCheckedKeys` 方法和 `check` 事件,#9718 #9730 +- Transfer + - 新增 `clearQuery` 方法,#9753 +- Select + - 新增 `popper-append-to-body` 属性,#9782 + +#### 修复 +- Table + - 修复点击可展开行的展开图标会触发 `row-click` 事件的问题,#9654 + - 修复某些情况下通过拖动改变列宽后,布局没有同步更新的问题,#9668 + - 修复合计行与固定列并存时的样式问题,#9667 +- Container + - 修复布局组件在 IE11 中无法自动填充可用空间的问题,#9655 +- Loading + - 修复在 `mounted` 中修改 `v-loading` 的值为 true 时不能正确显示 Loading 的问题,#9722 +- Switch + - 修复点击时会触发两次原生 click 事件的问题,#9760 + +### 2.1.0 Charcoal + +*2018-01-31* + +#### 新特性 +- Cascader + - 新增 `focus` 和 `blur` 事件,#9184(by @viewweiwu) +- Table + - `filter-method` 方法加入第三个参数 `column`,#9196(by @liyanlong) +- DatePicker + - 新增 `prefix-icon` 和 `clear-icon` 属性,#9237(by @AdamSGit) + - 新增 `default-time` 属性,#9094(by @nighca) + - `value-format` 属性增加对 `timestamp` 的支持,#9319(by @wacky6) +- InputNumber + - 组件绑定变量的值支持 `undefined`,#9361 +- Select + - 新增 `auto-complete` 属性,#9388 +- Form + - 新增 `disabled` 属性,#9529 + - 新增 `validateOnRuleChange` 属性,#8141 +- Notificaition + - 新增 `closeAll` 方法,#9514 + +#### 修复 +- InputNumber + - 修复初始输入小数点时被重置的问题,#9116 +- Dropdown + - 修复当页面仅有水平滚动条时,某些浏览器下拉菜单定位错误的问题,#9138(by @banzhuanmei) +- Table + - 修复带有固定列的 Table 在列数据变化后固定列的个数计算错误的问题,#9188(by @kolesoffac) + - 修复多级表头最后一列的边框不能正确显示的问题,#9326 + - 修复在 Safari 浏览器中表头错位的问题,#9327 + - 修复带有展开行的表格在展开某一行后,当表格数据更新但 `row-key` 值不变时,该行会自动收起的问题,#9462 + - 修复在一些情况下不必要的多次渲染问题,#9426 + - 修复动态改变 TableColumn 的 `width` 属性时,其宽度计算错误的问题,#9426 +- Loading + - 修复某些情况下 Loading 不能被正确隐藏的问题,#9313 +- DatePicker + - 修复 `focus` 方法在范围选择时无效的问题,#9437 + - 修复当目前时刻处于不可选择的范围内时,点击面板上的「此刻」按钮仍能选中目前时刻的问题,#9470(by @wacky6) + - 修复当在月选择面板中选中天数较少的月份时,日期面板呈现下一个月的问题,#9577(by @wacky6) +- Steps + - 修复在 IE 11 中的样式问题,#9454 + +#### 非兼容性更新 +- Menu + - `collapse` 状态下的弹出菜单现在会插入至 body 元素,修复其位于 Aside 内时弹出菜单不可见的问题,#9263 +- Table + - 勾选多选表格的 checkbox 时不再同时触发 `row-click` 事件,#9467 +- Loading + - 非全屏 Loading 遮罩层的 `z-index` 修改为 2000;全屏 Loading 遮罩层的 `z-index` 值会随页面上的弹出组件动态更新,#9522 +- Dropdown + - `show-timeout` 和 `hide-timeout` 属性现在仅在 trigger 为 `hover` 时生效,#9573 + +### 2.0.11 + +*2018-01-08* + +- 修复 Input 的 `prepend` 或 `append` slot 中 Select 的边框颜色错误,#9089 +- 修复 Select 的 `remove-tag` 事件参数与文档不符的问题,#9090 +- 新增 SubMenu 的 `show-timeout` 和 `hide-timeout` 属性,#8934(by @HugoLew) +- 修复按需引入 Table 时 `show-overflow-tooltip` 的 Tooltip 样式丢失的问题,#9130 +- 修复 Table 在执行 `clearSort` 后点击对应列的排序图标无法正常排序的问题,#9100(by @zEmily) +- 捷克语的 i18n 配置文件由 `cz` 重命名为 `cs-CZ`,#9164 + +### 2.0.10 + +*2017-12-29* + +- 修复了 Table 在固定列和合计行并存时的高度计算错误的问题,#9026 +- 修复了 Table 样式 SCSS 文件错误编译的问题,#9028 +- 现在 DatePicker 的 `change` 事件只会在 `value` 真正改变的时候触发,#9029(by @remizovvv) +- 新增 Input 的 `tabindex` 属性,#9041(by @dicklwm) + +### 2.0.9🎄 + +*2017-12-24* + +- 新增 Upload 的 `before-remove` 钩子方法,#8788(by @firesh) +- 修复 FormItem 的 `error` 属性初始值无效的问题,#8840 +- 通过指令调用的 Loading 现在支持以 `element-loading-custom-class` 属性的方式设置自定义类名,#8826(by @earlymeme) +- 修复 CarouselItem 为异步获取时被隐藏的问题,#8921 +- 新增 Tree 的 `renderAfterExpand` 属性,#8972 + +### 2.0.8 + +*2017-12-12* + +- 新增西班牙语文档 +- 修复 `show-timeout` 对点击触发的 Dropdown 无效的问题,#8734(by @presidenten) +- 修复 Form 对于 `trigger` 为 blur 的校验规则触发时机有误的问题,#8776 +- 修复 DatePicker 在范围选择时 blur 事件触发时机有误的问题,#8784 +- TimePicker 的 `format` 新增对 AM/PM 的支持,#8620(by @firesh) + +### 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* + +- 提升 Cascader、Dropdown、Message、Notification、Popover、Tooltip、Tree 的可访问性 +- 修复当视口变窄时 Container 无法同步更新其宽度的问题,#8042 +- 修复 Tree 的 `updateKeyChildren` 在删除子节点时的行为错误,#8100 +- 修复带有边框的 CheckboxButton 在 Form 中高度错误的问题,#8100 +- 修复 Menu 在解析自定义颜色时的错误,#8153(by @zhouyixiang) + +### 2.0.3 + +*2017-11-03* + +- 修复范围选择的 DatePicker `editable` 和 `readonly` 属性无法正常工作的问题,#7922 +- 修复嵌套的 Tabs 的样式错误,#7941 +- 修复纵向 Steps 中最后一个 Step 的样式错误,#7980 +- 修复 Pagination 的 `current-change` 事件触发时机错误的问题,#7995 +- 修复由于 Menu 使用了未注册的 Tooltip 造成其在按需引入时报错的问题,#7995 + +### 2.0.2 + +*2017-10-31* + +- 在 InputNumber 的加减按钮上单击鼠标右键不再触发值的改变,#7817 +- Form 的 `validate` 方法现在能够正确地在异步校验完成后执行回调了,#7774(by @Allenice) +- 修复 DatePicker 的范围选择在内核为 Chromium 53-57 的浏览器中无法使用的问题,#7838 +- 修复 `list-type` 为 picture-card 的 Upload 预览和删除图标丢失的问题,#7857 +- 新增 TableColumn 的 `sort-by` 属性,#7828(by @wangfengming) +- 修复周模式下的 DatePicker 在选择某年第一周可能会显示为前一年第一周的问题,#7860(by @hh23485) +- 修复垂直模式的 Steps 中图标宽度的样式错误,#7891 +- 增大了 Tree 中展开箭头的点击热区,#7891 + +### 2.0.1 + +*2017-10-28* + +- 修复 RadioButton 和 CheckboxButton 的样式问题,#7793 +- 修复 TimePicker 在某些情况下无法滚动的问题,#7811 +- 修复部分组件在按需引入时样式不完整的问题,#7811 + +### 2.0.0 Carbon + +*2017-10-27* + +#### 新特性 +- 综合 + - 新增 `theme-chalk` 主题 + - 增强以下组件的可访问性:Alert、AutoComplete、Breadcrumb、Button、Checkbox、Collapse、Input、InputNumber、Menu、Progress、Radio、Rate、Slider、Switch 和 Upload + - 新增布局组件 Container、Header、Aside、Main 和 Footer + - 新增 TypeScript 类型声明 + - 重绘了全部图标,并新增了部分图标 + - 新增了一系列基于断点的工具类,用于当视口尺寸满足一定条件时隐藏元素 + - 新增全局配置组件尺寸的功能。在引入 Element 时,配置 `size` 字段可以改变所有组件的默认尺寸 +- Button + - 新增 `round` 属性,用于圆角按钮 #6643 +- TimeSelect + - 可以用 `Up`、`Down` 导航,用 `Enter` 选中时间 #6023 +- TimePicker + - 可以用方向键导航,用 `Enter` 选中时间 #6050 + - 新增 `start-placeholder` 和 `end-placeholder`,用于设置范围选择时两个输入框的占位符 #7169 + - 新增 `arrow-control` 属性,提供另一种交互形式,#7438 +- Tree + - 子节点在首次被展开之前不进行渲染 #6257 + - 新增 `check-descendants` 属性,设置 `lazy` 模式下勾选节点时,是否完全展开整个子树 #6235 +- Tag + - 新增 `size` 属性 #7203 +- Datepicker + - type 为 `datetimerange` 时可以使用 `timeFormat` 格式化时间选择器 #6052 + - 新增 `start-placeholder` 和 `end-placeholder`,用于设置范围选择时两个输入框的占位符 #7169 + - 新增 `value-format` 属性,支持对绑定值的格式进行自定义,#7367 + - 新增 `unlink-panels` 属性,用于在选择日期范围时取消两个日期面板之间的联动 +- MessageBox + - 新增 `closeOnHashChange` 属性 #6043 + - 新增 `center` 属性,提供居中布局 #7029 + - 新增 `roundButton` 属性,使得内部按钮为圆角按钮 #7029 + - 新增 `dangerouslyUseHTMLString` 属性,使得 `message` 支持传入 HTML 字符串* #6043 + - 新增 `inputType` 属性,用户指定内部输入框的类型,#7651 +- Dialog + - 新增 `width`、`fullscreen`、`append-to-body` 属性,支持嵌套使用 + - 新增 `center` 属性,提供居中布局 #7042 + - 新增 `focus-after-closed`、`focus-after-open`属性,支持无障碍访问 #6511 +- ColorPicker + - 增加手动输入色值的支持 #6167 + - 新增 `size` 属性,用于控制组件的大小 #7026 + - 新增 `disabled` 属性,用于禁用组件 #7026 + - 新增 `popper-class` 属性,#7351 +- Message + - 图标部分使用 icon 代替图片,从而支持通过 CSS 修改图标背景色 #6207 + - 新增 `dangerouslyUseHTMLString` 属性,使得 `message` 属性支持传入 HTML 字符串* #6207 + - 新增 `center` 属性,提供居中布局 #6875 +- Notification + - 新增 `position` 属性,用于配置 Notification 出现的位置 #6231 + - 新增 `dangerouslyUseHTMLString` 属性,使得 `message` 属性支持传入 HTML 字符串* #6231 + - 新增 `showClose` 属性,用于隐藏关闭按钮 #6402 +- Rate + - 新增 `show-score` 属性,控制是否在右侧显示当前分数 #6295 +- Tabs + - 新增 `tab-position` 属性,控制选项面板内容显示的上、下、左、右四个方向 #6096 +- Radio + - 增加 `border` 属性和 `size` 属性 #6690 +- Checkbox + - 增加 `border` 属性和 `size` 属性 #6690 +- Alert + - 新增 `center` 属性,提供居中布局 #6876 +- Menu + - 新增 `background-color`、`text-color` 和 `active-text-color` 属性,分别用于设置菜单的背景色、菜单的文字颜色和当前激活菜单的文字颜色 #7064 + - 新增 `open` 和 `close` 方法,支持手动打开和关闭 SubMenu,#7412 +- Form + - 新增 `inline-message` 属性,设置后校验信息会以行内样式显示 #7032 + - 新增 `status-icon` 属性,用于在输入框中显示校验结果反馈图标 #7032 + - Form 和 FormItem 新增 `size` 属性,用于控制表单内组件的尺寸,#7428 + - `validate` 方法在不传入 callback 的情况下返回 promise,#7405 + - 新增 `clearValidate` 方法,用于清空所有表单项的验证信息,#7623 +- Input + - 新增 `suffix`、`prefix` 的 slot,以及 `suffixIcon`、`prefixIcon` 属性,用于给输入框内部增加前置和后置内容 #7032 +- Breadcrumb + - 新增 `separator-class` 属性,可使用图标作为分隔符 #7203 +- Steps + - 新增 `simple` 属性,用于开启简洁风格的步骤条 #7274 +- Pagination + - 新增 `prev-text` 和 `next-text` 属性,用于自定义上一页和下一页的文本 #7005 +- Loading + - 配置对象新增 `spinner` 和 `background` 字段,支持自定义加载图标和背景色,#7390 +- Autocomplete + - 新增 `debounce` 属性,#7413 +- Upload + - 新增 `limit` 和 `on-exceed` 属性,支持对上传文件的个数进行限制,#7405 +- DateTimePicker + - 新增 `time-arrow-control` 属性,用于开启时间选择器的 `arrow-control`,#7438 +- Layout + - 新增断点 `xl`,适用于宽度大于 1920px 的视口 +- Table + - 新增 `span-method` 属性,用于合并行或列 + - 新增 `clearSort` 方法,用于清空排序状态 + - 新增 `clearFilter` 方法,用于清空过滤状态 + - 对于可展开行,当该行展开时会获得一个 `.expanded` 类名,方便自定义样式 + - 新增 `size` 属性,用于控制表格尺寸 + - 新增 `toggleRowExpansion` 方法,用于手动展开或关闭行 + - 新增 `cell-class-name` 属性,用于指定单元格的类名 + - 新增 `cell-style` 属性,用于指定单元格的样式 + - 新增 `header-row-class-name` 属性,用于指定表头行的类名 + - 新增 `header-row-style` 属性,用于指定表头行的样式 + - 新增 `header-cell-class-name` 属性,用于指定表头单元格的类名 + - 新增 `header-cell-style` 属性,用于指定表头单元格的样式 + - TableColumn 的 `prop` 属性支持 `object[key]` 格式 + - TableColumn 新增 `index` 属性,用于自定义索引值 +- Select + - 新增 `reserve-keyword` 属性,用于在选择某个选项后保留当前的搜索关键词 + +#### 修复 +- DatePicker + - 选择周数时,`v-model` 结果返回该周第二天的问题 #6038 + - 在 `daterange` 类型中,第一次的输入会被清空的问题 #6021 +- DateTimePicker + - 和 TimePicker 相互影响的问题 #6090 + - 选择时间小时和秒可超出限制的问题 #6076 +- TimePicker + - 失去焦点时无法正确改变 `v-model` 值的问题 #6023 +- Dialog + - 当含有下拉框时,下拉框的打开和关闭会造成文字虚晃的问题 #6088 +- Select + - 提升性能,修复组件销毁时可能导致 Vue dev-tool 卡死的问题 #6151 +- Table + - 修复 Table 在父元素从 `display: none` 变成其他状态时会隐藏的问题 + - 修复 Table 在父元素为 `display: flex` 时可能出现的宽度逐渐变大的问题 + - 修复 `append` 具名 slot 和固定列并存时,动态获取表格数据会导致固定列消失的问题 + - 修复 `expand-row-keys` 属性初始化无效的问题 + - 修复 `data` 改变时过滤条件失效的问题 + - 修复多级表头时固定列隐藏情况计算错误的问题 + - 修复 `max-height` 变更后无法恢复的问题 + - 修复一些样式上的计算错误 + +#### 非兼容性更新 +- 综合 + - 移除 `theme-default` + - 最低兼容 Vue 2.5.2 和 IE 10 + - 表单组件的 `change` 事件和 Pagination 的 `current-change` 事件现在仅响应用户交互 + - Button 和表单组件的 `size` 属性现在可接受 `medium`、`small` 和 `mini` + - 为了方便使用第三方图标,Button 的 `icon` 属性、Input 的 `prefix-icon` 和 `suffix-icon` 属性、Steps 的 `icon` 属性现在需要传入完整的图标类名 +- Dialog + - 移除 `size` 属性。现在 Dialog 的尺寸由 `width` 和 `fullscreen` 控制 + - 移除通过 `v-model` 控制 Dialog 显示和隐藏的功能 +- Rate + - `text-template` 属性更名为 `score-template` +- Dropdown + - `menu-align` 属性变更为 `placement`,增加更多方位属性 +- Transfer + - `footer-format` 属性更名为 `format` +- Switch + - 由于 `on-*` 属性在 JSX 中会被识别为事件,导致 Switch 所有 `on-*` 属性在 JSX 中无法正常工作,所以 `on-*` 属性更名为 `active-*`,对应地,`off-*` 属性更名为 `inactive-*`。受到影响的属性有:`on-icon-class`、`off-icon-class`、`on-text`、`off-text`、`on-color`、`off-color`、`on-value`、`off-value` + - `active-text` 和 `inactive-text` 属性不再有默认值 +- Tag + - `type` 属性现在支持 `success`、`info`、`warning` 和 `danger` 四个值 +- Menu + - 移除 `theme` 属性。现在通过 `background-color`、`text-color` 和 `active-text-color` 属性进行颜色的自定义 +- Input + - 移除 `icon` 属性。现在通过 `suffix-icon` 属性或者 `suffix` 具名 slot 来加入尾部图标 + - 移除 `on-icon-click` 属性和 `click` 事件。现在如果需要为输入框中的图标添加点击事件,请以具名 slot 的方式添加图标 + - `change` 事件现在仅在输入框失去焦点或用户按下回车时触发,与原生 input 元素一致。如果需要实时响应用户的输入,可以使用 `input` 事件 +- Autocomplete + - 移除 `custom-item` 属性。现在通过 `scoped slot` 自定义输入建议列表项的内容 + - 移除 `props` 属性,现在使用 `value-key` 属性指定输入建议对象中用于显示的键名 +- Steps + - 移除 `center` 属性 + - 现在步骤条将默认充满父容器 +- DatePicker + - `change` 事件参数现在为组件的绑定值,格式由 `value-format` 控制 +- Table + - 移除通过 `inline-template` 自定义列模板的功能 + - `sort-method` 现在和 `Array.sort` 保持一致的逻辑,要求返回一个数字 + - 将 `append` slot 移至 `tbody` 元素以外,以保证其只被渲染一次 + - `expand` 事件更名为 `expand-change`,以保证 API 的命名一致性 + - `row-class-name` 和 `row-style` 的函数参数改为对象,以保证 API 的一致性 + +## +* 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 [XSS 攻击](https://en.wikipedia.org/wiki/Cross-site_scripting)。因此请在 `dangerouslyUseHTMLString` 打开的情况下,确保 `message` 的内容是可信的,**永远不要**将用户提交的内容赋值给 `message` 属性。 diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 0000000..841d7f0 --- /dev/null +++ b/FAQ.md @@ -0,0 +1,217 @@ +## 常见问题 + +
+ 给组件绑定的事件为什么无法触发? + + 在 Vue 2.0 中,为**自定义**组件绑定**原生**事件必须使用 `.native` 修饰符: + ```html + Click Me + ``` + + 从易用性的角度出发,我们对 `Button` 组件进行了处理,使它可以监听 `click` 事件: + ```html + Click Me + ``` + + 但是对于其他组件,还是需要添加 `.native` 修饰符。 +
+ +
+ 如何在 Table 组件的每一行添加操作该行数据的按钮? + + 使用 [Scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots) 即可: + ```html + + + + ``` + 参数 `row` 即为对应行的数据。 +
+ +
+ Tree 组件的 `render-content` 和 Table 组件的 `render-header` 怎么用? + + 请阅读 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)进行配置。 +
+ +
+ 所有组件的任意属性都支持 `.sync` 修饰符吗? + + 不是。对于支持 `.sync` 修饰符的属性,我们会在文档的 API 表格中注明。更多 `.sync` 的用法请查看 [Vue 文档](https://vuejs.org/v2/guide/components.html#sync-Modifier)。 +
+ +
+ 你们的文档怎么偷偷更新了? + + 我们只会在 Element 发布新版本时同步更新文档,以体现最新的变化。详细的更新内容可以查看 [changelog](https://github.com/ElemeFE/element/blob/master/CHANGELOG.zh-CN.md)。 +
+ +
+ 在项目中引入 Element,但是 CSS 报错/字体文件报错/组件没有样式是什么原因? + + 请参考我们提供的 [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) 的项目模板。 +
+ +
+ 将 Element 克隆至本地,运行时为何会报错/跑不起来? + + 首先,确保克隆的是 master 分支的最新代码,并且文件完整。其次,确保本地的 node 版本在 4.0 以上,npm 版本在 3.0 以上。最后,可以启动开发环境: + + ```bash + npm run dev + ``` + + 或是直接打包: + + ```bash + npm run dist + ``` +
+ +## FAQ + +
+ Why are my event listeners not working? + + In Vue 2.0, adding **native** event handlers in **custom** components requires a `.native` modifier: + ```html + Click Me + ``` + + For the sake of usability, we processed `Button` so it can listen to `click` events: + ```html + Click Me + ``` + + For other components, the `.native` modifier is still mandatory. +
+ +
+ How do I add buttons in each row of Table to operate data of that row? + + Just use [Scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots): + ```html + + + + ``` + The parameter `row` is the data object of corresponding row. +
+ +
+ How do `render-content` of Tree and `render-header` of Table work? + + 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. +
+ +
+ Can I use `.sync` modifier on every attribute? + + 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). +
+ +
+ When do you update documentations of Element? + + 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)。 +
+ +
+ I imported Element in my project, but why does it report CSS error/font file error/components have no style? + + 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). +
+ +
+ I cloned Element's repo, but failed to run it. How do I solve it? + + 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 + ``` +
+ +## Preguntas más frecuentes + +
+ ¿Porque mis receptores de eventos no funcionan? + + En Vue 2.0, agregando **nativos** receptores de evento **a medida** componentes requiere el modificador `.native`: + ``` + html + Haga Clic Aquí + ``` + + Para conveniencia, hemos ya procesado eventos para el componente `Button` para que el interfaz sea consistente con `clic` eventos de otros componentes: + + ```html + Haga Clic Aquí + ``` + + Para otros componentes el uso del modificador `.native` sigue siendo obligatorio. +
+ +
+ ¿Como agrego botones en cada linea de una tabla para que operen en los datos de esa linea? + + Simplemente agregue [“Scoped slot”](https://vuejs.org/v2/guide/components.html#Scoped-Slots): + ```html + + + + ``` + El parámetro `row` contiene los datos de la linea correspondiente de la tabla. +
+ +
+ ¿Como funcionan `render-content` de `Tree` y `render-header` de `Table`? + + 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. +
+ +
+ ¿Puedo usar el modificador `.sync` con cada atributo? + + 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). +
+ +
+ ¿Cuando añaden a la documentación de `Element`? + + 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). +
+ +
+ ¿Importé `Element` a mi proyecto pero tengo errores con `CSS` y/o fuentes y mis componentes no tienen ningún estilo? + + 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). +
+ +
+ Hice un clon del repositorio de `Element` pero no arranca. ¿Como lo resuelvo? + + 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 + ``` +
diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cf66100 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016-present ElemeFE + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ccedd52 --- /dev/null +++ b/Makefile @@ -0,0 +1,46 @@ +.PHONY: dist test +default: help + +# build all theme +build-theme: + npm run build:theme + +install: + npm install + +install-cn: + npm install --registry=http://registry.npm.taobao.org + +dev: + npm run dev + +play: + npm run dev:play + +new: + node build/bin/new.js $(filter-out $@,$(MAKECMDGOALS)) + +new-lang: + node build/bin/new-lang.js $(filter-out $@,$(MAKECMDGOALS)) + +dist: install + npm run dist + +deploy: + @npm run deploy + +pub: + npm run pub + +test: + npm run test:watch + +help: + @echo " \033[35mmake\033[0m \033[1m命令使用说明\033[0m" + @echo " \033[35mmake install\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 安装依赖" + @echo " \033[35mmake new [中文名]\033[0m\t--- 创建新组件 package. 例如 'make new button 按钮'" + @echo " \033[35mmake dev\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 开发模式" + @echo " \033[35mmake dist\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 编译项目,生成目标文件" + @echo " \033[35mmake deploy\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 部署 demo" + @echo " \033[35mmake pub\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 发布到 npm 上" + @echo " \033[35mmake new-lang \033[0m\t\033[0m\t\033[0m\t--- 为网站添加新语言. 例如 'make new-lang fr'" diff --git a/README.md b/README.md new file mode 100644 index 0000000..c429865 --- /dev/null +++ b/README.md @@ -0,0 +1,146 @@ +

+ +

+ +

+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +

+ +> A Vue.js 2.0 UI Toolkit for Web. + +Element will stay with Vue 2.x + +For Vue 3.0, we recommend using [Element Plus](https://github.com/element-plus/element-plus) from the same team + +## Links +- Homepage and documentation + - [International users](http://element.eleme.io/#/en-US) + - [Chinese users](http://element-cn.eleme.io/#/zh-CN) + - [Spanish users](http://element.eleme.io/#/es) + - [French users](http://element.eleme.io/#/fr-FR) +- [awesome-element](https://github.com/ElementUI/awesome-element) +- [FAQ](./FAQ.md) +- [Vue.js 3.0 migration](https://github.com/element-plus/element-plus) +- [Customize theme](http://element.eleme.io/#/en-US/component/custom-theme) +- [Preview and generate theme online](https://elementui.github.io/theme-chalk-preview) +- [Element for React](https://github.com/elemefe/element-react) +- [Element for Angular](https://github.com/ElemeFE/element-angular) +- [Atom helper](https://github.com/ElemeFE/element-helper) +- [Visual Studio Code helper](https://github.com/ElemeFE/vscode-element-helper) +- Starter kit + - [element-starter](https://github.com/ElementUI/element-starter) + - [element-in-laravel-starter](https://github.com/ElementUI/element-in-laravel-starter) +- [Design resources](https://github.com/ElementUI/Resources) +- Gitter + - [International users](https://gitter.im/element-en/Lobby) + - [Chinese users](https://gitter.im/ElemeFE/element) + +## Install +```shell +npm install element-ui -S +``` + +## Quick Start +``` javascript +import Vue from 'vue' +import Element from 'element-ui' + +Vue.use(Element) + +// or +import { + Select, + Button + // ... +} from 'element-ui' + +Vue.component(Select.name, Select) +Vue.component(Button.name, Button) +``` +For more information, please refer to [Quick Start](http://element.eleme.io/#/en-US/component/quickstart) in our documentation. + +## Browser Support +Modern browsers and Internet Explorer 10+. + +## Development +Skip this part if you just want to use Element. + +For those who are interested in contributing to Element, please refer to our 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) | [Français](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.fr-FR.md)) to see how to run this project. + +## Changelog +Detailed changes for each release are documented in the [release notes](https://github.com/ElemeFE/element/releases). + +## FAQ +We have collected some [frequently asked questions](https://github.com/ElemeFE/element/blob/master/FAQ.md). Before reporting an issue, please search if the FAQ has the answer to your problem. + +## Contribution +Please make sure to read the 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) | [Français](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.fr-FR.md)) before making a pull request. + +## Special Thanks +English documentation is brought to you by SwiftGG Translation Team: +- [raychenfj](https://github.com/raychenfj) +- [kevin](http://thekevin.cn/) +- [曾小涛](https://github.com/zengxiaotao) +- [湾仔王二](https://github.com/wanzaiwanger) +- [BlooDLine](http://www.ibloodline.com/) +- [陈铭嘉](https://chenmingjia.github.io/) +- [千叶知风](http://mpc6.com/) +- [梁杰](http://numbbbbb.com) +- [Changing](https://github.com/sunzhuo11) +- [mmoaay](https://github.com/mmoaay) + +Spanish documentation is made possible by these community developers: +- [adavie1](https://github.com/adavie1) +- [carmencitaqiu](https://github.com/carmencitaqiu) +- [coderdiaz](https://github.com/coderdiaz) +- [fedegar33](https://github.com/fedegar33) +- [Gonzalo2310](https://github.com/Gonzalo2310) +- [lesterbx](https://github.com/lesterbx) +- [ProgramerGuy](https://github.com/ProgramerGuy) +- [SantiagoGdaR](https://github.com/SantiagoGdaR) +- [sigfriedCub1990](https://github.com/sigfriedCub1990) +- [thechosenjuan](https://github.com/thechosenjuan) + +French documentation is made possible by these community developers: +- [smalesys](https://github.com/smalesys) +- [blombard](https://github.com/blombard) + +## Join Discussion Group + +Scan the QR code using [Dingtalk App](https://www.dingtalk.com/) to join in discussion group : + +Join Discusion Group + + +## LICENSE +[MIT](LICENSE) diff --git a/build/bin/build-entry.js b/build/bin/build-entry.js new file mode 100644 index 0000000..8639eb5 --- /dev/null +++ b/build/bin/build-entry.js @@ -0,0 +1,99 @@ +var Components = require('../../components.json'); +var fs = require('fs'); +var render = require('json-templater/string'); +var uppercamelcase = require('uppercamelcase'); +var path = require('path'); +var endOfLine = require('os').EOL; + +var OUTPUT_PATH = path.join(__dirname, '../../src/index.js'); +var IMPORT_TEMPLATE = 'import {{name}} from \'../packages/{{package}}/index.js\';'; +var INSTALL_COMPONENT_TEMPLATE = ' {{name}}'; +var MAIN_TEMPLATE = `/* Automatically generated by './build/bin/build-entry.js' */ + +{{include}} +import locale from 'element-ui/src/locale'; +import CollapseTransition from 'element-ui/src/transitions/collapse-transition'; + +const components = [ +{{install}}, + CollapseTransition +]; + +const install = function(Vue, opts = {}) { + locale.use(opts.locale); + locale.i18n(opts.i18n); + + components.forEach(component => { + Vue.component(component.name, component); + }); + + Vue.use(InfiniteScroll); + Vue.use(Loading.directive); + + Vue.prototype.$ELEMENT = { + size: opts.size || '', + zIndex: opts.zIndex || 2000 + }; + + Vue.prototype.$loading = Loading.service; + Vue.prototype.$msgbox = MessageBox; + Vue.prototype.$alert = MessageBox.alert; + Vue.prototype.$confirm = MessageBox.confirm; + Vue.prototype.$prompt = MessageBox.prompt; + Vue.prototype.$notify = Notification; + Vue.prototype.$message = Message; + +}; + +/* istanbul ignore if */ +if (typeof window !== 'undefined' && window.Vue) { + install(window.Vue); +} + +export default { + version: '{{version}}', + locale: locale.use, + i18n: locale.i18n, + install, + CollapseTransition, + Loading, +{{list}} +}; +`; + +delete Components.font; + +var ComponentNames = Object.keys(Components); + +var includeComponentTemplate = []; +var installTemplate = []; +var listTemplate = []; + +ComponentNames.forEach(name => { + var componentName = uppercamelcase(name); + + includeComponentTemplate.push(render(IMPORT_TEMPLATE, { + name: componentName, + package: name + })); + + if (['Loading', 'MessageBox', 'Notification', 'Message', 'InfiniteScroll'].indexOf(componentName) === -1) { + installTemplate.push(render(INSTALL_COMPONENT_TEMPLATE, { + name: componentName, + component: name + })); + } + + if (componentName !== 'Loading') listTemplate.push(` ${componentName}`); +}); + +var template = render(MAIN_TEMPLATE, { + include: includeComponentTemplate.join(endOfLine), + install: installTemplate.join(',' + endOfLine), + version: process.env.VERSION || require('../../package.json').version, + list: listTemplate.join(',' + endOfLine) +}); + +fs.writeFileSync(OUTPUT_PATH, template); +console.log('[build entry] DONE:', OUTPUT_PATH); + diff --git a/build/bin/build-locale.js b/build/bin/build-locale.js new file mode 100644 index 0000000..ad66ae3 --- /dev/null +++ b/build/bin/build-locale.js @@ -0,0 +1,39 @@ +var fs = require('fs'); +var save = require('file-save'); +var resolve = require('path').resolve; +var basename = require('path').basename; +var localePath = resolve(__dirname, '../../src/locale/lang'); +var fileList = fs.readdirSync(localePath); + +var transform = function(filename, name, cb) { + require('babel-core').transformFile(resolve(localePath, filename), { + plugins: [ + 'add-module-exports', + ['transform-es2015-modules-umd', {loose: true}] + ], + moduleId: name + }, cb); +}; + +fileList + .filter(function(file) { + return /\.js$/.test(file); + }) + .forEach(function(file) { + var name = basename(file, '.js'); + + transform(file, name, function(err, result) { + if (err) { + console.error(err); + } else { + var code = result.code; + + code = code + .replace('define(\'', 'define(\'element/locale/') + .replace('global.', 'global.ELEMENT.lang = global.ELEMENT.lang || {}; \n global.ELEMENT.lang.'); + save(resolve(__dirname, '../../lib/umd/locale', file)).write(code); + + console.log(file); + } + }); + }); diff --git a/build/bin/gen-cssfile.js b/build/bin/gen-cssfile.js new file mode 100644 index 0000000..d324118 --- /dev/null +++ b/build/bin/gen-cssfile.js @@ -0,0 +1,32 @@ +var fs = require('fs'); +var path = require('path'); +var Components = require('../../components.json'); +var themes = [ + 'theme-chalk' +]; +Components = Object.keys(Components); +var basepath = path.resolve(__dirname, '../../packages/'); + +function fileExists(filePath) { + try { + return fs.statSync(filePath).isFile(); + } catch (err) { + return false; + } +} + +themes.forEach((theme) => { + var isSCSS = theme !== 'theme-default'; + var indexContent = isSCSS ? '@import "./base.scss";\n' : '@import "./base.css";\n'; + Components.forEach(function(key) { + if (['icon', 'option', 'option-group'].indexOf(key) > -1) return; + var fileName = key + (isSCSS ? '.scss' : '.css'); + indexContent += '@import "./' + fileName + '";\n'; + var filePath = path.resolve(basepath, theme, 'src', fileName); + if (!fileExists(filePath)) { + fs.writeFileSync(filePath, '', 'utf8'); + console.log(theme, ' 创建遗漏的 ', fileName, ' 文件'); + } + }); + fs.writeFileSync(path.resolve(basepath, theme, 'src', isSCSS ? 'index.scss' : 'index.css'), indexContent); +}); diff --git a/build/bin/gen-indices.js b/build/bin/gen-indices.js new file mode 100644 index 0000000..ee15913 --- /dev/null +++ b/build/bin/gen-indices.js @@ -0,0 +1,58 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const algoliasearch = require('algoliasearch'); +const slugify = require('transliteration').slugify; +const key = require('./algolia-key'); + +const client = algoliasearch('4C63BTGP6S', key); +const langs = { + 'zh-CN': 'element-zh', + 'en-US': 'element-en', + 'es': 'element-es', + 'fr-FR': 'element-fr' +}; + +['zh-CN', 'en-US', 'es', 'fr-FR'].forEach(lang => { + const indexName = langs[lang]; + const index = client.initIndex(indexName); + index.clearIndex(err => { + if (err) return; + fs.readdir(path.resolve(__dirname, `../../examples/docs/${ lang }`), (err, files) => { + if (err) return; + let indices = []; + files.forEach(file => { + const component = file.replace('.md', ''); + const content = fs.readFileSync(path.resolve(__dirname, `../../examples/docs/${ lang }/${ file }`), 'utf8'); + const matches = content + .replace(/:::[\s\S]*?:::/g, '') + .replace(/```[\s\S]*?```/g, '') + .match(/#{2,4}[^#]*/g) + .map(match => match.replace(/\n+/g, '\n').split('\n').filter(part => !!part)) + .map(match => { + const length = match.length; + if (length > 2) { + const desc = match.slice(1, length).join(''); + return [match[0], desc]; + } + return match; + }); + + indices = indices.concat(matches.map(match => { + const isComponent = match[0].indexOf('###') < 0; + const title = match[0].replace(/#{2,4}/, '').trim(); + const index = { component, title }; + index.ranking = isComponent ? 2 : 1; + index.anchor = slugify(title); + index.content = (match[1] || title).replace(/<[^>]+>/g, ''); + return index; + })); + }); + + index.addObjects(indices, (err, res) => { + console.log(err, res); + }); + }); + }); +}); diff --git a/build/bin/i18n.js b/build/bin/i18n.js new file mode 100644 index 0000000..d758b12 --- /dev/null +++ b/build/bin/i18n.js @@ -0,0 +1,26 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var langConfig = require('../../examples/i18n/page.json'); + +langConfig.forEach(lang => { + try { + fs.statSync(path.resolve(__dirname, `../../examples/pages/${ lang.lang }`)); + } catch (e) { + fs.mkdirSync(path.resolve(__dirname, `../../examples/pages/${ lang.lang }`)); + } + + Object.keys(lang.pages).forEach(page => { + var templatePath = path.resolve(__dirname, `../../examples/pages/template/${ page }.tpl`); + var outputPath = path.resolve(__dirname, `../../examples/pages/${ lang.lang }/${ page }.vue`); + var content = fs.readFileSync(templatePath, 'utf8'); + var pairs = lang.pages[page]; + + Object.keys(pairs).forEach(key => { + content = content.replace(new RegExp(`<%=\\s*${ key }\\s*>`, 'g'), pairs[key]); + }); + + fs.writeFileSync(outputPath, content); + }); +}); diff --git a/build/bin/iconInit.js b/build/bin/iconInit.js new file mode 100644 index 0000000..40691cc --- /dev/null +++ b/build/bin/iconInit.js @@ -0,0 +1,22 @@ +'use strict'; + +var postcss = require('postcss'); +var fs = require('fs'); +var path = require('path'); +var fontFile = fs.readFileSync(path.resolve(__dirname, '../../packages/theme-chalk/src/icon.scss'), 'utf8'); +var nodes = postcss.parse(fontFile).nodes; +var classList = []; + +nodes.forEach((node) => { + var selector = node.selector || ''; + var reg = new RegExp(/\.el-icon-([^:]+):before/); + var arr = selector.match(reg); + + if (arr && arr[1]) { + classList.push(arr[1]); + } +}); + +classList.reverse(); // 希望按 css 文件顺序倒序排列 + +fs.writeFile(path.resolve(__dirname, '../../examples/icon.json'), JSON.stringify(classList), () => {}); diff --git a/build/bin/new-lang.js b/build/bin/new-lang.js new file mode 100644 index 0000000..ca93c29 --- /dev/null +++ b/build/bin/new-lang.js @@ -0,0 +1,60 @@ +'use strict'; + +console.log(); +process.on('exit', () => { + console.log(); +}); + +if (!process.argv[2]) { + console.error('[language] is required!'); + process.exit(1); +} + +var fs = require('fs'); +const path = require('path'); +const fileSave = require('file-save'); +const lang = process.argv[2]; +// const configPath = path.resolve(__dirname, '../../examples/i18n', lang); + +// 添加到 components.json +const componentFile = require('../../examples/i18n/component.json'); +if (componentFile.some(item => item.lang === lang)) { + console.error(`${lang} already exists.`); + process.exit(1); +} +let componentNew = Object.assign({}, componentFile.filter(item => item.lang === 'en-US')[0], { lang }); +componentFile.push(componentNew); +fileSave(path.join(__dirname, '../../examples/i18n/component.json')) + .write(JSON.stringify(componentFile, null, ' '), 'utf8') + .end('\n'); + +// 添加到 page.json +const pageFile = require('../../examples/i18n/page.json'); +let pageNew = Object.assign({}, pageFile.filter(item => item.lang === 'en-US')[0], { lang }); +pageFile.push(pageNew); +fileSave(path.join(__dirname, '../../examples/i18n/page.json')) + .write(JSON.stringify(pageFile, null, ' '), 'utf8') + .end('\n'); + +// 添加到 route.json +const routeFile = require('../../examples/i18n/route.json'); +routeFile.push({ lang }); +fileSave(path.join(__dirname, '../../examples/i18n/route.json')) + .write(JSON.stringify(routeFile, null, ' '), 'utf8') + .end('\n'); + +// 添加到 nav.config.json +const navFile = require('../../examples/nav.config.json'); +navFile[lang] = navFile['en-US']; +fileSave(path.join(__dirname, '../../examples/nav.config.json')) + .write(JSON.stringify(navFile, null, ' '), 'utf8') + .end('\n'); + +// docs 下新建对应文件夹 +try { + fs.statSync(path.resolve(__dirname, `../../examples/docs/${ lang }`)); +} catch (e) { + fs.mkdirSync(path.resolve(__dirname, `../../examples/docs/${ lang }`)); +} + +console.log('DONE!'); diff --git a/build/bin/new.js b/build/bin/new.js new file mode 100644 index 0000000..8f1694a --- /dev/null +++ b/build/bin/new.js @@ -0,0 +1,155 @@ +'use strict'; + +console.log(); +process.on('exit', () => { + console.log(); +}); + +if (!process.argv[2]) { + console.error('[组件名]必填 - Please enter new component name'); + process.exit(1); +} + +const path = require('path'); +const fs = require('fs'); +const fileSave = require('file-save'); +const uppercamelcase = require('uppercamelcase'); +const componentname = process.argv[2]; +const chineseName = process.argv[3] || componentname; +const ComponentName = uppercamelcase(componentname); +const PackagePath = path.resolve(__dirname, '../../packages', componentname); +const Files = [ + { + filename: 'index.js', + content: `import ${ComponentName} from './src/main'; + +/* istanbul ignore next */ +${ComponentName}.install = function(Vue) { + Vue.component(${ComponentName}.name, ${ComponentName}); +}; + +export default ${ComponentName};` + }, + { + filename: 'src/main.vue', + content: ` + +` + }, + { + filename: path.join('../../examples/docs/zh-CN', `${componentname}.md`), + content: `## ${ComponentName} ${chineseName}` + }, + { + filename: path.join('../../examples/docs/en-US', `${componentname}.md`), + content: `## ${ComponentName}` + }, + { + filename: path.join('../../examples/docs/es', `${componentname}.md`), + content: `## ${ComponentName}` + }, + { + filename: path.join('../../examples/docs/fr-FR', `${componentname}.md`), + content: `## ${ComponentName}` + }, + { + filename: path.join('../../test/unit/specs', `${componentname}.spec.js`), + content: `import { createTest, destroyVM } from '../util'; +import ${ComponentName} from 'packages/${componentname}'; + +describe('${ComponentName}', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(${ComponentName}, true); + expect(vm.$el).to.exist; + }); +}); +` + }, + { + filename: path.join('../../packages/theme-chalk/src', `${componentname}.scss`), + content: `@import "mixins/mixins"; +@import "common/var"; + +@include b(${componentname}) { +}` + }, + { + filename: path.join('../../types', `${componentname}.d.ts`), + content: `import { ElementUIComponent } from './component' + +/** ${ComponentName} Component */ +export declare class El${ComponentName} extends ElementUIComponent { +}` + } +]; + +// 添加到 components.json +const componentsFile = require('../../components.json'); +if (componentsFile[componentname]) { + console.error(`${componentname} 已存在.`); + process.exit(1); +} +componentsFile[componentname] = `./packages/${componentname}/index.js`; +fileSave(path.join(__dirname, '../../components.json')) + .write(JSON.stringify(componentsFile, null, ' '), 'utf8') + .end('\n'); + +// 添加到 index.scss +const sassPath = path.join(__dirname, '../../packages/theme-chalk/src/index.scss'); +const sassImportText = `${fs.readFileSync(sassPath)}@import "./${componentname}.scss";`; +fileSave(sassPath) + .write(sassImportText, 'utf8') + .end('\n'); + +// 添加到 element-ui.d.ts +const elementTsPath = path.join(__dirname, '../../types/element-ui.d.ts'); + +let elementTsText = `${fs.readFileSync(elementTsPath)} +/** ${ComponentName} Component */ +export class ${ComponentName} extends El${ComponentName} {}`; + +const index = elementTsText.indexOf('export') - 1; +const importString = `import { El${ComponentName} } from './${componentname}'`; + +elementTsText = elementTsText.slice(0, index) + importString + '\n' + elementTsText.slice(index); + +fileSave(elementTsPath) + .write(elementTsText, 'utf8') + .end('\n'); + +// 创建 package +Files.forEach(file => { + fileSave(path.join(PackagePath, file.filename)) + .write(file.content, 'utf8') + .end('\n'); +}); + +// 添加到 nav.config.json +const navConfigFile = require('../../examples/nav.config.json'); + +Object.keys(navConfigFile).forEach(lang => { + let groups = navConfigFile[lang][4].groups; + groups[groups.length - 1].list.push({ + path: `/${componentname}`, + title: lang === 'zh-CN' && componentname !== chineseName + ? `${ComponentName} ${chineseName}` + : ComponentName + }); +}); + +fileSave(path.join(__dirname, '../../examples/nav.config.json')) + .write(JSON.stringify(navConfigFile, null, ' '), 'utf8') + .end('\n'); + +console.log('DONE!'); diff --git a/build/bin/template.js b/build/bin/template.js new file mode 100644 index 0000000..0cd2fe1 --- /dev/null +++ b/build/bin/template.js @@ -0,0 +1,16 @@ +const path = require('path'); +const templates = path.resolve(process.cwd(), './examples/pages/template'); + +const chokidar = require('chokidar'); +let watcher = chokidar.watch([templates]); + +watcher.on('ready', function() { + watcher + .on('change', function() { + exec('npm run i18n'); + }); +}); + +function exec(cmd) { + return require('child_process').execSync(cmd).toString().trim(); +} diff --git a/build/bin/version.js b/build/bin/version.js new file mode 100644 index 0000000..94584b7 --- /dev/null +++ b/build/bin/version.js @@ -0,0 +1,6 @@ +var fs = require('fs'); +var path = require('path'); +var version = process.env.VERSION || require('../../package.json').version; +var content = { '1.4.13': '1.4', '2.0.11': '2.0', '2.1.0': '2.1', '2.2.2': '2.2', '2.3.9': '2.3', '2.4.11': '2.4', '2.5.4': '2.5', '2.6.3': '2.6', '2.7.2': '2.7', '2.8.2': '2.8', '2.9.2': '2.9', '2.10.1': '2.10', '2.11.1': '2.11', '2.12.0': '2.12', '2.13.2': '2.13', '2.14.1': '2.14' }; +if (!content[version]) content[version] = '2.15'; +fs.writeFileSync(path.resolve(__dirname, '../../examples/versions.json'), JSON.stringify(content)); diff --git a/build/config.js b/build/config.js new file mode 100644 index 0000000..eaaa990 --- /dev/null +++ b/build/config.js @@ -0,0 +1,49 @@ +var path = require('path'); +var fs = require('fs'); +var nodeExternals = require('webpack-node-externals'); +var Components = require('../components.json'); + +var utilsList = fs.readdirSync(path.resolve(__dirname, '../src/utils')); +var mixinsList = fs.readdirSync(path.resolve(__dirname, '../src/mixins')); +var transitionList = fs.readdirSync(path.resolve(__dirname, '../src/transitions')); +var externals = {}; + +Object.keys(Components).forEach(function(key) { + externals[`element-ui/packages/${key}`] = `element-ui/lib/${key}`; +}); + +externals['element-ui/src/locale'] = 'element-ui/lib/locale'; +utilsList.forEach(function(file) { + file = path.basename(file, '.js'); + externals[`element-ui/src/utils/${file}`] = `element-ui/lib/utils/${file}`; +}); +mixinsList.forEach(function(file) { + file = path.basename(file, '.js'); + externals[`element-ui/src/mixins/${file}`] = `element-ui/lib/mixins/${file}`; +}); +transitionList.forEach(function(file) { + file = path.basename(file, '.js'); + externals[`element-ui/src/transitions/${file}`] = `element-ui/lib/transitions/${file}`; +}); + +externals = [Object.assign({ + vue: 'vue' +}, externals), nodeExternals()]; + +exports.externals = externals; + +exports.alias = { + main: path.resolve(__dirname, '../src'), + packages: path.resolve(__dirname, '../packages'), + examples: path.resolve(__dirname, '../examples'), + 'element-ui': path.resolve(__dirname, '../') +}; + +exports.vue = { + root: 'Vue', + commonjs: 'vue', + commonjs2: 'vue', + amd: 'vue' +}; + +exports.jsexclude = /node_modules|utils\/popper\.js|utils\/date\.js/; diff --git a/build/deploy-ci.sh b/build/deploy-ci.sh new file mode 100644 index 0000000..cf76f0d --- /dev/null +++ b/build/deploy-ci.sh @@ -0,0 +1,78 @@ +#! /bin/sh +mkdir temp_web +git config --global user.name "element-bot" +git config --global user.email "wallement@gmail.com" + +if [ "$ROT_TOKEN" = "" ]; then + echo "Bye~" + exit 0 +fi + +# release +if [ "$TRAVIS_TAG" ]; then + # build lib + npm run dist + cd temp_web + git clone https://$ROT_TOKEN@github.com/ElementUI/lib.git && cd lib + rm -rf `find * ! -name README.md` + cp -rf ../../lib/** . + git add -A . + git commit -m "[build] $TRAVIS_TAG" + git tag $TRAVIS_TAG + git push origin master --tags + cd ../.. + + # build theme-chalk + cd temp_web + git clone https://$ROT_TOKEN@github.com/ElementUI/theme-chalk.git && cd theme-chalk + rm -rf * + cp -rf ../../packages/theme-chalk/** . + git add -A . + git commit -m "[build] $TRAVIS_TAG" + git tag $TRAVIS_TAG + git push origin master --tags + cd ../.. + + # build site + npm run deploy:build + cd temp_web + git clone --depth 1 -b gh-pages --single-branch https://$ROT_TOKEN@github.com/ElemeFE/element.git && cd element + # build sub folder + echo $TRAVIS_TAG + + SUB_FOLDER='2.15' + mkdir $SUB_FOLDER + rm -rf *.js *.css *.map static + rm -rf $SUB_FOLDER/** + cp -rf ../../examples/element-ui/** . + cp -rf ../../examples/element-ui/** $SUB_FOLDER/ + git add -A . + git commit -m "$TRAVIS_COMMIT_MSG" + git push origin gh-pages + cd ../.. + + echo "DONE, Bye~" + exit 0 +fi + +# build dev site +npm run build:file && CI_ENV=/dev/$TRAVIS_BRANCH/ node_modules/.bin/cross-env NODE_ENV=production node_modules/.bin/webpack --config build/webpack.demo.js +cd temp_web +git clone https://$ROT_TOKEN@github.com/ElementUI/dev.git && cd dev +mkdir $TRAVIS_BRANCH +rm -rf $TRAVIS_BRANCH/** +cp -rf ../../examples/element-ui/** $TRAVIS_BRANCH/ +git add -A . +git commit -m "$TRAVIS_COMMIT_MSG" +git push origin master +cd ../.. + +# push dev theme-chalk +cd temp_web +git clone -b $TRAVIS_BRANCH https://$ROT_TOKEN@github.com/ElementUI/theme-chalk.git && cd theme-chalk +rm -rf * +cp -rf ../../packages/theme-chalk/** . +git add -A . +git commit -m "$TRAVIS_COMMIT_MSG" +git push origin $TRAVIS_BRANCH +cd ../.. diff --git a/build/deploy-faas.sh b/build/deploy-faas.sh new file mode 100644 index 0000000..699bcf8 --- /dev/null +++ b/build/deploy-faas.sh @@ -0,0 +1,19 @@ +#! /bin/sh +set -ex +mkdir temp_web +npm run deploy:build +cd temp_web +git clone --depth 1 -b gh-pages --single-branch https://github.com/ElemeFE/element.git && cd element + +# build sub folder +SUB_FOLDER='2.15' +mkdir -p $SUB_FOLDER +rm -rf *.js *.css *.map static +rm -rf $SUB_FOLDER/** +cp -rf ../../examples/element-ui/** . +cp -rf ../../examples/element-ui/** $SUB_FOLDER/ +cd ../.. + +# deploy domestic site +faas deploy daily -P element +rm -rf temp_web diff --git a/build/gen-single-config.js b/build/gen-single-config.js new file mode 100644 index 0000000..e30be94 --- /dev/null +++ b/build/gen-single-config.js @@ -0,0 +1,17 @@ +var path = require('path'); +var config = require('./config'); + +module.exports = function(context, moduleName, entry) { + return { + entry: { + index: path.resolve(context, entry || 'index.js') + }, + dist: path.resolve(context, 'lib'), + template: false, + format: 'umd', + moduleName: moduleName, + extends: ['vue2'], + alias: config.alias, + externals: { vue: config.vue } + }; +}; diff --git a/build/git-release.sh b/build/git-release.sh new file mode 100644 index 0000000..2795b7a --- /dev/null +++ b/build/git-release.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env sh +git checkout dev + +if test -n "$(git status --porcelain)"; then + echo 'Unclean working tree. Commit or stash changes first.' >&2; + exit 128; +fi + +if ! git fetch --quiet 2>/dev/null; then + echo 'There was a problem fetching your branch. Run `git fetch` to see more...' >&2; + exit 128; +fi + +if test "0" != "$(git rev-list --count --left-only @'{u}'...HEAD)"; then + echo 'Remote history differ. Please pull changes.' >&2; + exit 128; +fi + +echo 'No conflicts.' >&2; diff --git a/build/md-loader/config.js b/build/md-loader/config.js new file mode 100644 index 0000000..b491c53 --- /dev/null +++ b/build/md-loader/config.js @@ -0,0 +1,26 @@ +const Config = require('markdown-it-chain'); +const anchorPlugin = require('markdown-it-anchor'); +const slugify = require('transliteration').slugify; +const containers = require('./containers'); +const overWriteFenceRule = require('./fence'); + +const config = new Config(); + +config + .options.html(true).end() + + .plugin('anchor').use(anchorPlugin, [ + { + level: 2, + slugify: slugify, + permalink: true, + permalinkBefore: true + } + ]).end() + + .plugin('containers').use(containers).end(); + +const md = config.toMd(); +overWriteFenceRule(md); + +module.exports = md; diff --git a/build/md-loader/containers.js b/build/md-loader/containers.js new file mode 100644 index 0000000..4be9010 --- /dev/null +++ b/build/md-loader/containers.js @@ -0,0 +1,24 @@ +const mdContainer = require('markdown-it-container'); + +module.exports = md => { + md.use(mdContainer, 'demo', { + validate(params) { + return params.trim().match(/^demo\s*(.*)$/); + }, + render(tokens, idx) { + const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/); + if (tokens[idx].nesting === 1) { + const description = m && m.length > 1 ? m[1] : ''; + const content = tokens[idx + 1].type === 'fence' ? tokens[idx + 1].content : ''; + return ` + ${description ? `
${md.render(description)}
` : ''} + + `; + } + return '
'; + } + }); + + md.use(mdContainer, 'tip'); + md.use(mdContainer, 'warning'); +}; diff --git a/build/md-loader/fence.js b/build/md-loader/fence.js new file mode 100644 index 0000000..d328623 --- /dev/null +++ b/build/md-loader/fence.js @@ -0,0 +1,14 @@ +// 覆盖默认的 fence 渲染策略 +module.exports = md => { + const defaultRender = md.renderer.rules.fence; + md.renderer.rules.fence = (tokens, idx, options, env, self) => { + const token = tokens[idx]; + // 判断该 fence 是否在 :::demo 内 + const prevToken = tokens[idx - 1]; + const isInDemoContainer = prevToken && prevToken.nesting === 1 && prevToken.info.trim().match(/^demo\s*(.*)$/); + if (token.info === 'html' && isInDemoContainer) { + return ``; + } + return defaultRender(tokens, idx, options, env, self); + }; +}; diff --git a/build/md-loader/index.js b/build/md-loader/index.js new file mode 100644 index 0000000..2ef0e55 --- /dev/null +++ b/build/md-loader/index.js @@ -0,0 +1,67 @@ +const { + stripScript, + stripTemplate, + genInlineComponentText +} = require('./util'); +const md = require('./config'); + +module.exports = function(source) { + const content = md.render(source); + + const startTag = ''; + const endTagLen = endTag.length; + + let componenetsString = ''; + let id = 0; // demo 的 id + let output = []; // 输出的内容 + let start = 0; // 字符串开始位置 + + let commentStart = content.indexOf(startTag); + let commentEnd = content.indexOf(endTag, commentStart + startTagLen); + while (commentStart !== -1 && commentEnd !== -1) { + output.push(content.slice(start, commentStart)); + + const commentContent = content.slice(commentStart + startTagLen, commentEnd); + const html = stripTemplate(commentContent); + const script = stripScript(commentContent); + let demoComponentContent = genInlineComponentText(html, script); + const demoComponentName = `element-demo${id}`; + output.push(``); + componenetsString += `${JSON.stringify(demoComponentName)}: ${demoComponentContent},`; + + // 重新计算下一次的位置 + id++; + start = commentEnd + endTagLen; + commentStart = content.indexOf(startTag, start); + commentEnd = content.indexOf(endTag, commentStart + startTagLen); + } + + // 仅允许在 demo 不存在时,才可以在 Markdown 中写 script 标签 + // todo: 优化这段逻辑 + let pageScript = ''; + if (componenetsString) { + pageScript = ``; + } else if (content.indexOf('') + ''.length; + pageScript = content.slice(0, start); + } + + output.push(content.slice(start)); + return ` + + ${pageScript} + `; +}; diff --git a/build/md-loader/util.js b/build/md-loader/util.js new file mode 100644 index 0000000..a9572aa --- /dev/null +++ b/build/md-loader/util.js @@ -0,0 +1,79 @@ +const { compileTemplate } = require('@vue/component-compiler-utils'); +const compiler = require('vue-template-compiler'); + +function stripScript(content) { + const result = content.match(/<(script)>([\s\S]+)<\/\1>/); + return result && result[2] ? result[2].trim() : ''; +} + +function stripStyle(content) { + const result = content.match(/<(style)\s*>([\s\S]+)<\/\1>/); + return result && result[2] ? result[2].trim() : ''; +} + +// 编写例子时不一定有 template。所以采取的方案是剔除其他的内容 +function stripTemplate(content) { + content = content.trim(); + if (!content) { + return content; + } + return content.replace(/<(script|style)[\s\S]+<\/\1>/g, '').trim(); +} + +function pad(source) { + return source + .split(/\r?\n/) + .map(line => ` ${line}`) + .join('\n'); +} + +function genInlineComponentText(template, script) { + // https://github.com/vuejs/vue-loader/blob/423b8341ab368c2117931e909e2da9af74503635/lib/loaders/templateLoader.js#L46 + const finalOptions = { + source: `
${template}
`, + filename: 'inline-component', // TODO:这里有待调整 + compiler + }; + const compiled = compileTemplate(finalOptions); + // tips + if (compiled.tips && compiled.tips.length) { + compiled.tips.forEach(tip => { + console.warn(tip); + }); + } + // errors + if (compiled.errors && compiled.errors.length) { + console.error( + `\n Error compiling template:\n${pad(compiled.source)}\n` + + compiled.errors.map(e => ` - ${e}`).join('\n') + + '\n' + ); + } + let demoComponentContent = ` + ${compiled.code} + `; + // todo: 这里采用了硬编码有待改进 + script = script.trim(); + if (script) { + script = script.replace(/export\s+default/, 'const democomponentExport ='); + } else { + script = 'const democomponentExport = {}'; + } + demoComponentContent = `(function() { + ${demoComponentContent} + ${script} + return { + render, + staticRenderFns, + ...democomponentExport + } + })()`; + return demoComponentContent; +} + +module.exports = { + stripScript, + stripStyle, + stripTemplate, + genInlineComponentText +}; diff --git a/build/release.sh b/build/release.sh new file mode 100644 index 0000000..29711a2 --- /dev/null +++ b/build/release.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env sh +set -e + +git checkout master +git merge dev + +VERSION=`npx select-version-cli` + +read -p "Releasing $VERSION - are you sure? (y/n)" -n 1 -r +echo # (optional) move to a new line +if [[ $REPLY =~ ^[Yy]$ ]] +then + echo "Releasing $VERSION ..." + + # build + VERSION=$VERSION npm run dist + + # ssr test + node test/ssr/require.test.js + + # publish theme + echo "Releasing theme-chalk $VERSION ..." + cd packages/theme-chalk + npm version $VERSION --message "[release] $VERSION" + if [[ $VERSION =~ "beta" ]] + then + npm publish --tag beta + else + npm publish + fi + cd ../.. + + # commit + git add -A + git commit -m "[build] $VERSION" + npm version $VERSION --message "[release] $VERSION" + + # publish + git push eleme master + git push eleme refs/tags/v$VERSION + git checkout dev + git rebase master + git push eleme dev + + if [[ $VERSION =~ "beta" ]] + then + npm publish --tag beta + else + npm publish + fi +fi diff --git a/build/webpack.common.js b/build/webpack.common.js new file mode 100644 index 0000000..9cc6556 --- /dev/null +++ b/build/webpack.common.js @@ -0,0 +1,71 @@ +const path = require('path'); +const ProgressBarPlugin = require('progress-bar-webpack-plugin'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); + +const config = require('./config'); + +module.exports = { + mode: 'production', + entry: { + app: ['./src/index.js'] + }, + output: { + path: path.resolve(process.cwd(), './lib'), + publicPath: '/dist/', + filename: 'element-ui.common.js', + chunkFilename: '[id].js', + libraryExport: 'default', + library: 'ELEMENT', + libraryTarget: 'commonjs2' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: config.alias, + modules: ['node_modules'] + }, + externals: config.externals, + performance: { + hints: false + }, + stats: { + children: false + }, + optimization: { + minimize: false + }, + module: { + rules: [ + { + test: /\.(jsx?|babel|es6)$/, + include: process.cwd(), + exclude: config.jsexclude, + loader: 'babel-loader' + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + compilerOptions: { + preserveWhitespace: false + } + } + }, + { + test: /\.css$/, + loaders: ['style-loader', 'css-loader'] + }, + { + test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/, + loader: 'url-loader', + query: { + limit: 10000, + name: path.posix.join('static', '[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new ProgressBarPlugin(), + new VueLoaderPlugin() + ] +}; diff --git a/build/webpack.component.js b/build/webpack.component.js new file mode 100644 index 0000000..2ea8c5a --- /dev/null +++ b/build/webpack.component.js @@ -0,0 +1,68 @@ +const path = require('path'); +const ProgressBarPlugin = require('progress-bar-webpack-plugin'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); + +const Components = require('../components.json'); +const config = require('./config'); + +const webpackConfig = { + mode: 'production', + entry: Components, + output: { + path: path.resolve(process.cwd(), './lib'), + publicPath: '/dist/', + filename: '[name].js', + chunkFilename: '[id].js', + libraryTarget: 'commonjs2' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: config.alias, + modules: ['node_modules'] + }, + externals: config.externals, + performance: { + hints: false + }, + stats: 'none', + optimization: { + minimize: false + }, + module: { + rules: [ + { + test: /\.(jsx?|babel|es6)$/, + include: process.cwd(), + exclude: config.jsexclude, + loader: 'babel-loader' + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + compilerOptions: { + preserveWhitespace: false + } + } + }, + { + test: /\.css$/, + loaders: ['style-loader', 'css-loader'] + }, + { + test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/, + loader: 'url-loader', + query: { + limit: 10000, + name: path.posix.join('static', '[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new ProgressBarPlugin(), + new VueLoaderPlugin() + ] +}; + +module.exports = webpackConfig; diff --git a/build/webpack.conf.js b/build/webpack.conf.js new file mode 100644 index 0000000..72dac87 --- /dev/null +++ b/build/webpack.conf.js @@ -0,0 +1,71 @@ +const path = require('path'); +const ProgressBarPlugin = require('progress-bar-webpack-plugin'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const TerserPlugin = require('terser-webpack-plugin'); + +const config = require('./config'); + +module.exports = { + mode: 'production', + entry: { + app: ['./src/index.js'] + }, + output: { + path: path.resolve(process.cwd(), './lib'), + publicPath: '/dist/', + filename: 'index.js', + chunkFilename: '[id].js', + libraryTarget: 'umd', + libraryExport: 'default', + library: 'ELEMENT', + umdNamedDefine: true, + globalObject: 'typeof self !== \'undefined\' ? self : this' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: config.alias + }, + externals: { + vue: config.vue + }, + optimization: { + minimizer: [ + new TerserPlugin({ + terserOptions: { + output: { + comments: false + } + } + }) + ] + }, + performance: { + hints: false + }, + stats: { + children: false + }, + module: { + rules: [ + { + test: /\.(jsx?|babel|es6)$/, + include: process.cwd(), + exclude: config.jsexclude, + loader: 'babel-loader' + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + compilerOptions: { + preserveWhitespace: false + } + } + } + ] + }, + plugins: [ + new ProgressBarPlugin(), + new VueLoaderPlugin() + ] +}; diff --git a/build/webpack.demo.js b/build/webpack.demo.js new file mode 100644 index 0000000..4ad30ae --- /dev/null +++ b/build/webpack.demo.js @@ -0,0 +1,163 @@ +const path = require('path'); +const webpack = require('webpack'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const ProgressBarPlugin = require('progress-bar-webpack-plugin'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); +const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); + +const config = require('./config'); + +const isProd = process.env.NODE_ENV === 'production'; +const isPlay = !!process.env.PLAY_ENV; + +const webpackConfig = { + mode: process.env.NODE_ENV, + entry: isProd ? { + docs: './examples/entry.js' + } : (isPlay ? './examples/play.js' : './examples/entry.js'), + output: { + path: path.resolve(process.cwd(), './examples/element-ui/'), + publicPath: process.env.CI_ENV || '', + filename: '[name].[hash:7].js', + chunkFilename: isProd ? '[name].[hash:7].js' : '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: config.alias, + modules: ['node_modules'] + }, + devServer: { + host: '0.0.0.0', + port: 8085, + publicPath: '/', + hot: true + }, + performance: { + hints: false + }, + stats: { + children: false + }, + module: { + rules: [ + { + enforce: 'pre', + test: /\.(vue|jsx?)$/, + exclude: /node_modules/, + loader: 'eslint-loader' + }, + { + test: /\.(jsx?|babel|es6)$/, + include: process.cwd(), + exclude: config.jsexclude, + loader: 'babel-loader' + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + compilerOptions: { + preserveWhitespace: false + } + } + }, + { + test: /\.(scss|css)$/, + use: [ + isProd ? MiniCssExtractPlugin.loader : 'style-loader', + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.md$/, + use: [ + { + loader: 'vue-loader', + options: { + compilerOptions: { + preserveWhitespace: false + } + } + }, + { + loader: path.resolve(__dirname, './md-loader/index.js') + } + ] + }, + { + test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/, + loader: 'url-loader', + // todo: 这种写法有待调整 + query: { + limit: 10000, + name: path.posix.join('static', '[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new webpack.HotModuleReplacementPlugin(), + new HtmlWebpackPlugin({ + template: './examples/index.tpl', + filename: './index.html', + favicon: './examples/favicon.ico' + }), + new CopyWebpackPlugin([ + { from: 'examples/versions.json' } + ]), + new ProgressBarPlugin(), + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.FAAS_ENV': JSON.stringify(process.env.FAAS_ENV) + }), + new webpack.LoaderOptionsPlugin({ + vue: { + compilerOptions: { + preserveWhitespace: false + } + } + }) + ], + optimization: { + minimizer: [] + }, + devtool: '#eval-source-map' +}; + +if (isProd) { + webpackConfig.externals = { + vue: 'Vue', + 'vue-router': 'VueRouter', + 'highlight.js': 'hljs' + }; + webpackConfig.plugins.push( + new MiniCssExtractPlugin({ + filename: '[name].[contenthash:7].css' + }) + ); + webpackConfig.optimization.minimizer.push( + new UglifyJsPlugin({ + cache: true, + parallel: true, + sourceMap: false + }), + new OptimizeCSSAssetsPlugin({}) + ); + // https://webpack.js.org/configuration/optimization/#optimizationsplitchunks + webpackConfig.optimization.splitChunks = { + cacheGroups: { + vendor: { + test: /\/src\//, + name: 'element-ui', + chunks: 'all' + } + } + }; + webpackConfig.devtool = false; +} + +module.exports = webpackConfig; diff --git a/build/webpack.extension.js b/build/webpack.extension.js new file mode 100644 index 0000000..2f8752c --- /dev/null +++ b/build/webpack.extension.js @@ -0,0 +1,33 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const demoConfig = require('./webpack.demo'); +const webpack = require('webpack'); +const ProgressBarPlugin = require('progress-bar-webpack-plugin'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); + +demoConfig.entry = { + background: path.join(process.cwd(), './examples/extension/src/background'), + entry: path.join(process.cwd(), './examples/extension/src/entry') +}; +demoConfig.output = { + path: path.join(process.cwd(), './examples/extension/dist'), + filename: '[name].js' +}; +demoConfig.plugins = [ + new CopyWebpackPlugin([ + { from: 'examples/extension/src/manifest.json' }, + { from: 'examples/extension/src/icon.png' } + ]), + new VueLoaderPlugin(), + new ProgressBarPlugin(), + new webpack.LoaderOptionsPlugin({ + vue: { + compilerOptions: { + preserveWhitespace: false + } + } + }), + new webpack.HotModuleReplacementPlugin() +]; +demoConfig.module.rules.find(a => a.loader === 'url-loader').query = {}; +module.exports = demoConfig; diff --git a/build/webpack.test.js b/build/webpack.test.js new file mode 100644 index 0000000..e8f78cb --- /dev/null +++ b/build/webpack.test.js @@ -0,0 +1,67 @@ +const path = require('path'); +const ProgressBarPlugin = require('progress-bar-webpack-plugin'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); + +const config = require('./config'); + +const webpackConfig = { + mode: 'development', + entry: { + app: ['./src/index.js'] + }, + output: { + path: path.resolve(process.cwd(), './dist'), + publicPath: '/dist/', + filename: '[name].js', + chunkFilename: '[id].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: Object.assign(config.alias, { + 'vue$': 'vue/dist/vue.common.js' + }), + modules: ['node_modules'] + }, + module: { + rules: [ + { + test: /\.(jsx?|babel|es6)$/, + include: process.cwd(), + exclude: config.jsexclude, + loader: 'babel-loader' + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + compilerOptions: { + preserveWhitespace: false + } + } + }, + { + test: /\.css$/, + loaders: ['style-loader', 'css-loader'] + }, + { + test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/, + loader: 'url-loader', + query: { + limit: 10000, + name: path.posix.join('static', '[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin() + ] +}; + +if (!process.env.CI_ENV) { + webpackConfig.plugins.push( + new ProgressBarPlugin() + ); +} + +module.exports = webpackConfig; diff --git a/components.json b/components.json new file mode 100644 index 0000000..754da2b --- /dev/null +++ b/components.json @@ -0,0 +1,84 @@ +{ + "pagination": "./packages/pagination/index.js", + "dialog": "./packages/dialog/index.js", + "autocomplete": "./packages/autocomplete/index.js", + "dropdown": "./packages/dropdown/index.js", + "dropdown-menu": "./packages/dropdown-menu/index.js", + "dropdown-item": "./packages/dropdown-item/index.js", + "menu": "./packages/menu/index.js", + "submenu": "./packages/submenu/index.js", + "menu-item": "./packages/menu-item/index.js", + "menu-item-group": "./packages/menu-item-group/index.js", + "input": "./packages/input/index.js", + "input-number": "./packages/input-number/index.js", + "radio": "./packages/radio/index.js", + "radio-group": "./packages/radio-group/index.js", + "radio-button": "./packages/radio-button/index.js", + "checkbox": "./packages/checkbox/index.js", + "checkbox-button": "./packages/checkbox-button/index.js", + "checkbox-group": "./packages/checkbox-group/index.js", + "switch": "./packages/switch/index.js", + "select": "./packages/select/index.js", + "option": "./packages/option/index.js", + "option-group": "./packages/option-group/index.js", + "button": "./packages/button/index.js", + "button-group": "./packages/button-group/index.js", + "table": "./packages/table/index.js", + "table-column": "./packages/table-column/index.js", + "date-picker": "./packages/date-picker/index.js", + "time-select": "./packages/time-select/index.js", + "time-picker": "./packages/time-picker/index.js", + "popover": "./packages/popover/index.js", + "tooltip": "./packages/tooltip/index.js", + "message-box": "./packages/message-box/index.js", + "breadcrumb": "./packages/breadcrumb/index.js", + "breadcrumb-item": "./packages/breadcrumb-item/index.js", + "form": "./packages/form/index.js", + "form-item": "./packages/form-item/index.js", + "tabs": "./packages/tabs/index.js", + "tab-pane": "./packages/tab-pane/index.js", + "tag": "./packages/tag/index.js", + "tree": "./packages/tree/index.js", + "alert": "./packages/alert/index.js", + "notification": "./packages/notification/index.js", + "slider": "./packages/slider/index.js", + "loading": "./packages/loading/index.js", + "icon": "./packages/icon/index.js", + "row": "./packages/row/index.js", + "col": "./packages/col/index.js", + "upload": "./packages/upload/index.js", + "progress": "./packages/progress/index.js", + "spinner": "./packages/spinner/index.js", + "message": "./packages/message/index.js", + "badge": "./packages/badge/index.js", + "card": "./packages/card/index.js", + "rate": "./packages/rate/index.js", + "steps": "./packages/steps/index.js", + "step": "./packages/step/index.js", + "carousel": "./packages/carousel/index.js", + "scrollbar": "./packages/scrollbar/index.js", + "carousel-item": "./packages/carousel-item/index.js", + "collapse": "./packages/collapse/index.js", + "collapse-item": "./packages/collapse-item/index.js", + "cascader": "./packages/cascader/index.js", + "color-picker": "./packages/color-picker/index.js", + "transfer": "./packages/transfer/index.js", + "container": "./packages/container/index.js", + "header": "./packages/header/index.js", + "aside": "./packages/aside/index.js", + "main": "./packages/main/index.js", + "footer": "./packages/footer/index.js", + "timeline": "./packages/timeline/index.js", + "timeline-item": "./packages/timeline-item/index.js", + "link": "./packages/link/index.js", + "divider": "./packages/divider/index.js", + "image": "./packages/image/index.js", + "calendar": "./packages/calendar/index.js", + "backtop": "./packages/backtop/index.js", + "infinite-scroll": "./packages/infinite-scroll/index.js", + "page-header": "./packages/page-header/index.js", + "cascader-panel": "./packages/cascader-panel/index.js", + "avatar": "./packages/avatar/index.js", + "drawer": "./packages/drawer/index.js", + "popconfirm": "./packages/popconfirm/index.js" +} diff --git a/element_logo.svg b/element_logo.svg new file mode 100644 index 0000000..0f58717 --- /dev/null +++ b/element_logo.svg @@ -0,0 +1,13 @@ + + + + Shape + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/app.vue b/examples/app.vue new file mode 100644 index 0000000..90b7168 --- /dev/null +++ b/examples/app.vue @@ -0,0 +1,85 @@ + + + diff --git a/examples/assets/images/Axure-Components.svg b/examples/assets/images/Axure-Components.svg new file mode 100644 index 0000000..74a555b --- /dev/null +++ b/examples/assets/images/Axure-Components.svg @@ -0,0 +1,41 @@ + + + + Axure Components_icon + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/images/Module.svg b/examples/assets/images/Module.svg new file mode 100644 index 0000000..4867658 --- /dev/null +++ b/examples/assets/images/Module.svg @@ -0,0 +1,62 @@ + + + + Module_icon + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/images/Sketch-Template.svg b/examples/assets/images/Sketch-Template.svg new file mode 100644 index 0000000..065b2ad --- /dev/null +++ b/examples/assets/images/Sketch-Template.svg @@ -0,0 +1,37 @@ + + + + Sketch Template_icon + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/images/button-d-cn.png b/examples/assets/images/button-d-cn.png new file mode 100644 index 0000000..a3afa11 Binary files /dev/null and b/examples/assets/images/button-d-cn.png differ diff --git a/examples/assets/images/button-d-en.png b/examples/assets/images/button-d-en.png new file mode 100644 index 0000000..5210474 Binary files /dev/null and b/examples/assets/images/button-d-en.png differ diff --git a/examples/assets/images/button-l-cn.png b/examples/assets/images/button-l-cn.png new file mode 100644 index 0000000..e334448 Binary files /dev/null and b/examples/assets/images/button-l-cn.png differ diff --git a/examples/assets/images/button-l-en.png b/examples/assets/images/button-l-en.png new file mode 100644 index 0000000..d368df9 Binary files /dev/null and b/examples/assets/images/button-l-en.png differ diff --git a/examples/assets/images/cloud-1.png b/examples/assets/images/cloud-1.png new file mode 100644 index 0000000..1f221b5 Binary files /dev/null and b/examples/assets/images/cloud-1.png differ diff --git a/examples/assets/images/cloud-2.png b/examples/assets/images/cloud-2.png new file mode 100644 index 0000000..651f30e Binary files /dev/null and b/examples/assets/images/cloud-2.png differ diff --git a/examples/assets/images/compo-1.png b/examples/assets/images/compo-1.png new file mode 100644 index 0000000..6264c03 Binary files /dev/null and b/examples/assets/images/compo-1.png differ diff --git a/examples/assets/images/compo-2.png b/examples/assets/images/compo-2.png new file mode 100644 index 0000000..202dbde Binary files /dev/null and b/examples/assets/images/compo-2.png differ diff --git a/examples/assets/images/compo-3.png b/examples/assets/images/compo-3.png new file mode 100644 index 0000000..c018f4f Binary files /dev/null and b/examples/assets/images/compo-3.png differ diff --git a/examples/assets/images/component.png b/examples/assets/images/component.png new file mode 100644 index 0000000..ebd1830 Binary files /dev/null and b/examples/assets/images/component.png differ diff --git a/examples/assets/images/consistency.png b/examples/assets/images/consistency.png new file mode 100644 index 0000000..8d26fd6 Binary files /dev/null and b/examples/assets/images/consistency.png differ diff --git a/examples/assets/images/controllability.png b/examples/assets/images/controllability.png new file mode 100644 index 0000000..f9fc9d4 Binary files /dev/null and b/examples/assets/images/controllability.png differ diff --git a/examples/assets/images/dialog-close.png b/examples/assets/images/dialog-close.png new file mode 100644 index 0000000..c810eaf Binary files /dev/null and b/examples/assets/images/dialog-close.png differ diff --git a/examples/assets/images/efficiency.png b/examples/assets/images/efficiency.png new file mode 100644 index 0000000..d0f9130 Binary files /dev/null and b/examples/assets/images/efficiency.png differ diff --git a/examples/assets/images/element-demo.jpeg b/examples/assets/images/element-demo.jpeg new file mode 100644 index 0000000..047e726 Binary files /dev/null and b/examples/assets/images/element-demo.jpeg differ diff --git a/examples/assets/images/element-logo-small.svg b/examples/assets/images/element-logo-small.svg new file mode 100644 index 0000000..9e185f5 --- /dev/null +++ b/examples/assets/images/element-logo-small.svg @@ -0,0 +1,12 @@ + + + + Shape Copy + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/examples/assets/images/element-logo.svg b/examples/assets/images/element-logo.svg new file mode 100644 index 0000000..8cd2c6d --- /dev/null +++ b/examples/assets/images/element-logo.svg @@ -0,0 +1,12 @@ + + + + Shape Copy + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/examples/assets/images/feedback.png b/examples/assets/images/feedback.png new file mode 100644 index 0000000..6f53085 Binary files /dev/null and b/examples/assets/images/feedback.png differ diff --git a/examples/assets/images/figure-1.png b/examples/assets/images/figure-1.png new file mode 100644 index 0000000..7a80415 Binary files /dev/null and b/examples/assets/images/figure-1.png differ diff --git a/examples/assets/images/figure-2.png b/examples/assets/images/figure-2.png new file mode 100644 index 0000000..dc7e482 Binary files /dev/null and b/examples/assets/images/figure-2.png differ diff --git a/examples/assets/images/guide.png b/examples/assets/images/guide.png new file mode 100644 index 0000000..7874829 Binary files /dev/null and b/examples/assets/images/guide.png differ diff --git a/examples/assets/images/hamburger.png b/examples/assets/images/hamburger.png new file mode 100644 index 0000000..b31a246 Binary files /dev/null and b/examples/assets/images/hamburger.png differ diff --git a/examples/assets/images/icon-check.png b/examples/assets/images/icon-check.png new file mode 100644 index 0000000..37663f8 Binary files /dev/null and b/examples/assets/images/icon-check.png differ diff --git a/examples/assets/images/icon-copy.png b/examples/assets/images/icon-copy.png new file mode 100644 index 0000000..3837bf3 Binary files /dev/null and b/examples/assets/images/icon-copy.png differ diff --git a/examples/assets/images/icon-download.png b/examples/assets/images/icon-download.png new file mode 100644 index 0000000..4a81a05 Binary files /dev/null and b/examples/assets/images/icon-download.png differ diff --git a/examples/assets/images/icon-edit.png b/examples/assets/images/icon-edit.png new file mode 100644 index 0000000..050f702 Binary files /dev/null and b/examples/assets/images/icon-edit.png differ diff --git a/examples/assets/images/icon-redo.svg b/examples/assets/images/icon-redo.svg new file mode 100644 index 0000000..2333225 --- /dev/null +++ b/examples/assets/images/icon-redo.svg @@ -0,0 +1,19 @@ + + + + icon-redo + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/images/icon-undo.svg b/examples/assets/images/icon-undo.svg new file mode 100644 index 0000000..a7301f5 --- /dev/null +++ b/examples/assets/images/icon-undo.svg @@ -0,0 +1,19 @@ + + + + icon-undo + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/images/icon-upload.svg b/examples/assets/images/icon-upload.svg new file mode 100644 index 0000000..269ef59 --- /dev/null +++ b/examples/assets/images/icon-upload.svg @@ -0,0 +1,19 @@ + + + + icon_upload + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/images/intro-theme-b.png b/examples/assets/images/intro-theme-b.png new file mode 100644 index 0000000..46a5e22 Binary files /dev/null and b/examples/assets/images/intro-theme-b.png differ diff --git a/examples/assets/images/maximize.svg b/examples/assets/images/maximize.svg new file mode 100644 index 0000000..f4a2e23 --- /dev/null +++ b/examples/assets/images/maximize.svg @@ -0,0 +1 @@ +最大化 \ No newline at end of file diff --git a/examples/assets/images/minimize.svg b/examples/assets/images/minimize.svg new file mode 100644 index 0000000..3f7400a --- /dev/null +++ b/examples/assets/images/minimize.svg @@ -0,0 +1 @@ +最小化 \ No newline at end of file diff --git a/examples/assets/images/navbar_0.png b/examples/assets/images/navbar_0.png new file mode 100644 index 0000000..5fbe864 Binary files /dev/null and b/examples/assets/images/navbar_0.png differ diff --git a/examples/assets/images/navbar_1.png b/examples/assets/images/navbar_1.png new file mode 100644 index 0000000..3137e48 Binary files /dev/null and b/examples/assets/images/navbar_1.png differ diff --git a/examples/assets/images/navbar_2.png b/examples/assets/images/navbar_2.png new file mode 100644 index 0000000..e225afa Binary files /dev/null and b/examples/assets/images/navbar_2.png differ diff --git a/examples/assets/images/navbar_3.png b/examples/assets/images/navbar_3.png new file mode 100644 index 0000000..42007ea Binary files /dev/null and b/examples/assets/images/navbar_3.png differ diff --git a/examples/assets/images/plant-1.png b/examples/assets/images/plant-1.png new file mode 100644 index 0000000..458563a Binary files /dev/null and b/examples/assets/images/plant-1.png differ diff --git a/examples/assets/images/plant-2.png b/examples/assets/images/plant-2.png new file mode 100644 index 0000000..7f58ed6 Binary files /dev/null and b/examples/assets/images/plant-2.png differ diff --git a/examples/assets/images/qrcode.png b/examples/assets/images/qrcode.png new file mode 100644 index 0000000..e921aec Binary files /dev/null and b/examples/assets/images/qrcode.png differ diff --git a/examples/assets/images/resource-placeholder.svg b/examples/assets/images/resource-placeholder.svg new file mode 100644 index 0000000..dd335ee --- /dev/null +++ b/examples/assets/images/resource-placeholder.svg @@ -0,0 +1,23 @@ + + + + 整理中-icon + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/images/resource.png b/examples/assets/images/resource.png new file mode 100644 index 0000000..9975686 Binary files /dev/null and b/examples/assets/images/resource.png differ diff --git a/examples/assets/images/search-by-algolia.svg b/examples/assets/images/search-by-algolia.svg new file mode 100644 index 0000000..989ed6a --- /dev/null +++ b/examples/assets/images/search-by-algolia.svg @@ -0,0 +1 @@ +search-by-algolia \ No newline at end of file diff --git a/examples/assets/images/term-arial.png b/examples/assets/images/term-arial.png new file mode 100644 index 0000000..c5d2210 Binary files /dev/null and b/examples/assets/images/term-arial.png differ diff --git a/examples/assets/images/term-helvetica.png b/examples/assets/images/term-helvetica.png new file mode 100644 index 0000000..f0e8af9 Binary files /dev/null and b/examples/assets/images/term-helvetica.png differ diff --git a/examples/assets/images/term-hiragino.png b/examples/assets/images/term-hiragino.png new file mode 100644 index 0000000..e04fa23 Binary files /dev/null and b/examples/assets/images/term-hiragino.png differ diff --git a/examples/assets/images/term-microsoft.png b/examples/assets/images/term-microsoft.png new file mode 100644 index 0000000..b1c03c0 Binary files /dev/null and b/examples/assets/images/term-microsoft.png differ diff --git a/examples/assets/images/term-pingfang.png b/examples/assets/images/term-pingfang.png new file mode 100644 index 0000000..f56b7c1 Binary files /dev/null and b/examples/assets/images/term-pingfang.png differ diff --git a/examples/assets/images/term-sf.png b/examples/assets/images/term-sf.png new file mode 100644 index 0000000..65a53a7 Binary files /dev/null and b/examples/assets/images/term-sf.png differ diff --git a/examples/assets/images/theme-index-blue.png b/examples/assets/images/theme-index-blue.png new file mode 100644 index 0000000..94d1262 Binary files /dev/null and b/examples/assets/images/theme-index-blue.png differ diff --git a/examples/assets/images/theme-index-icon.svg b/examples/assets/images/theme-index-icon.svg new file mode 100644 index 0000000..e8d95dc --- /dev/null +++ b/examples/assets/images/theme-index-icon.svg @@ -0,0 +1 @@ +资源 104 \ No newline at end of file diff --git a/examples/assets/images/theme-index-red.png b/examples/assets/images/theme-index-red.png new file mode 100644 index 0000000..1a7f0d7 Binary files /dev/null and b/examples/assets/images/theme-index-red.png differ diff --git a/examples/assets/images/theme-intro.png b/examples/assets/images/theme-intro.png new file mode 100644 index 0000000..bb5da7a Binary files /dev/null and b/examples/assets/images/theme-intro.png differ diff --git a/examples/assets/images/typography.png b/examples/assets/images/typography.png new file mode 100644 index 0000000..2063d91 Binary files /dev/null and b/examples/assets/images/typography.png differ diff --git a/examples/assets/images/web.png b/examples/assets/images/web.png new file mode 100644 index 0000000..8f85521 Binary files /dev/null and b/examples/assets/images/web.png differ diff --git a/examples/assets/styles/common.css b/examples/assets/styles/common.css new file mode 100644 index 0000000..9111a58 --- /dev/null +++ b/examples/assets/styles/common.css @@ -0,0 +1,169 @@ +html, body { + margin: 0; + padding: 0; + height: 100%; + font-family: 'Helvetica Neue',Helvetica,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',SimSun,sans-serif; + font-weight: 400; + -webkit-font-smoothing: antialiased; + -webkit-tap-highlight-color: transparent; + + &.is-component { + overflow: hidden; + } +} + +#app { + height: 100%; + + &.is-component { + overflow-y: hidden; + + .main-cnt { + padding: 0; + margin-top: 0; + height: 100%; + min-height: auto; + } + + .headerWrapper { + position: fixed; + width: 100%; + left: 0; + top: 0; + z-index: 1500; + + .container { + padding: 0; + } + } + } +} + +a { + color: #409EFF; + text-decoration: none; +} + +code { + background-color: #f9fafc; + padding: 0 4px; + border: 1px solid #eaeefb; + border-radius: 4px; +} + +button, input, select, textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; + color: inherit; +} + +.hljs { + line-height: 1.8; + font-family: Menlo, Monaco, Consolas, Courier, monospace; + font-size: 12px; + padding: 18px 24px; + background-color: #fafafa; + border: solid 1px #eaeefb; + margin-bottom: 25px; + border-radius: 4px; + -webkit-font-smoothing: auto; +} + +.main-cnt { + margin-top: -80px; + padding: 80px 0 340px; + box-sizing: border-box; + min-height: 100%; +} + +.container, +.page-container { + width: 1140px; + padding: 0; + margin: 0 auto; +} + +.page-container { + padding-top: 55px; + + h2 { + font-size: 28px; + color: #1f2d3d; + margin: 0; + } + h3 { + font-size: 22px; + } + h2, h3, h4, h5 { + font-weight: normal; + color: #1f2f3d; + + &:hover a { + opacity: .4; + } + + a { + float: left; + margin-left: -20px; + opacity: 0; + cursor: pointer; + + &:hover { + opacity: .4; + } + } + } + + p { + font-size: 14px; + color: #5e6d82; + line-height: 1.5em; + } + + .tip { + padding: 8px 16px; + background-color: #ECF8FF; + border-radius: 4px; + border-left: #50bfff 5px solid; + margin: 20px 0; + + code { + background-color: rgba(255, 255, 255, .7); + color: #445368; + } + } + + .warning { + padding: 8px 16px; + background-color: #fff6f7; + border-radius: 4px; + border-left: #FE6C6F 5px solid; + margin: 20px 0; + + code { + background-color: rgba(255, 255, 255, .7); + color: #445368; + } + } +} +.demo { + margin: 20px 0; +} +@media (max-width: 1140px) { + .container, + .page-container { + width: 100%; + } +} + +@media (max-width: 768px) { + .container, + .page-container { + padding: 0 20px; + } + + #app.is-component .headerWrapper .container { + padding: 0 12px; + } +} diff --git a/examples/assets/styles/fonts/icomoon.eot b/examples/assets/styles/fonts/icomoon.eot new file mode 100644 index 0000000..9aed42a Binary files /dev/null and b/examples/assets/styles/fonts/icomoon.eot differ diff --git a/examples/assets/styles/fonts/icomoon.svg b/examples/assets/styles/fonts/icomoon.svg new file mode 100644 index 0000000..ccf388c --- /dev/null +++ b/examples/assets/styles/fonts/icomoon.svg @@ -0,0 +1,14 @@ + + + +Generated by IcoMoon + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/styles/fonts/icomoon.ttf b/examples/assets/styles/fonts/icomoon.ttf new file mode 100644 index 0000000..e17987d Binary files /dev/null and b/examples/assets/styles/fonts/icomoon.ttf differ diff --git a/examples/assets/styles/fonts/icomoon.woff b/examples/assets/styles/fonts/icomoon.woff new file mode 100644 index 0000000..16695e1 Binary files /dev/null and b/examples/assets/styles/fonts/icomoon.woff differ diff --git a/examples/assets/styles/fonts/style.css b/examples/assets/styles/fonts/style.css new file mode 100644 index 0000000..2e1570b --- /dev/null +++ b/examples/assets/styles/fonts/style.css @@ -0,0 +1,39 @@ +@font-face { + font-family: 'icomoon'; + src: url('icomoon.eot?h6xgdm'); + src: url('icomoon.eot?h6xgdm#iefix') format('embedded-opentype'), + url('icomoon.ttf?h6xgdm') format('truetype'), + url('icomoon.woff?h6xgdm') format('woff'), + url('icomoon.svg?h6xgdm#icomoon') format('svg'); + font-weight: normal; + font-style: normal; +} + +[class^="icon-"], [class*=" icon-"] { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'icomoon' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-rate-face-off:before { + content: "\e900"; +} +.icon-rate-face-1:before { + content: "\e901"; +} +.icon-rate-face-2:before { + content: "\e902"; +} +.icon-rate-face-3:before { + content: "\e903"; +} + diff --git a/examples/bus.js b/examples/bus.js new file mode 100644 index 0000000..c17d88a --- /dev/null +++ b/examples/bus.js @@ -0,0 +1,2 @@ +import Vue from 'vue'; +export default new Vue(); diff --git a/examples/color.js b/examples/color.js new file mode 100644 index 0000000..662b233 --- /dev/null +++ b/examples/color.js @@ -0,0 +1,18 @@ +export const tintColor = (c, tint) => { + const color = c.replace('#', ''); + let red = parseInt(color.slice(0, 2), 16); + let green = parseInt(color.slice(2, 4), 16); + let blue = parseInt(color.slice(4, 6), 16); + + if (tint === 0) { // when primary color is in its rgb space + return [red, green, blue].join(','); + } else { + red += Math.round(tint * (255 - red)); + green += Math.round(tint * (255 - green)); + blue += Math.round(tint * (255 - blue)); + red = red.toString(16); + green = green.toString(16); + blue = blue.toString(16); + return `#${ red }${ green }${ blue }`; + } +}; diff --git a/examples/components/demo-block.vue b/examples/components/demo-block.vue new file mode 100644 index 0000000..0a1d2f3 --- /dev/null +++ b/examples/components/demo-block.vue @@ -0,0 +1,337 @@ + + + + + diff --git a/examples/components/footer-nav.vue b/examples/components/footer-nav.vue new file mode 100644 index 0000000..63c5fd9 --- /dev/null +++ b/examples/components/footer-nav.vue @@ -0,0 +1,121 @@ + + + + + \ No newline at end of file diff --git a/examples/components/footer.vue b/examples/components/footer.vue new file mode 100644 index 0000000..d24ca40 --- /dev/null +++ b/examples/components/footer.vue @@ -0,0 +1,188 @@ + + + + + diff --git a/examples/components/header.vue b/examples/components/header.vue new file mode 100644 index 0000000..6a21083 --- /dev/null +++ b/examples/components/header.vue @@ -0,0 +1,524 @@ + + + diff --git a/examples/components/search.vue b/examples/components/search.vue new file mode 100644 index 0000000..9d0f688 --- /dev/null +++ b/examples/components/search.vue @@ -0,0 +1,222 @@ + + + + + diff --git a/examples/components/side-nav.vue b/examples/components/side-nav.vue new file mode 100644 index 0000000..76ffa7a --- /dev/null +++ b/examples/components/side-nav.vue @@ -0,0 +1,274 @@ + + + diff --git a/examples/components/theme-configurator/action.vue b/examples/components/theme-configurator/action.vue new file mode 100644 index 0000000..3dba0fe --- /dev/null +++ b/examples/components/theme-configurator/action.vue @@ -0,0 +1,153 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/borderRadius.vue b/examples/components/theme-configurator/editor/borderRadius.vue new file mode 100644 index 0000000..8ee85f2 --- /dev/null +++ b/examples/components/theme-configurator/editor/borderRadius.vue @@ -0,0 +1,89 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/boxShadow.vue b/examples/components/theme-configurator/editor/boxShadow.vue new file mode 100644 index 0000000..312fc6e --- /dev/null +++ b/examples/components/theme-configurator/editor/boxShadow.vue @@ -0,0 +1,158 @@ + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/color-picker/index.js b/examples/components/theme-configurator/editor/color-picker/index.js new file mode 100644 index 0000000..d79e21e --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/index.js @@ -0,0 +1,8 @@ +import ColorPicker from './src/main'; + +/* istanbul ignore next */ +ColorPicker.install = function(Vue) { + Vue.component(ColorPicker.name, ColorPicker); +}; + +export default ColorPicker; diff --git a/examples/components/theme-configurator/editor/color-picker/src/color.js b/examples/components/theme-configurator/editor/color-picker/src/color.js new file mode 100644 index 0000000..8dee3c8 --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/src/color.js @@ -0,0 +1,316 @@ +const hsv2hsl = function(hue, sat, val) { + return [ + hue, + (sat * val / ((hue = (2 - sat) * val) < 1 ? hue : 2 - hue)) || 0, + hue / 2 + ]; +}; + +// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 +// +const isOnePointZero = function(n) { + return typeof n === 'string' && n.indexOf('.') !== -1 && parseFloat(n) === 1; +}; + +const isPercentage = function(n) { + return typeof n === 'string' && n.indexOf('%') !== -1; +}; + +// Take input from [0, n] and return it as [0, 1] +const bound01 = function(value, max) { + if (isOnePointZero(value)) value = '100%'; + + const processPercent = isPercentage(value); + value = Math.min(max, Math.max(0, parseFloat(value))); + + // Automatically convert percentage into number + if (processPercent) { + value = parseInt(value * max, 10) / 100; + } + + // Handle floating point rounding errors + if ((Math.abs(value - max) < 0.000001)) { + return 1; + } + + // Convert into [0, 1] range if it isn't already + return (value % max) / parseFloat(max); +}; + +const INT_HEX_MAP = { 10: 'A', 11: 'B', 12: 'C', 13: 'D', 14: 'E', 15: 'F' }; + +const toHex = function({ r, g, b }) { + const hexOne = function(value) { + value = Math.min(Math.round(value), 255); + const high = Math.floor(value / 16); + const low = value % 16; + return '' + (INT_HEX_MAP[high] || high) + (INT_HEX_MAP[low] || low); + }; + + if (isNaN(r) || isNaN(g) || isNaN(b)) return ''; + + return '#' + hexOne(r) + hexOne(g) + hexOne(b); +}; + +const HEX_INT_MAP = { A: 10, B: 11, C: 12, D: 13, E: 14, F: 15 }; + +const parseHexChannel = function(hex) { + if (hex.length === 2) { + return (HEX_INT_MAP[hex[0].toUpperCase()] || +hex[0]) * 16 + (HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1]); + } + + return HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1]; +}; + +const hsl2hsv = function(hue, sat, light) { + sat = sat / 100; + light = light / 100; + let smin = sat; + const lmin = Math.max(light, 0.01); + let sv; + let v; + + light *= 2; + sat *= (light <= 1) ? light : 2 - light; + smin *= lmin <= 1 ? lmin : 2 - lmin; + v = (light + sat) / 2; + sv = light === 0 ? (2 * smin) / (lmin + smin) : (2 * sat) / (light + sat); + + return { + h: hue, + s: sv * 100, + v: v * 100 + }; +}; + +// `rgbToHsv` +// Converts an RGB color value to HSV +// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] +// *Returns:* { h, s, v } in [0,1] +const rgb2hsv = function(r, g, b) { + r = bound01(r, 255); + g = bound01(g, 255); + b = bound01(b, 255); + + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + let h, s; + let v = max; + + const d = max - min; + s = max === 0 ? 0 : d / max; + + if (max === min) { + h = 0; // achromatic + } else { + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return { h: h * 360, s: s * 100, v: v * 100 }; +}; + +// `hsvToRgb` +// Converts an HSV color value to RGB. +// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] +// *Returns:* { r, g, b } in the set [0, 255] +const hsv2rgb = function(h, s, v) { + h = bound01(h, 360) * 6; + s = bound01(s, 100); + v = bound01(v, 100); + + const i = Math.floor(h); + const f = h - i; + const p = v * (1 - s); + const q = v * (1 - f * s); + const t = v * (1 - (1 - f) * s); + const mod = i % 6; + const r = [v, q, p, p, t, v][mod]; + const g = [t, v, v, q, p, p][mod]; + const b = [p, p, t, v, v, q][mod]; + + return { + r: Math.round(r * 255), + g: Math.round(g * 255), + b: Math.round(b * 255) + }; +}; + +export default class Color { + constructor(options) { + this._hue = 0; + this._saturation = 100; + this._value = 100; + this._alpha = 100; + + this.enableAlpha = false; + this.format = 'hex'; + this.value = ''; + + options = options || {}; + + for (let option in options) { + if (options.hasOwnProperty(option)) { + this[option] = options[option]; + } + } + + this.doOnChange(); + } + + set(prop, value) { + if (arguments.length === 1 && typeof prop === 'object') { + for (let p in prop) { + if (prop.hasOwnProperty(p)) { + this.set(p, prop[p]); + } + } + + return; + } + + this['_' + prop] = value; + this.doOnChange(); + } + + get(prop) { + return this['_' + prop]; + } + + toRgb() { + return hsv2rgb(this._hue, this._saturation, this._value); + } + + fromString(value) { + if (!value) { + this._hue = 0; + this._saturation = 100; + this._value = 100; + + this.doOnChange(); + return; + } + + const fromHSV = (h, s, v) => { + this._hue = Math.max(0, Math.min(360, h)); + this._saturation = Math.max(0, Math.min(100, s)); + this._value = Math.max(0, Math.min(100, v)); + + this.doOnChange(); + }; + + if (value.indexOf('hsl') !== -1) { + const parts = value.replace(/hsla|hsl|\(|\)/gm, '') + .split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10)); + + if (parts.length === 4) { + this._alpha = Math.floor(parseFloat(parts[3]) * 100); + } else if (parts.length === 3) { + this._alpha = 100; + } + if (parts.length >= 3) { + const { h, s, v } = hsl2hsv(parts[0], parts[1], parts[2]); + fromHSV(h, s, v); + } + } else if (value.indexOf('hsv') !== -1) { + const parts = value.replace(/hsva|hsv|\(|\)/gm, '') + .split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10)); + + if (parts.length === 4) { + this._alpha = Math.floor(parseFloat(parts[3]) * 100); + } else if (parts.length === 3) { + this._alpha = 100; + } + if (parts.length >= 3) { + fromHSV(parts[0], parts[1], parts[2]); + } + } else if (value.indexOf('rgb') !== -1) { + const parts = value.replace(/rgba|rgb|\(|\)/gm, '') + .split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10)); + + if (parts.length === 4) { + this._alpha = Math.floor(parseFloat(parts[3]) * 100); + } else if (parts.length === 3) { + this._alpha = 100; + } + if (parts.length >= 3) { + const { h, s, v } = rgb2hsv(parts[0], parts[1], parts[2]); + fromHSV(h, s, v); + } + } else if (value.indexOf('#') !== -1) { + const hex = value.replace('#', '').trim(); + let r, g, b; + + if (hex.length === 3) { + r = parseHexChannel(hex[0] + hex[0]); + g = parseHexChannel(hex[1] + hex[1]); + b = parseHexChannel(hex[2] + hex[2]); + } else if (hex.length === 6 || hex.length === 8) { + r = parseHexChannel(hex.substring(0, 2)); + g = parseHexChannel(hex.substring(2, 4)); + b = parseHexChannel(hex.substring(4, 6)); + } + + if (hex.length === 8) { + this._alpha = Math.floor(parseHexChannel(hex.substring(6)) / 255 * 100); + } else if (hex.length === 3 || hex.length === 6) { + this._alpha = 100; + } + + const { h, s, v } = rgb2hsv(r, g, b); + fromHSV(h, s, v); + } + } + + compare(color) { + return Math.abs(color._hue - this._hue) < 2 && + Math.abs(color._saturation - this._saturation) < 1 && + Math.abs(color._value - this._value) < 1 && + Math.abs(color._alpha - this._alpha) < 1; + } + + doOnChange() { + const { _hue, _saturation, _value, _alpha, format } = this; + + if (this.enableAlpha) { + switch (format) { + case 'hsl': + const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100); + this.value = `hsla(${ _hue }, ${ Math.round(hsl[1] * 100) }%, ${ Math.round(hsl[2] * 100) }%, ${ _alpha / 100})`; + break; + case 'hsv': + this.value = `hsva(${ _hue }, ${ Math.round(_saturation) }%, ${ Math.round(_value) }%, ${ _alpha / 100})`; + break; + default: + const { r, g, b } = hsv2rgb(_hue, _saturation, _value); + this.value = `rgba(${r}, ${g}, ${b}, ${ _alpha / 100 })`; + } + } else { + switch (format) { + case 'hsl': + const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100); + this.value = `hsl(${ _hue }, ${ Math.round(hsl[1] * 100) }%, ${ Math.round(hsl[2] * 100) }%)`; + break; + case 'hsv': + this.value = `hsv(${ _hue }, ${ Math.round(_saturation) }%, ${ Math.round(_value) }%)`; + break; + case 'rgb': + const { r, g, b } = hsv2rgb(_hue, _saturation, _value); + this.value = `rgb(${r}, ${g}, ${b})`; + break; + default: + this.value = toHex(hsv2rgb(_hue, _saturation, _value)); + } + } + } +}; diff --git a/examples/components/theme-configurator/editor/color-picker/src/components/alpha-slider.vue b/examples/components/theme-configurator/editor/color-picker/src/components/alpha-slider.vue new file mode 100644 index 0000000..efeb87f --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/src/components/alpha-slider.vue @@ -0,0 +1,132 @@ + + + diff --git a/examples/components/theme-configurator/editor/color-picker/src/components/color-list.vue b/examples/components/theme-configurator/editor/color-picker/src/components/color-list.vue new file mode 100644 index 0000000..0230eed --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/src/components/color-list.vue @@ -0,0 +1,111 @@ + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/color-picker/src/components/hue-slider.vue b/examples/components/theme-configurator/editor/color-picker/src/components/hue-slider.vue new file mode 100644 index 0000000..c93e42c --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/src/components/hue-slider.vue @@ -0,0 +1,123 @@ + + + diff --git a/examples/components/theme-configurator/editor/color-picker/src/components/picker-dropdown.vue b/examples/components/theme-configurator/editor/color-picker/src/components/picker-dropdown.vue new file mode 100644 index 0000000..1c16839 --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/src/components/picker-dropdown.vue @@ -0,0 +1,135 @@ + + + diff --git a/examples/components/theme-configurator/editor/color-picker/src/components/predefine.vue b/examples/components/theme-configurator/editor/color-picker/src/components/predefine.vue new file mode 100644 index 0000000..1387c48 --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/src/components/predefine.vue @@ -0,0 +1,61 @@ + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/color-picker/src/components/sv-panel.vue b/examples/components/theme-configurator/editor/color-picker/src/components/sv-panel.vue new file mode 100644 index 0000000..66676a6 --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/src/components/sv-panel.vue @@ -0,0 +1,100 @@ + + + diff --git a/examples/components/theme-configurator/editor/color-picker/src/draggable.js b/examples/components/theme-configurator/editor/color-picker/src/draggable.js new file mode 100644 index 0000000..339a485 --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/src/draggable.js @@ -0,0 +1,36 @@ +import Vue from 'vue'; +let isDragging = false; + +export default function(element, options) { + if (Vue.prototype.$isServer) return; + const moveFn = function(event) { + if (options.drag) { + options.drag(event); + } + }; + const upFn = function(event) { + document.removeEventListener('mousemove', moveFn); + document.removeEventListener('mouseup', upFn); + document.onselectstart = null; + document.ondragstart = null; + + isDragging = false; + + if (options.end) { + options.end(event); + } + }; + element.addEventListener('mousedown', function(event) { + if (isDragging) return; + document.onselectstart = function() { return false; }; + document.ondragstart = function() { return false; }; + + document.addEventListener('mousemove', moveFn); + document.addEventListener('mouseup', upFn); + isDragging = true; + + if (options.start) { + options.start(event); + } + }); +} diff --git a/examples/components/theme-configurator/editor/color-picker/src/main.vue b/examples/components/theme-configurator/editor/color-picker/src/main.vue new file mode 100644 index 0000000..21f9cae --- /dev/null +++ b/examples/components/theme-configurator/editor/color-picker/src/main.vue @@ -0,0 +1,190 @@ + + + diff --git a/examples/components/theme-configurator/editor/color.vue b/examples/components/theme-configurator/editor/color.vue new file mode 100644 index 0000000..90705d6 --- /dev/null +++ b/examples/components/theme-configurator/editor/color.vue @@ -0,0 +1,93 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/fontLineHeight.vue b/examples/components/theme-configurator/editor/fontLineHeight.vue new file mode 100644 index 0000000..ef7455f --- /dev/null +++ b/examples/components/theme-configurator/editor/fontLineHeight.vue @@ -0,0 +1,104 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/fontSize.vue b/examples/components/theme-configurator/editor/fontSize.vue new file mode 100644 index 0000000..f78fd06 --- /dev/null +++ b/examples/components/theme-configurator/editor/fontSize.vue @@ -0,0 +1,105 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/fontWeight.vue b/examples/components/theme-configurator/editor/fontWeight.vue new file mode 100644 index 0000000..9a30581 --- /dev/null +++ b/examples/components/theme-configurator/editor/fontWeight.vue @@ -0,0 +1,109 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/input.vue b/examples/components/theme-configurator/editor/input.vue new file mode 100644 index 0000000..548a1ee --- /dev/null +++ b/examples/components/theme-configurator/editor/input.vue @@ -0,0 +1,45 @@ + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/mixin.vue b/examples/components/theme-configurator/editor/mixin.vue new file mode 100644 index 0000000..f898eef --- /dev/null +++ b/examples/components/theme-configurator/editor/mixin.vue @@ -0,0 +1,81 @@ + + \ No newline at end of file diff --git a/examples/components/theme-configurator/editor/simpleText.vue b/examples/components/theme-configurator/editor/simpleText.vue new file mode 100644 index 0000000..f0628c4 --- /dev/null +++ b/examples/components/theme-configurator/editor/simpleText.vue @@ -0,0 +1,41 @@ + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/index.vue b/examples/components/theme-configurator/index.vue new file mode 100644 index 0000000..6e7483b --- /dev/null +++ b/examples/components/theme-configurator/index.vue @@ -0,0 +1,195 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/main.vue b/examples/components/theme-configurator/main.vue new file mode 100644 index 0000000..5acbc9c --- /dev/null +++ b/examples/components/theme-configurator/main.vue @@ -0,0 +1,130 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme-configurator/shortcut.vue b/examples/components/theme-configurator/shortcut.vue new file mode 100644 index 0000000..7a77098 --- /dev/null +++ b/examples/components/theme-configurator/shortcut.vue @@ -0,0 +1,27 @@ + + \ No newline at end of file diff --git a/examples/components/theme-configurator/utils/boxShadow.js b/examples/components/theme-configurator/utils/boxShadow.js new file mode 100644 index 0000000..382aa4b --- /dev/null +++ b/examples/components/theme-configurator/utils/boxShadow.js @@ -0,0 +1,59 @@ +const VALUES_REG = /,(?![^\(]*\))/; +const PARTS_REG = /\s(?![^(]*\))/; +const LENGTH_REG = /^[0-9]+[a-zA-Z%]+?$/; + +const parseValue = str => { + const parts = str.split(PARTS_REG); + const inset = parts.includes('inset'); + const last = parts.slice(-1)[0]; + const color = !isLength(last) ? last : undefined; + + const nums = parts + .filter(n => n !== 'inset') + .filter(n => n !== color) + .map(toNum); + const [ offsetX, offsetY, blurRadius, spreadRadius ] = nums; + + return { + inset, + offsetX, + offsetY, + blurRadius, + spreadRadius, + color + }; +}; + +const stringifyValue = obj => { + const { + inset, + offsetX = 0, + offsetY = 0, + blurRadius = 0, + spreadRadius, + color + } = obj || {}; + + return [ + (inset ? 'inset' : null), + offsetX, + offsetY, + blurRadius, + spreadRadius, + color + ].filter(v => v !== null && v !== undefined) + .map(toPx) + .map(s => ('' + s).trim()) + .join(' '); +}; + +const isLength = v => v === '0' || LENGTH_REG.test(v); +const toNum = v => { + if (!/px$/.test(v) && v !== '0') return v; + const n = parseFloat(v); + return !isNaN(n) ? n : v; +}; +const toPx = n => typeof n === 'number' && n !== 0 ? (n + 'px') : n; + +export const parse = str => str.split(VALUES_REG).map(s => s.trim()).map(parseValue); +export const stringify = arr => arr.map(stringifyValue).join(', '); diff --git a/examples/components/theme-configurator/utils/utils.js b/examples/components/theme-configurator/utils/utils.js new file mode 100644 index 0000000..1068a8d --- /dev/null +++ b/examples/components/theme-configurator/utils/utils.js @@ -0,0 +1,68 @@ +import deepmerge from 'deepmerge'; +import constant from '../../../i18n/theme-editor.json'; + +export const filterConfigType = (name) => { + switch (name) { + case 'color': + case 'typography': + case 'border': + return 'global'; + default: + return 'local'; + } +}; + +export const filterGlobalValue = (defaultConfig, userConfig) => { + const valueObject = {}; + const globalArr = ['color', 'typography', 'border']; + globalArr.forEach((global) => { + const configObj = {}; + defaultConfig + .find(config => (config.name === global)) + .config.forEach(c => (configObj[c.key] = deepmerge({}, c))); + valueObject[global] = configObj; + Object.keys(configObj).forEach((c) => { + if (userConfig.global[c]) { + configObj[c].value = userConfig.global[c]; + } + }); + }); + return valueObject; +}; + +export const getStyleDisplayValue = (displayValue, global) => { + if (displayValue.startsWith('$')) { + return global[displayValue].value; + } + return displayValue; +}; + +const getLang = () => { + return location.hash.replace('#', '').split('/')[1] || 'zh-CN'; +}; + +const getNameFromI18N = (name) => { + const lang = getLang(); + return constant.filter(config => config.lang === lang)[0][name]; +}; + +export const getVariableDisplayName = (key) => { + return getNameFromI18N('variable-name')[key] || key; +}; + +export const getStyleDisplayName = (config, componentName) => { + const displayNameMap = getNameFromI18N('display-name'); + if (config.name) { + return getVariableDisplayName(config.key.replace('$--', '')); + } + let displayName = config.key.replace(`$--${componentName}-`, ''); + Object.keys(displayNameMap).forEach((name) => { + displayName = displayName.replace(name, displayNameMap[name]); + }); + displayName = displayName.replace(/-/g, ' '); + return displayName.trim(); +}; + +export const getActionDisplayName = (key) => { + return getNameFromI18N('action')[key] || key; +}; diff --git a/examples/components/theme-picker.vue b/examples/components/theme-picker.vue new file mode 100644 index 0000000..fa87a07 --- /dev/null +++ b/examples/components/theme-picker.vue @@ -0,0 +1,157 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme/basic-tokens-preview.vue b/examples/components/theme/basic-tokens-preview.vue new file mode 100644 index 0000000..a2cd90f --- /dev/null +++ b/examples/components/theme/basic-tokens-preview.vue @@ -0,0 +1,280 @@ + + + + diff --git a/examples/components/theme/components-preview.vue b/examples/components/theme/components-preview.vue new file mode 100644 index 0000000..0f5b349 --- /dev/null +++ b/examples/components/theme/components-preview.vue @@ -0,0 +1,539 @@ + + + diff --git a/examples/components/theme/constant.js b/examples/components/theme/constant.js new file mode 100644 index 0000000..6730aa9 --- /dev/null +++ b/examples/components/theme/constant.js @@ -0,0 +1,16 @@ +export const DEFAULT_THEME_CONFIG = { + global: {}, + local: {} +}; + +export const ELEMENT_THEME_USER_CONFIG = 'ELEMENT_THEME_USER_CONFIG'; + +export const ELEMENT_THEME_PREVIEW_CONFIG = 'ELEMENT_THEME_PREVIEW_CONFIG'; + +export const ACTION_DOWNLOAD_THEME = 'ELEMENT_THEME_ACTION_DOWNLOAD'; + +export const ACTION_APPLY_THEME = 'ELEMENT_THEME_ACTION_ALLPY_CSS'; + +export const ACTION_COMPONECT_SELECT = 'ELEMENT_THEME_ACTION_COMPONECT_SELECT'; + +export const ACTION_USER_CONFIG_UPDATE = 'ELEMENT_THEME_USER_CONFIG_UPDATE'; diff --git a/examples/components/theme/loader/ajax.js b/examples/components/theme/loader/ajax.js new file mode 100644 index 0000000..ce248e5 --- /dev/null +++ b/examples/components/theme/loader/ajax.js @@ -0,0 +1,65 @@ +const defaultError = 'Server Error 500'; +const defaultTimeout = 'Request Timeout'; +const xhr = (method, url, data = null, cb) => { + return new window.Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + const doReject = (xhr) => { + reject(xhr.response || xhr.statusText || defaultError); + }; + xhr.open(method, url); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.timeout = 10000; + if (cb) cb(xhr); + xhr.onload = () => { + if (xhr.readyState === 4) { + if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { + let response = xhr.response; + const type = xhr.getResponseHeader('Content-Type'); + if (type.indexOf('zip') > -1) { + let filename = 'style.zip'; + const disposition = xhr.getResponseHeader('content-disposition'); + if (disposition && disposition.indexOf('attachment') !== -1) { + var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; + var matches = filenameRegex.exec(disposition); + if (matches != null && matches[1]) { + filename = matches[1].replace(/['"]/g, ''); + } + } + var blob = new Blob([response], { type }); + var zipUrl = URL.createObjectURL(blob); + var link = document.createElement('a'); + link.href = zipUrl; + link.download = filename; + link.click(); + resolve(response); + return; + } + try { + response = JSON.parse(xhr.response); + } catch (e) {} + resolve(response); + } else { + doReject(xhr); + } + } else { + doReject(xhr); + } + }; + xhr.onerror = () => { + doReject(xhr); + }; + xhr.ontimeout = () => { + xhr.abort(); + reject(defaultTimeout); + }; + xhr.send(JSON.stringify(data)); + }); +}; + +export const post = (url, data, cb) => { + return xhr('POST', url, data, cb); +}; + +export const get = (url) => { + return xhr('GET', url); +}; diff --git a/examples/components/theme/loader/api.js b/examples/components/theme/loader/api.js new file mode 100644 index 0000000..450786d --- /dev/null +++ b/examples/components/theme/loader/api.js @@ -0,0 +1,24 @@ +import Element from 'main/index.js'; +import { post, get } from './ajax'; + +const { version } = Element; + +const hostList = { + local: 'http://localhost:3008/', + alpha: 'https://element-api.ar.elenet.me/element/theme/', + production: 'https://element-api.ele.me/element/theme/' +}; + +const host = hostList[process.env.FAAS_ENV] || hostList.production; + +export const getVars = () => { + return get(`${host}getVariable?version=${version}`); +}; + +export const getTestEle = () => { + return get(`${hostList.alpha}getVariable`); +}; + +export const updateVars = (data, cb) => { + return post(`${host}updateVariable?version=${version}`, data, cb); +}; diff --git a/examples/components/theme/loader/docStyle.vue b/examples/components/theme/loader/docStyle.vue new file mode 100644 index 0000000..b10da44 --- /dev/null +++ b/examples/components/theme/loader/docStyle.vue @@ -0,0 +1,62 @@ + diff --git a/examples/components/theme/loader/index.vue b/examples/components/theme/loader/index.vue new file mode 100644 index 0000000..e078d11 --- /dev/null +++ b/examples/components/theme/loader/index.vue @@ -0,0 +1,106 @@ + \ No newline at end of file diff --git a/examples/components/theme/loader/loading/index.vue b/examples/components/theme/loader/loading/index.vue new file mode 100644 index 0000000..1f597e1 --- /dev/null +++ b/examples/components/theme/loader/loading/index.vue @@ -0,0 +1,35 @@ + + diff --git a/examples/components/theme/loader/loading/progress.js b/examples/components/theme/loader/loading/progress.js new file mode 100644 index 0000000..54ba20d --- /dev/null +++ b/examples/components/theme/loader/loading/progress.js @@ -0,0 +1,6 @@ +import Vue from 'vue'; +import ProgressBar from './progress.vue'; + +Vue.prototype.$bar = new Vue(ProgressBar).$mount(); + +document.body.appendChild(Vue.prototype.$bar.$el); diff --git a/examples/components/theme/loader/loading/progress.vue b/examples/components/theme/loader/loading/progress.vue new file mode 100644 index 0000000..e66d545 --- /dev/null +++ b/examples/components/theme/loader/loading/progress.vue @@ -0,0 +1,108 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme/localstorage.js b/examples/components/theme/localstorage.js new file mode 100644 index 0000000..7d330e6 --- /dev/null +++ b/examples/components/theme/localstorage.js @@ -0,0 +1,38 @@ +import { + ELEMENT_THEME_PREVIEW_CONFIG, + ELEMENT_THEME_USER_CONFIG +} from './constant'; + +export const saveToLocal = (key, value) => { + localStorage.setItem(key, JSON.stringify(value)); +}; + +export const loadFromLocal = (key) => { + try { + return JSON.parse(localStorage.getItem(key)); + } catch (e) { + console.error(e); + return null; + } +}; + +export const savePreviewToLocal = (value) => { + saveToLocal(ELEMENT_THEME_PREVIEW_CONFIG, value); +}; + +export const loadPreviewFromLocal = () => { + return loadFromLocal(ELEMENT_THEME_PREVIEW_CONFIG) || {}; +}; + +export const removePreviewFromLocal = () => { + return localStorage.removeItem(ELEMENT_THEME_PREVIEW_CONFIG); +}; + +export const saveUserThemeToLocal = (value) => { + saveToLocal(ELEMENT_THEME_USER_CONFIG, value); +}; + +export const loadUserThemeFromLocal = () => { + return loadFromLocal(ELEMENT_THEME_USER_CONFIG); +}; + diff --git a/examples/components/theme/theme-card.vue b/examples/components/theme/theme-card.vue new file mode 100644 index 0000000..016961f --- /dev/null +++ b/examples/components/theme/theme-card.vue @@ -0,0 +1,406 @@ + + + + + \ No newline at end of file diff --git a/examples/components/theme/theme-list.js b/examples/components/theme/theme-list.js new file mode 100644 index 0000000..7e5b8d1 --- /dev/null +++ b/examples/components/theme/theme-list.js @@ -0,0 +1,15 @@ +export const themeList = [ + { + name: 'Element', + author: 'Element', + theme: '{"global":{"$--color-primary":"#409EFF"},"local":{}}' + } +]; + +export const eleThemeList = [ + { + name: 'Kiwi', + author: 'Element', + theme: '{"global":{"$--color-primary":"#1989FA","$--color-success":"#5CB87A","$--color-warning":"#E6A23C","$--color-danger":"#F56C6C","$--color-info":"#8896B3","$--font-size-small":"13px","$--font-size-base":"14px","$--font-size-medium":"16px","$--font-size-large":"22px","$--font-size-extra-large":"28px","$--font-line-height-secondary":"20px"},"local":{"$--button-primary-background-color":"$--color-primary","$--switch-font-size":"14px","$--datepicker-active-color":"$--color-primary","$--tooltip-border-color":"$--border-color-base","$--tooltip-color":"#FFFFFF","$--tooltip-padding":"10px","$--collapse-header-font-size":"14px","$--collapse-content-font-size":"14px","$--collapse-content-font-color":"$--color-text-regular","$--radio-input-background-color":"#FFFFFF","$--radio-icon-color":"$--color-warning","$--radio-button-checked-background-color":"$--color-primary","$--input-border-radius":"$--border-radius-base","$--select-input-focus-border-color":"$--color-primary","$--select-font-size":"14px","$--select-option-selected-font-color":"$--color-primary","$--select-input-font-size":"14px","$--select-option-height":"34px","$--slider-main-background-color":"$--color-primary","$--tag-font-color":"$--color-primary","$--tag-default-hover-background-color":"$--color-primary","$--message-warning-font-color":"$--color-warning","$--alert-title-font-size":"14px","$--alert-icon-size":"14px","$--alert-icon-large-size":"22px","$--alert-close-customed-font-size":"12px","$--notification-title-font-size":"16px","$--notification-content-font-size":"14px","$--menu-item-font-color":"$--color-primary"}}' + } +]; diff --git a/examples/components/theme/utils.js b/examples/components/theme/utils.js new file mode 100644 index 0000000..7a6de22 --- /dev/null +++ b/examples/components/theme/utils.js @@ -0,0 +1,24 @@ +export const isEmptyObject = (obj) => (JSON.stringify(obj) === '{}'); + +export const getThemeConfigObject = (config) => { + try { + const conf = JSON.parse(config); + const { global, local } = conf; + if (!isEmptyObject(global) || !isEmptyObject(local)) { + return conf; + } + return false; + } catch (e) { + return false; + } +}; + +export const updateDomHeadStyle = (id, styleContent) => { + let styleTag = document.getElementById(id); + if (!styleTag) { + styleTag = document.createElement('style'); + styleTag.setAttribute('id', id); + document.head.appendChild(styleTag); + } + styleTag.innerText = styleContent.replace(/@font-face{[^}]+}/, ''); +}; diff --git a/examples/demo-styles/alert.scss b/examples/demo-styles/alert.scss new file mode 100644 index 0000000..dae5f06 --- /dev/null +++ b/examples/demo-styles/alert.scss @@ -0,0 +1,7 @@ +.demo-block.demo-alert .el-alert { + margin: 20px 0 0; +} + +.demo-block.demo-alert .el-alert:first-child { + margin: 0; +} diff --git a/examples/demo-styles/avatar.scss b/examples/demo-styles/avatar.scss new file mode 100644 index 0000000..d655db7 --- /dev/null +++ b/examples/demo-styles/avatar.scss @@ -0,0 +1,62 @@ +.demo-avatar { + + &.demo-basic { + text-align: center; + + .demo-basic--circle, .demo-basic--square { + display: flex; + justify-content: space-between; + align-items: center; + .block { + flex: 1; + } + + .block:not(:last-child) { + border-right: 1px solid rgba(224, 230, 237, 0.5); + } + } + + } + + .sub-title { + margin-bottom: 10px; + font-size: 14px; + color: #8492a6; + } + + .el-col:not(:last-child) { + border-right: 1px solid rgba(224,230,237,.5); + } + + .demo-type { + display: flex; + + >div { + flex: 1; + text-align: center; + } + + >div:not(:last-child) { + border-right: 1px solid rgba(224,230,237,.5); + } + } + + .demo-fit { + display: flex; + text-align: center; + justify-content: space-between; + + .block { + flex: 1; + display: flex; + flex-direction: column; + flex-grow: 0; + } + + .title { + margin-bottom: 10px; + font-size: 14px; + color: #8492a6; + } + } +} diff --git a/examples/demo-styles/badge.scss b/examples/demo-styles/badge.scss new file mode 100644 index 0000000..494dacd --- /dev/null +++ b/examples/demo-styles/badge.scss @@ -0,0 +1,19 @@ +.demo-badge.demo-block .el-dropdown { + vertical-align: middle; +} +.demo-badge.demo-block { + .share-button { + width: 36px; + padding: 10px; + } + + .mark { + margin-top: 8px; + line-height: 1; + float: right; + } + + .item { + margin-right: 40px; + } +} diff --git a/examples/demo-styles/border.scss b/examples/demo-styles/border.scss new file mode 100644 index 0000000..57df683 --- /dev/null +++ b/examples/demo-styles/border.scss @@ -0,0 +1,44 @@ +.demo-border .text { + width: 15%; +} +.demo-border .line { + width: 70%; +} +.demo-border .line div { + width: 100%; + height: 0; + border-top: 1px solid #eee; +} +.demo-border .line .dashed { + border-top: 2px dashed #eee; +} +.demo-shadow { + height: 100px; + width: 50%; + border: 1px solid #eee; +} +.demo-shadow-text { + line-height: 50px; + color: #666; + font-size: 14px; +} +.demo-radius .title { + color: #666; + font-size: 18px; + margin: 10px 0; +} +.demo-radius .value { + color: #333; + font-size: 16px; + margin: 10px 0; +} +.demo-radius .radius { + height: 60px; + width: 70%; + border: 1px solid #d7dae2; + border-radius: 0; + margin-top: 20px; +} +.demo-radius .radius-30 { + border-radius: 30px; +} diff --git a/examples/demo-styles/button.scss b/examples/demo-styles/button.scss new file mode 100644 index 0000000..bc8b788 --- /dev/null +++ b/examples/demo-styles/button.scss @@ -0,0 +1,21 @@ +.demo-block.demo-button { + .el-row { + margin-bottom: 20px; + + &:last-child { + margin-bottom: 0; + } + } + .el-button + .el-button { + margin-left: 10px; + } + .el-button-group { + .el-button + .el-button { + margin-left: 0; + } + + & + .el-button-group { + margin-left: 10px; + } + } +} diff --git a/examples/demo-styles/calendar.scss b/examples/demo-styles/calendar.scss new file mode 100644 index 0000000..62198bd --- /dev/null +++ b/examples/demo-styles/calendar.scss @@ -0,0 +1,5 @@ +.demo-calendar.demo-block { + .is-selected { + color: #1989FA; + } +} diff --git a/examples/demo-styles/card.scss b/examples/demo-styles/card.scss new file mode 100644 index 0000000..a558b14 --- /dev/null +++ b/examples/demo-styles/card.scss @@ -0,0 +1,33 @@ +.demo-block.demo-card { + .text { + font-size: 14px; + } + + .time { + font-size: 13px; + color: #999; + } + + .bottom { + margin-top: 13px; + line-height: 12px; + } + + .item { + margin-bottom: 18px; + } + + .button { + padding: 0; + float: right; + } + + .image { + width: 100%; + display: block; + } + + .box-card { + width: 480px; + } +} diff --git a/examples/demo-styles/carousel.scss b/examples/demo-styles/carousel.scss new file mode 100644 index 0000000..dc5295a --- /dev/null +++ b/examples/demo-styles/carousel.scss @@ -0,0 +1,46 @@ +.demo-carousel .block { + padding: 30px; + text-align: center; + border-right: solid 1px #eff2f6; + display: inline-block; + width: 49%; + box-sizing: border-box; + &:last-child { + border-right: none; + } +} + +.demo-carousel .demonstration { + display: block; + color: #8492a6; + font-size: 14px; + margin-bottom: 20px; +} + +.demo-carousel .el-carousel__container { + text-align: center; +} + +.demo-carousel .el-carousel__item { + h3 { + color: #fff; + font-size: 18px; + line-height: 300px; + margin: 0; + &.small { + font-size: 14px; + line-height: 150px; + } + &.medium { + font-size: 14px; + line-height: 200px; + } + } + &:nth-child(2n) { + background-color: #99a9bf; + } + &:nth-child(2n + 1) { + background-color: #d3dce6; + } +} + diff --git a/examples/demo-styles/cascader.scss b/examples/demo-styles/cascader.scss new file mode 100644 index 0000000..765676c --- /dev/null +++ b/examples/demo-styles/cascader.scss @@ -0,0 +1,30 @@ +.demo-cascader { + .el-cascader { + width: 222px; + } +} +.demo-cascader-size { + .el-cascader { + vertical-align: top; + margin-right: 15px; + } +} +.demo-cascader .source > div { + display: flex; +} +.demo-cascader .block { + padding: 30px 0; + text-align: center; + border-right: solid 1px #eff2f6; + width: 50%; + box-sizing: border-box; + &:last-child { + border-right: none; + } +} +.demo-cascader .demonstration { + display: block; + color: #8492a6; + font-size: 14px; + margin-bottom: 20px; +} diff --git a/examples/demo-styles/collapse.scss b/examples/demo-styles/collapse.scss new file mode 100644 index 0000000..11c0d36 --- /dev/null +++ b/examples/demo-styles/collapse.scss @@ -0,0 +1,7 @@ +.demo-collapse { + .el-collapse-item__header { + .header-icon { + margin-left: 5px; + } + } +} diff --git a/examples/demo-styles/color-picker.scss b/examples/demo-styles/color-picker.scss new file mode 100644 index 0000000..621cc8a --- /dev/null +++ b/examples/demo-styles/color-picker.scss @@ -0,0 +1,20 @@ +.demo-color-picker .block { + padding: 30px 0; + text-align: center; + border-right: solid 1px #eff2f6; + display: inline-block; + width: 50%; + box-sizing: border-box; + &:last-child { + border-right: none; + } +} +.demo-color-picker .demonstration { + display: block; + color: #8492a6; + font-size: 14px; + margin-bottom: 20px; +} +.demo-color-picker .el-color-picker + .el-color-picker { + margin-left: 20px; +} diff --git a/examples/demo-styles/color.scss b/examples/demo-styles/color.scss new file mode 100644 index 0000000..c8a1457 --- /dev/null +++ b/examples/demo-styles/color.scss @@ -0,0 +1,72 @@ +.demo-color-box { + position: relative; + border-radius: 4px; + padding: 20px; + margin: 5px 0; + height: 114px; + box-sizing: border-box; + color: #fff; + font-size: 14px; + + & .value { + font-size: 12px; + opacity: 0.69; + line-height: 24px; + } +} +.demo-color-box-other { + height: 74px; + margin: 10px 0 !important; + border-radius: 4px 4px 4px 4px !important; + padding: 15px 20px; +} +.demo-color-box-group { + .demo-color-box { + border-radius: 0; + margin: 0; + } + .demo-color-box:first-child { + border-radius: 4px 4px 0 0; + } + .demo-color-box:last-child { + border-radius: 0 0 4px 4px; + } +} +.bg-color-sub { + width: 100%; + height: 40px; + left: 0; + bottom: 0; + position: absolute; + border-radius: 0 0 4px 4px; +} +.bg-blue-sub-item { + width: 11.1111111%; + height: 100%; + display: inline-block; +} +.bg-blue-sub-item:first-child { + border-radius: 0 0 0 4px; +} +.bg-success-sub-item { + width: 50%; + height: 100%; + display: inline-block; +} +.bg-success-sub-item:first-child { + border-radius: 0 0 0 4px; +} +.bg-success-sub-item:last-child { + border-radius: 0 0 4px 0; +} +.bg-transparent { + border: 1px solid #fcc3c3; + color: #303133; + background: url("data:image/svg+xml;utf8,"); + background-repeat: no-repeat; + background-position: center center; + background-size: 100% 100%, auto; +} +.demo-color-box-lite { + color: #303133; +} diff --git a/examples/demo-styles/container.scss b/examples/demo-styles/container.scss new file mode 100644 index 0000000..f97fc74 --- /dev/null +++ b/examples/demo-styles/container.scss @@ -0,0 +1,43 @@ +.el-header, +.el-footer { + background-color: #b3c0d1; + color: #333; + line-height: 60px; +} + +.el-aside { + color: #333; +} + +#chang-jian-ye-mian-bu-ju + .demo-container { + .el-header, + .el-footer { + text-align: center; + } + + .el-aside { + background-color: #d3dce6; + text-align: center; + line-height: 200px; + } + + .el-main { + background-color: #e9eef3; + color: #333; + text-align: center; + line-height: 160px; + } + + & > .source > .el-container { + margin-bottom: 40px; + + &:nth-child(5) .el-aside, + &:nth-child(6) .el-aside { + line-height: 260px; + } + + &:nth-child(7) .el-aside { + line-height: 320px; + } + } +} diff --git a/examples/demo-styles/date-picker.scss b/examples/demo-styles/date-picker.scss new file mode 100644 index 0000000..96bee1a --- /dev/null +++ b/examples/demo-styles/date-picker.scss @@ -0,0 +1,36 @@ +.demo-block.demo-date-picker .source > div { + padding: 0; + display: flex; + flex-wrap: wrap; +} + +.demo-date-picker .block { + padding: 30px 0; + text-align: center; + border-right: solid 1px #eff2f6; + flex: 1; + &:last-child { + border-right: none; + } +} + +.demo-date-picker .container { + flex: 1; + border-right: solid 1px #eff2f6; + .block { + border-right: none; + &:last-child { + border-top: solid 1px #eff2f6; + } + } + &:last-child { + border-right: none; + } +} + +.demo-date-picker .demonstration { + display: block; + color: #8492a6; + font-size: 14px; + margin-bottom: 20px; +} diff --git a/examples/demo-styles/datetime-picker.scss b/examples/demo-styles/datetime-picker.scss new file mode 100644 index 0000000..bec439b --- /dev/null +++ b/examples/demo-styles/datetime-picker.scss @@ -0,0 +1,21 @@ +.demo-block.demo-datetime-picker .source > div { + padding: 0; + display: flex; +} + +.demo-datetime-picker .block { + padding: 30px 0; + text-align: center; + border-right: solid 1px #eff2f6; + flex: 1; + &:last-child { + border-right: none; + } +} + +.demo-datetime-picker .demonstration { + display: block; + color: #8492a6; + font-size: 14px; + margin-bottom: 20px; +} diff --git a/examples/demo-styles/dialog.scss b/examples/demo-styles/dialog.scss new file mode 100644 index 0000000..ddf1043 --- /dev/null +++ b/examples/demo-styles/dialog.scss @@ -0,0 +1,20 @@ +.demo-block.demo-dialog { + .dialog-footer button:first-child { + margin-right: 10px; + } + .full-image { + width: 100%; + } + .el-dialog__wrapper { + margin: 0; + } + .el-select { + width: 300px; + } + .el-input { + width: 300px; + } + .el-button--text { + margin-right: 15px; + } +} diff --git a/examples/demo-styles/divider.scss b/examples/demo-styles/divider.scss new file mode 100644 index 0000000..a4cd0c0 --- /dev/null +++ b/examples/demo-styles/divider.scss @@ -0,0 +1,9 @@ +.demo-divider-container-1 { + display: inline-block; + width: 33%; +} + +.demo-divider-container-2 { + display: inline-block; + width: 50%; +} \ No newline at end of file diff --git a/examples/demo-styles/drawer.scss b/examples/demo-styles/drawer.scss new file mode 100644 index 0000000..1171361 --- /dev/null +++ b/examples/demo-styles/drawer.scss @@ -0,0 +1,21 @@ +.demo-drawer { + &__content { + display: flex; + flex-direction: column; + height: 100%; + form { + flex: 1; + } + } + + &__footer { + display: flex; + button { + flex: 1; + } + } +} + +.el-drawer__body { + padding: 20px; +} diff --git a/examples/demo-styles/dropdown.scss b/examples/demo-styles/dropdown.scss new file mode 100644 index 0000000..07c20b6 --- /dev/null +++ b/examples/demo-styles/dropdown.scss @@ -0,0 +1,37 @@ +.demo-block { + .el-dropdown { + vertical-align: top; + + & + .el-dropdown { + margin-left: 15px; + } + } + .el-dropdown-link { + cursor: pointer; + color: #409eff; + } + .el-icon-arrow-down { + font-size: 12px; + } +} + +.block-col-2 { + margin: -24px; + + .el-col { + padding: 30px 0; + text-align: center; + border-right: 1px solid #eff2f6; + + &:last-child { + border-right: 0; + } + } +} + +.demo-dropdown .demonstration { + display: block; + color: #8492a6; + font-size: 14px; + margin-bottom: 20px; +} diff --git a/examples/demo-styles/form.scss b/examples/demo-styles/form.scss new file mode 100644 index 0000000..6d04bc8 --- /dev/null +++ b/examples/demo-styles/form.scss @@ -0,0 +1,73 @@ +.demo-form { + .el-select .el-input { + width: 380px; + } + .el-form { + width: 460px; + } + + .line { + text-align: center; + } + + .el-checkbox-group { + width: 320px; + margin: 0; + padding: 0; + list-style: none; + + &:after, + &:before { + content: " "; + display: table; + } + &:after { + clear: both; + visibility: hidden; + font-size: 0; + height: 0; + } + + .el-checkbox { + float: left; + width: 160px; + padding-right: 20px; + margin: 0; + padding: 0; + + + .el-checkbox { + margin-left: 0; + } + } + } + .demo-form-normal { + width: 460px; + } + .demo-form-inline { + width: auto; + + .el-input { + width: 150px; + } + > * { + margin-right: 10px; + } + } + .demo-ruleForm { + width: 460px; + + .el-select .el-input { + width: 360px; + } + } + .demo-dynamic { + .el-input { + margin-right: 10px; + width: 270px; + vertical-align: top; + } + } + .fr { + float: right; + } +} diff --git a/examples/demo-styles/i18n.scss b/examples/demo-styles/i18n.scss new file mode 100644 index 0000000..eabe9ce --- /dev/null +++ b/examples/demo-styles/i18n.scss @@ -0,0 +1,8 @@ +ul.language-list { + color: #5e6d82; + font-size: 14px; + padding-left: 20px; + li { + line-height: 1.8; + } +} diff --git a/examples/demo-styles/icon.scss b/examples/demo-styles/icon.scss new file mode 100644 index 0000000..3f670b4 --- /dev/null +++ b/examples/demo-styles/icon.scss @@ -0,0 +1,69 @@ +.demo-icon .source > div > i { + color: #606266; + margin: 0 20px; + font-size: 1.5em; + vertical-align: middle; +} + +.demo-icon .source button { + margin: 0 20px; +} + +.page-component .content > ul.icon-list { + overflow: hidden; + list-style: none; + padding: 0!important; + border: solid 1px #eaeefb; + border-radius: 4px; +} +.icon-list li { + float: left; + width: 16.66%; + text-align: center; + height: 120px; + line-height: 120px; + color: #666; + font-size: 13px; + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; + margin-right: -1px; + margin-bottom: -1px; + + &::after { + display: inline-block; + content: ""; + height: 100%; + vertical-align: middle; + } + + span { + display: inline-block; + line-height: normal; + vertical-align: middle; + font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", + "Microsoft YaHei", SimSun, sans-serif; + color: #99a9bf; + transition: color 0.15s linear; + } + + i { + display: block; + font-size: 32px; + margin-bottom: 15px; + color: #606266; + transition: color 0.15s linear; + } + + .icon-name { + display: inline-block; + padding: 0 3px; + height: 1em; + } + + &:hover { + span, + i { + color: rgb(92, 182, 255); + } + } +} diff --git a/examples/demo-styles/image.scss b/examples/demo-styles/image.scss new file mode 100644 index 0000000..9bf4996 --- /dev/null +++ b/examples/demo-styles/image.scss @@ -0,0 +1,78 @@ +@keyframes dot { + 0% { width: 0; margin-right: 1em; } + 100% { width: 1em; margin-right: 0; } +} + +.demo-image { + .block { + padding: 30px 0; + text-align: center; + border-right: solid 1px #eff2f6; + display: inline-block; + width: 20%; + box-sizing: border-box; + vertical-align: top; + &:last-child { + border-right: none; + } + } + + .demonstration { + display: block; + color: #8492a6; + font-size: 14px; + margin-bottom: 20px; + } +} + +.demo-image__placeholder, .demo-image__error { + @extend .demo-image; + + .block { + width: 49%; + } + + .el-image { + width: 300px; + height: 200px; + } + + .image-slot { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + background: #f5f7fa; + color: #909399; + font-size: 14px; + } +} + +.demo-image__placeholder { + .dot { + animation: dot 2s infinite steps(3, start); + overflow: hidden; + } +} + +.demo-image__error { + .image-slot { + font-size: 30px; + } +} + +.demo-image__lazy { + height: 400px; + overflow-y: auto; + + .el-image { + display: block; + min-height: 200px; + margin-bottom: 10px; + + &:last-child { + margin-bottom: 0; + } + } +} diff --git a/examples/demo-styles/index.scss b/examples/demo-styles/index.scss new file mode 100644 index 0000000..2186b96 --- /dev/null +++ b/examples/demo-styles/index.scss @@ -0,0 +1,47 @@ +@import "./alert.scss"; +@import "./badge.scss"; +@import "./border.scss"; +@import "./button.scss"; +@import "./calendar.scss"; +@import "./card.scss"; +@import "./carousel.scss"; +@import "./cascader.scss"; +@import "./collapse.scss"; +@import "./color-picker.scss"; +@import "./color.scss"; +@import "./container.scss"; +@import "./date-picker.scss"; +@import "./datetime-picker.scss"; +@import "./dialog.scss"; +@import "./dropdown.scss"; +@import "./form.scss"; +@import "./i18n.scss"; +@import "./icon.scss"; +@import "./input-number.scss"; +@import "./input.scss"; +@import "./layout.scss"; +@import "./loading.scss"; +@import "./menu.scss"; +@import "./pagination.scss"; +@import "./popover.scss"; +@import "./progress.scss"; +@import "./rate.scss"; +@import "./select.scss"; +@import "./slider.scss"; +@import "./switch.scss"; +@import "./table.scss"; +@import "./tag.scss"; +@import "./time-picker.scss"; +@import "./timeline.scss"; +@import "./tooltip.scss"; +@import "./transition.scss"; +@import "./transfer.scss"; +@import "./tree.scss"; +@import "./typography.scss"; +@import "./upload.scss"; +@import "./divider.scss"; +@import "./image.scss"; +@import "./infinite-scroll.scss"; +@import "./avatar.scss"; +@import "./drawer.scss"; + diff --git a/examples/demo-styles/infinite-scroll.scss b/examples/demo-styles/infinite-scroll.scss new file mode 100644 index 0000000..a63f9eb --- /dev/null +++ b/examples/demo-styles/infinite-scroll.scss @@ -0,0 +1,46 @@ +.infinite-list { + height: 300px; + padding: 0; + margin: 0; + list-style: none; + + .infinite-list-item { + display: flex; + align-items: center; + justify-content: center; + height: 50px; + background: #e8f3fe; + margin: 10px; + color: lighten(#1989fa, 20%); + & + .list-item { + margin-top: 10px + } + } +} + +.infinite-list-wrapper { + height: 300px; + text-align: center; + + .list{ + padding: 0; + margin: 0; + list-style: none; + } + + + .list-item{ + display: flex; + align-items: center; + justify-content: center; + height: 50px; + background: #fff6f6; + color: #ff8484; + & + .list-item { + margin-top: 10px + } + } +} + + + diff --git a/examples/demo-styles/input-number.scss b/examples/demo-styles/input-number.scss new file mode 100644 index 0000000..b85cff7 --- /dev/null +++ b/examples/demo-styles/input-number.scss @@ -0,0 +1,5 @@ +.demo-block.demo-input-number { + .el-input-number + .el-input-number { + margin-left: 10px; + } +} diff --git a/examples/demo-styles/input.scss b/examples/demo-styles/input.scss new file mode 100644 index 0000000..88b51b9 --- /dev/null +++ b/examples/demo-styles/input.scss @@ -0,0 +1,65 @@ +.demo-input { + .el-select .el-input { + width: 130px; + } + .el-input { + width: 180px; + } + .el-textarea { + width: 414px; + } + .el-input-group { + width: 100%; + } + .demo-input-size { + .el-input { + vertical-align: top; + margin: 0 10px 10px 0; + } + } + .input-with-select .el-input-group__prepend { + background-color: #fff; + } + .demo-autocomplete { + text-align: center; + + .sub-title { + margin-bottom: 10px; + font-size: 14px; + color: #8492a6; + } + + .el-col:not(:last-child) { + border-right: 1px solid rgba(224, 230, 237, 0.5); + } + + .el-autocomplete { + text-align: left; + } + } +} +.el-autocomplete-suggestion.my-autocomplete { + li { + line-height: normal; + padding-top: 7px; + padding-bottom: 7px; + + .name { + text-overflow: ellipsis; + overflow: hidden; + } + .addr { + font-size: 12px; + color: #b4b4b4; + } + .highlighted .addr { + color: #ddd; + } + } +} +.demo-input-suffix { + margin-bottom: 15px; + .el-input { + margin-right: 15px; + } +} diff --git a/examples/demo-styles/layout.scss b/examples/demo-styles/layout.scss new file mode 100644 index 0000000..df63934 --- /dev/null +++ b/examples/demo-styles/layout.scss @@ -0,0 +1,28 @@ +.demo-layout { + .el-row { + margin-bottom: 20px; + &:last-child { + margin-bottom: 0; + } + } + .el-col { + border-radius: 4px; + } + .bg-purple-dark { + background: #99a9bf; + } + .bg-purple { + background: #d3dce6; + } + .bg-purple-light { + background: #e5e9f2; + } + .grid-content { + border-radius: 4px; + min-height: 36px; + } + .row-bg { + padding: 10px 0; + background-color: #f9fafc; + } +} diff --git a/examples/demo-styles/loading.scss b/examples/demo-styles/loading.scss new file mode 100644 index 0000000..0fd6e26 --- /dev/null +++ b/examples/demo-styles/loading.scss @@ -0,0 +1,3 @@ +.demo-loading .el-table { + border: none; +} diff --git a/examples/demo-styles/menu.scss b/examples/demo-styles/menu.scss new file mode 100644 index 0000000..3b35021 --- /dev/null +++ b/examples/demo-styles/menu.scss @@ -0,0 +1,27 @@ +.demo-block.demo-menu { + .el-menu-demo { + padding-left: 55px; + } + .el-menu-vertical-demo:not(.el-menu--collapse) { + width: 240px; + min-height: 400px; + } + .line { + height: 1px; + background-color: #e0e6ed; + margin: 35px -24px; + } + h5 { + font-size: 14px; + color: #8492a6; + margin-top: 10px; + } + .tac { + text-align: center; + + .el-menu-vertical-demo { + display: inline-block; + text-align: left; + } + } +} diff --git a/examples/demo-styles/pagination.scss b/examples/demo-styles/pagination.scss new file mode 100644 index 0000000..09f751d --- /dev/null +++ b/examples/demo-styles/pagination.scss @@ -0,0 +1,46 @@ +.demo-pagination .source.first { + padding: 0; +} + +.demo-pagination .first .block { + padding: 30px 0; + text-align: center; + border-right: solid 1px #eff2f6; + display: inline-block; + width: 50%; + box-sizing: border-box; + + &:last-child { + border-right: none; + } +} + +.demo-pagination .first .demonstration { + display: block; + color: #8492a6; + font-size: 14px; + margin-bottom: 20px; +} + +.demo-pagination .source.last { + padding: 0; +} + +.demo-pagination .last .block { + padding: 30px 24px; + border-bottom: solid 1px #eff2f6; + &:last-child { + border-bottom: none; + } +} + +.demo-pagination .last .demonstration { + font-size: 14px; + color: #8492a6; + line-height: 44px; +} + +.demo-pagination .last .demonstration + .el-pagination { + width: 70%; + margin: 5px 20px 0 0; +} diff --git a/examples/demo-styles/popover.scss b/examples/demo-styles/popover.scss new file mode 100644 index 0000000..ee18df7 --- /dev/null +++ b/examples/demo-styles/popover.scss @@ -0,0 +1,11 @@ +.demo-block.demo-popover { + .el-popover + .el-popover { + margin-left: 10px; + } + .el-input { + width: 360px; + } + .el-button { + margin-left: 10px; + } +} diff --git a/examples/demo-styles/progress.scss b/examples/demo-styles/progress.scss new file mode 100644 index 0000000..216c8d8 --- /dev/null +++ b/examples/demo-styles/progress.scss @@ -0,0 +1,9 @@ +.demo-block.demo-progress { + .el-progress--line { + margin-bottom: 15px; + width: 350px; + } + .el-progress--circle { + margin-right: 15px; + } +} diff --git a/examples/demo-styles/rate.scss b/examples/demo-styles/rate.scss new file mode 100644 index 0000000..b82b355 --- /dev/null +++ b/examples/demo-styles/rate.scss @@ -0,0 +1,18 @@ +.demo-rate .block { + padding: 30px 0; + text-align: center; + border-right: solid 1px #eff2f6; + display: inline-block; + width: 49%; + box-sizing: border-box; + &:last-child { + border-right: none; + } +} + +.demo-rate .demonstration { + display: block; + color: #8492a6; + font-size: 14px; + margin-bottom: 20px; +} diff --git a/examples/demo-styles/select.scss b/examples/demo-styles/select.scss new file mode 100644 index 0000000..3d3c8e9 --- /dev/null +++ b/examples/demo-styles/select.scss @@ -0,0 +1,3 @@ +.demo-select .el-select { + width: 240px; +} diff --git a/examples/demo-styles/slider.scss b/examples/demo-styles/slider.scss new file mode 100644 index 0000000..1b600a2 --- /dev/null +++ b/examples/demo-styles/slider.scss @@ -0,0 +1,24 @@ +.demo-block.demo-slider .source { + padding: 0; +} + +.demo-block.demo-slider .block { + padding: 30px 24px; + overflow: hidden; + border-bottom: solid 1px #eff2f6; + &:last-child { + border-bottom: none; + } +} + +.demo-block.demo-slider .demonstration { + font-size: 14px; + color: #8492a6; + line-height: 44px; +} + +.demo-block.demo-slider .demonstration + .el-slider { + float: right; + width: 70%; + margin-right: 20px; +} diff --git a/examples/demo-styles/switch.scss b/examples/demo-styles/switch.scss new file mode 100644 index 0000000..d62bb64 --- /dev/null +++ b/examples/demo-styles/switch.scss @@ -0,0 +1,5 @@ +.demo-block.demo-switch { + .el-switch { + margin: 20px 20px 20px 0; + } +} diff --git a/examples/demo-styles/table.scss b/examples/demo-styles/table.scss new file mode 100644 index 0000000..ccd16e6 --- /dev/null +++ b/examples/demo-styles/table.scss @@ -0,0 +1,23 @@ +.el-table .warning-row { + background: oldlace; +} + +.el-table .success-row { + background: #f0f9eb; +} + +.demo-table .name-wrapper { + display: inline-block; +} + +.demo-table .demo-table-expand { + label { + width: 90px; + color: #99a9bf; + } + .el-form-item { + margin-right: 0; + margin-bottom: 0; + width: 50%; + } +} diff --git a/examples/demo-styles/tag.scss b/examples/demo-styles/tag.scss new file mode 100644 index 0000000..967d05b --- /dev/null +++ b/examples/demo-styles/tag.scss @@ -0,0 +1,34 @@ +.demo-block.demo-tag { + .el-tag + .el-tag { + margin-left: 10px; + } + + .button-new-tag { + margin-left: 10px; + height: 32px; + line-height: 30px; + padding-top: 0; + padding-bottom: 0; + } + + .input-new-tag { + width: 90px; + margin-left: 10px; + vertical-align: bottom; + } + + .tag-group { + display: flex; + align-items: center; + + &__title { + width: 45px; + font-size: 14px; + color: #606266; + } + + &+.tag-group { + margin-top: 10px; + } + } +} diff --git a/examples/demo-styles/time-picker.scss b/examples/demo-styles/time-picker.scss new file mode 100644 index 0000000..f3c19a6 --- /dev/null +++ b/examples/demo-styles/time-picker.scss @@ -0,0 +1,5 @@ +.demo-block { + .el-date-editor + .el-date-editor { + margin-left: 10px; + } +} diff --git a/examples/demo-styles/timeline.scss b/examples/demo-styles/timeline.scss new file mode 100644 index 0000000..0a50028 --- /dev/null +++ b/examples/demo-styles/timeline.scss @@ -0,0 +1,6 @@ +.demo-timeline .source .radio { + margin-bottom: 20px; +} +.demo-timeline .source .radio .el-radio-group { + margin-left: 20px; +} diff --git a/examples/demo-styles/tooltip.scss b/examples/demo-styles/tooltip.scss new file mode 100644 index 0000000..74e3e23 --- /dev/null +++ b/examples/demo-styles/tooltip.scss @@ -0,0 +1,39 @@ +.demo-tooltip { + .el-tooltip + .el-tooltip { + margin-left: 15px; + } + .box { + width: 400px; + + .top { + text-align: center; + } + + .left { + float: left; + width: 60px; + } + + .right { + float: right; + width: 60px; + } + + .bottom { + clear: both; + text-align: center; + } + + .item { + margin: 4px; + } + + .left .el-tooltip__popper, + .right .el-tooltip__popper { + padding: 8px 10px; + } + .el-tooltip { + margin-left: 0; + } + } +} diff --git a/examples/demo-styles/transfer.scss b/examples/demo-styles/transfer.scss new file mode 100644 index 0000000..a5b4943 --- /dev/null +++ b/examples/demo-styles/transfer.scss @@ -0,0 +1,6 @@ +.demo-transfer { + .transfer-footer { + margin-left: 15px; + padding: 6px 5px; + } +} diff --git a/examples/demo-styles/transition.scss b/examples/demo-styles/transition.scss new file mode 100644 index 0000000..f7828c5 --- /dev/null +++ b/examples/demo-styles/transition.scss @@ -0,0 +1,14 @@ +.demo-transition { + .transition-box { + margin-bottom: 10px; + width: 200px; + height: 100px; + border-radius: 4px; + background-color: #409EFF; + text-align: center; + color: #fff; + padding: 40px 20px; + margin-right: 20px; + box-sizing: border-box; + } +} diff --git a/examples/demo-styles/tree.scss b/examples/demo-styles/tree.scss new file mode 100644 index 0000000..286b0f3 --- /dev/null +++ b/examples/demo-styles/tree.scss @@ -0,0 +1,48 @@ +.demo-tree { + .leaf { + width: 20px; + background: #ddd; + } + + .folder { + width: 20px; + background: #888; + } + + .buttons { + margin-top: 20px; + } + + .filter-tree { + margin-top: 20px; + } + + .custom-tree-container { + display: flex; + margin: -24px; + } + + .block { + flex: 1; + padding: 8px 24px 24px; + + &:first-child { + border-right: solid 1px #eff2f6; + } + + > p { + text-align: center; + margin: 0; + line-height: 4; + } + } + + .custom-tree-node { + flex: 1; + display: flex; + align-items: center; + justify-content: space-between; + font-size: 14px; + padding-right: 8px; + } +} diff --git a/examples/demo-styles/typography.scss b/examples/demo-styles/typography.scss new file mode 100644 index 0000000..ff9c0a2 --- /dev/null +++ b/examples/demo-styles/typography.scss @@ -0,0 +1,30 @@ +.demo-typo-size { + .color-dark-light { + color: #99a9bf; + } +} +.demo-term-box img { + width: 24%; + margin: 0 4% 20px 0; +} + +.lineH-left { + display: inline-block; + height: 80px; +} +.lineH-right { + display: inline-block; + list-style: none; + padding: 0 0 0 90px; + margin: 0; + vertical-align: top; +} +.lineH-right li { + font-size: 13px; + color: #666; + height: 20px; + line-height: 20px; +} +.lineH-right li span { + padding-left: 40px; +} diff --git a/examples/demo-styles/upload.scss b/examples/demo-styles/upload.scss new file mode 100644 index 0000000..e7f8a94 --- /dev/null +++ b/examples/demo-styles/upload.scss @@ -0,0 +1,39 @@ +.upload-tip { + color: #8492a6; + font-size: 12px; + margin-top: 7px; +} +.demo-block { + margin-bottom: 24px; + + .upload-demo { + width: 360px; + } + .avatar-uploader { + .el-upload { + border: 1px dashed #d9d9d9; + border-radius: 6px; + cursor: pointer; + position: relative; + overflow: hidden; + + &:hover, + &:focus { + border-color: #409eff; + } + } + .avatar-uploader-icon { + font-size: 28px; + color: #8c939d; + width: 178px; + height: 178px; + line-height: 178px; + text-align: center; + } + .avatar { + width: 178px; + height: 178px; + display: block; + } + } +} diff --git a/examples/docs/en-US/alert.md b/examples/docs/en-US/alert.md new file mode 100644 index 0000000..3db4f32 --- /dev/null +++ b/examples/docs/en-US/alert.md @@ -0,0 +1,242 @@ +## Alert + +Displays important alert messages. + +### Basic usage + +Alert components are non-overlay elements in the page that does not disappear automatically. + +:::demo Alert provides 4 types of themes defined by `type`, whose default value is `info`. + +```html + +``` +::: + +### Theme + +Alert provide two different themes, `light` and `dark`. + +:::demo Set `effect` to change theme, default is `light`. +```html + +``` +::: + +### Customizable close button + +Customize the close button as texts or other symbols. + +:::demo Alert allows you to configure if it's closable. The close button text and closing callbacks are also customizable. `closable` attribute decides if the component can be closed or not. It accepts `boolean`, and the default is `true`. You can set `close-text` attribute to replace the default cross symbol as the close button. Be careful that `close-text` must be a string. `close` event fires when the component is closed. + +```html + + + +``` +::: + +### With icon + +Displaying an icon improves readability. + +:::demo Setting the `show-icon` attribute displays an icon that corresponds with the current Alert type. + +```html + +``` +::: + +## Centered text + +Use the `center` attribute to center the text. + +:::demo + +```html + +``` +::: + +### With description + +Description includes a message with more detailed information. + +:::demo Besides the required `title` attribute, you can add a `description` attribute to help you describe the alert with more details. Description can only store text string, and it will word wrap automatically. + +```html + +``` +::: + +### With icon and description + +:::demo At last, this is an example with both icon and description. + +```html + +``` +::: + +### Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| title | title | string | — | — | +| type | Component type | string | success/warning/info/error | info | +| description | Descriptive text. Can also be passed with the default slot | string | — | — | +| closable | If closable or not | boolean | — | true | +| center | Whether to center the text | boolean | — | false | +| close-text | Customized close button text | string | — | — | +| show-icon | If a type icon is displayed | boolean | — | false | +| effect | Choose theme | string | light/dark | light | + +### Slot + +| Name | Description | +|------|--------| +| — | description | +| title | content of the Alert title | + +### Events +| Event Name | Description | Parameters | +|---------- |-------- |---------- | +| close | fires when alert is closed | — | diff --git a/examples/docs/en-US/avatar.md b/examples/docs/en-US/avatar.md new file mode 100644 index 0000000..99e9198 --- /dev/null +++ b/examples/docs/en-US/avatar.md @@ -0,0 +1,145 @@ +## Avatar avatar + +Avatars can be used to represent people or objects. It supports images, Icons, or characters. + +### Basic + +use `shape` and `size` prop to set avatar's shape and size + +:::demo +```html + + + +``` +::: + +### Types + +It supports images, Icons, or characters + +:::demo +```html + +``` +::: + +### Fallback when image load error + +fallback when image load error + +:::demo +```html + + + +``` +::: + +### How the image fit its container + +Set how the image fit its container for an image avatar, same as [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit). + +:::demo +```html + + + +``` +::: + +### Attributes + +| Attribute | Description | Type | Accepted Values | Default | +| ----------------- | -------------------------------- | --------------- | ------ | ------ | +| icon | set representation type to Icon, more info on Icon Component | string | | | +| size | set avatar size | number/string | number / large / medium / small | large | +| shape | set avatar shape | string | circle / square | circle | +| src | the address of the image for an image avatar | string | | | +| srcSet | A list of one or more strings separated by commas indicating a set of possible image sources for the user agent to use | string | | | +| alt | This attribute defines an alternative text description of the image | string | | | +| fit | set how the image fit its container for an image avatar | string | fill / contain / cover / none / scale-down | cover | + +### Events + +| Event Name | Description | Parameters | +| ------ | ------------------ | -------- | +| error | handler when img load error, return false to prevent default fallback behavior |(e: Event) | + +### Slot + +| Slot Name | Description | +| default | customize avatar content | diff --git a/examples/docs/en-US/backtop.md b/examples/docs/en-US/backtop.md new file mode 100644 index 0000000..faadfe3 --- /dev/null +++ b/examples/docs/en-US/backtop.md @@ -0,0 +1,60 @@ +## Backtop + +A button to back to top + +### Basic usage + +Scroll down to see the bottom-right button. +:::demo + +```html + +``` + +::: + +### Customizations + +Display area is 40px \* 40px. +:::demo + +```html + +``` + +::: + +### Attributes + +| Attribute | Description | Type | Accepted Values | Default | +| ----------------- | ------------------------------------------------------------------- | --------------- | --------------- | ------- | +| target | the target to trigger scroll | string | | | +| visibility-height | the button will not show until the scroll height reaches this value | number | | 200 | +| right | right distance | number | | 40 | +| bottom | bottom distance | number | | 40 | + +### Events + +| Event Name | Description | Parameters | +| ---------- | ------------------- | ----------- | +| click | triggers when click | click event | diff --git a/examples/docs/en-US/badge.md b/examples/docs/en-US/badge.md new file mode 100644 index 0000000..9f9a687 --- /dev/null +++ b/examples/docs/en-US/badge.md @@ -0,0 +1,124 @@ +## Badge + +A number or status mark on buttons and icons. + +### Basic usage + +Displays the amount of new messages. + +:::demo The amount is defined with `value` which accepts `Number` or `String`. + +```html + + comments + + + replies + + + comments + + + replies + + + + + Click Me + + + + comments + + + + replies + + + + + + +``` +::: + +### Max value + +You can customize the max value. + +:::demo The max value is defined by property `max` which is a `Number`. Note that it only works when `value` is also a `Number`. + +```html + + comments + + + replies + + + +``` +::: + +### Customizations + +Displays text content other than numbers. + +:::demo When `value` is a `String`, it can display customized text. + +```html + + comments + + + replies + + + +``` +::: + +### Little red dot + +Use a red dot to mark content that needs to be noticed. + +:::demo Use the attribute `is-dot`. It is a `Boolean`. + +```html +query + + + + + +``` +::: + +### Attributes +| Attribute | Description | Type | Accepted Values | Default | +|------------- |---------------- |---------------- |---------------------- |-------- | +| value | display value | string, number | — | — | +| max | maximum value, shows '{max}+' when exceeded. Only works if `value` is a `Number` | number | — | — | +| is-dot | if a little dot is displayed | boolean | — | false | +| hidden | hidden badge | boolean | — | false | +| type | button type | string | primary / success / warning / danger / info | — | diff --git a/examples/docs/en-US/border.md b/examples/docs/en-US/border.md new file mode 100644 index 0000000..540a522 --- /dev/null +++ b/examples/docs/en-US/border.md @@ -0,0 +1,135 @@ + + +## Border + +We standardize the borders that can be used in buttons, cards, pop-ups and other components. + +### Border + +There are few border styles to choose. + + + + + + + + + + + + + + + + + + + +
NameThicknessDemo
Solid1px +
+
Dashed2px +
+
+ +### Radius + +There are few radius styles to choose. + + + +
No Radius
+
border-radius: 0px
+
+
+ +
Small Radius
+
border-radius: {{borderRadiusSmall}}
+
+
+ +
Large Radius
+
border-radius: {{borderRadiusBase}}
+
+
+ +
Round Radius
+
border-radius: 30px
+
+
+
+ +### Shadow + +There are few shadow styles to choose. + +
+Basic Shadow box-shadow: {{boxShadowBase}} + +
+Light Shadow box-shadow: {{boxShadowLight}} diff --git a/examples/docs/en-US/breadcrumb.md b/examples/docs/en-US/breadcrumb.md new file mode 100644 index 0000000..fc8539a --- /dev/null +++ b/examples/docs/en-US/breadcrumb.md @@ -0,0 +1,49 @@ +## Breadcrumb + +Displays the location of the current page, making it easier to browser back. + +### Basic usage + + +:::demo In `el-breadcrumb`, each `el-breadcrumb-item` is a tag that stands for every level starting from homepage. This component has a `String` attribute `separator`, and it determines the separator. Its default value is '/'. + +```html + + homepage + promotion management + promotion list + promotion detail + +``` +::: + +### Icon separator + +:::demo Set `separator-class` to use `iconfont` as the separator,it will cover `separator` + +```html + + homepage + promotion management + promotion list + promotion detail + +``` +::: + +### Breadcrumb Attributes +| Attribute | Description | Type | Accepted Values | Default| +|---------- |-------------- |---------- |-------------------------------- |-------- | +| separator | separator character | string | — | / | +| separator-class | class name of icon separator | string | — | - | + +### Breadcrumb Item Attributes +| Attribute | Description | Type | Accepted Values | Default| +|---------- |-------------- |---------- |-------------------------------- |-------- | +| to | target route of the link, same as `to` of `vue-router` | string/object | — | — | +| replace | if `true`, the navigation will not leave a history record | boolean | — | false | + + + + + diff --git a/examples/docs/en-US/button.md b/examples/docs/en-US/button.md new file mode 100644 index 0000000..9c00fff --- /dev/null +++ b/examples/docs/en-US/button.md @@ -0,0 +1,165 @@ +## Button + +Commonly used button. + +### Basic usage + +:::demo Use `type`, `plain`, `round` and `circle` to define Button's style. + +```html + + Default + Primary + Success + Info + Warning + Danger + + + + Plain + Primary + Success + Info + Warning + Danger + + + + Round + Primary + Success + Info + Warning + Danger + + + + + + + + + + +``` +::: + +### Disabled Button + +The `disabled` attribute determines if the button is disabled. + +:::demo Use `disabled` attribute to determine whether a button is disabled. It accepts a `Boolean` value. + +```html + + Default + Primary + Success + Info + Warning + Danger + + + + Plain + Primary + Success + Info + Warning + Danger + +``` +::: + +### Text Button + +Buttons without border and background. + +:::demo +```html +Text Button +Text Button +``` +::: + +### Icon Button + +Use icons to add more meaning to Button. You can use icon alone to save some space, or use it with text. + +:::demo Use the `icon` attribute to add icon. You can find the icon list in Element icon component. Adding icons to the right side of the text is achievable with an `` tag. Custom icons can be used as well. + +```html + + + +Search +Upload +``` +::: + +### Button Group + +Displayed as a button group, can be used to group a series of similar operations. + +:::demo Use tag `` to group your buttons. + +```html + + Previous Page + Next Page + + + + + + +``` +::: + +### Loading Button + +Click the button to load data, then the button displays a loading state. + +:::demo Set `loading` attribute to `true` to display loading state. + +```html +Loading +``` +::: + +### Sizes + +Besides default size, Button component provides three additional sizes for you to choose among different scenarios. + +:::demo Use attribute `size` to set additional sizes with `medium`, `small` or `mini`. + +```html + + Default + Medium + Small + Mini + + + Default + Medium + Small + Mini + +``` +::: + +### Attributes +| Attribute | Description | Type | Accepted values | Default | +|---------- |-------- |---------- |------------- |-------- | +| size | button size | string | medium / small / mini | — | +| type | button type | string | primary / success / warning / danger / info / text | — | +| plain | determine whether it's a plain button | boolean | — | false | +| round | determine whether it's a round button | boolean | — | false | +| circle | determine whether it's a circle button | boolean | — | false | +| loading | determine whether it's loading | boolean | — | false | +| disabled | disable the button | boolean | — | false | +| icon | icon class name | string | — | — | +| autofocus | same as native button's `autofocus` | boolean | — | false | +| native-type | same as native button's `type` | string | button / submit / reset | button | \ No newline at end of file diff --git a/examples/docs/en-US/calendar.md b/examples/docs/en-US/calendar.md new file mode 100644 index 0000000..46302f4 --- /dev/null +++ b/examples/docs/en-US/calendar.md @@ -0,0 +1,66 @@ +## Calendar + +Display date. + +### Basic + +:::demo Set `value` to specify the currently displayed month. If `value` is not specified, current month is displayed. `value` supports two-way binding. +```html + + + + +``` +::: + +### Custom Content + +:::demo Customize what is displayed in the calendar cell by setting `scoped-slot` named `dateCell`. In `scoped-slot` you can get the date (the date of the current cell), data (including the type, isSelected, day attribute). For details, please refer to the API documentation below. +```html + + + + + +``` +::: + +### Range + +:::demo Set the `range` attribute to specify the display range of the calendar. Start time must be Monday, end time must be Sunday, and the time span cannot exceed two months. +```html + + +``` +::: + +### Attributes +| Attribute | Description | Type | Accepted Values | Default | +|-----------------|------------------- |---------- |---------------------- |--------- | +| value / v-model | binding value | Date/string/number | — | — | +| range | time range, including start time and end time. Start time must be start day of week, end time must be end day of week, the time span cannot exceed two months. | Array | — | — | +| first-day-of-week | fisrt day of week| Number | 1 to 7 | 1 | + +### dateCell Scoped Slot Parameters +| Attribute | Description | Type | Accepted Values | Default | +|-----------------|-------------- |---------- |---------------------- |--------- | +| date | date the cell represents | Date | — | — | +| data | { type, isSelected, day}. The `type` property indicates which month the date belongs, optional values are `prev-month`, `current-month`, `next-month`. The `isSelected` property indicates whether the date is selected. The `day` property is the formatted date in the format yyyy-MM-dd | Object | — | — | diff --git a/examples/docs/en-US/card.md b/examples/docs/en-US/card.md new file mode 100644 index 0000000..0abfb46 --- /dev/null +++ b/examples/docs/en-US/card.md @@ -0,0 +1,169 @@ +## Card +Integrate information in a card container. + +### Basic usage + +Card includes title, content and operations. + +:::demo Card is made up of `header` and `body`. `header` is optional, and its content distribution depends on a named slot. +```html + +
+ Card name + Operation button +
+
+ {{'List item ' + o }} +
+
+ + +``` +::: + +### Simple card + +The header part can be omitted. + +:::demo +```html + +
+ {{'List item ' + o }} +
+
+ + +``` +::: + +### With images + +Display richer content by adding some configs. + +:::demo The `body-style` attribute defines CSS style of custom `body`. This example also uses `el-col` for layout. +```html + + + + +
+ Yummy hamburger +
+ + Operating +
+
+
+
+
+ + + + +``` +::: + +### Shadow + +You can define when to show the card shadows + +:::demo The `shadow` attribute determines when the card shadows are displayed. It can be `always`, `hover` or `never`. +```html + + + + Always + + + + + Hover + + + + + Never + + + +``` +::: + +### Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------- |---------- |------------- |-------- | +| header | title of the card. Also accepts a DOM passed by `slot#header` | string| — | — | +| body-style | CSS style of body | object| — | { padding: '20px' } | +| shadow | when to show card shadows | string | always / hover / never | always | diff --git a/examples/docs/en-US/carousel.md b/examples/docs/en-US/carousel.md new file mode 100644 index 0000000..36ed9f9 --- /dev/null +++ b/examples/docs/en-US/carousel.md @@ -0,0 +1,212 @@ +## Carousel + +Loop a series of images or texts in a limited space + +### Basic usage + +:::demo Combine `el-carousel` with `el-carousel-item`, and you'll get a carousel. Content of each slide is completely customizable, and you just need to place it inside `el-carousel-item` tag. By default the carousel switches when mouse hovers over an indicator. Set `trigger` to `click`, and the carousel switches only when an indicator is clicked. +```html + + + +``` +::: + +### Indicators + +Indicators can be displayed outside the carousel + +:::demo The `indicator-position` attribute determines where the indicators are located. By default they are inside the carousel, and setting `indicator-position` to `outside` moves them outside; setting `indicator-position` to `none` hides the indicators. +```html + + + +``` +::: + +### Arrows + +You can define when arrows are displayed + +:::demo The `arrow` attribute determines when arrows are displayed. By default they appear when mouse hovers over the carousel. Setting `arrow` to `always` or `never` shows/hides the arrows permanently. +```html + + + +``` +::: + +### Card mode + +When a page is wide enough but has limited height, you can activate card mode for carousels + +:::demo Setting `type` to `card` activates the card mode. Apart from the appearance, the biggest difference between card mode and common mode is that clicking the slides at both sides directly switches the carousel in card mode. +```html + + + +``` +::: + +By default, `direction` is `horizontal`. Let carousel be displayed in the vertical direction by setting `direction` to `vertical`. + +:::demo +```html + + + +``` +::: + +### Carousel Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| height | height of the carousel | string | — | — | +| initial-index | index of the initially active slide (starting from 0) | number | — | 0 | +| trigger | how indicators are triggered | string | hover/click | hover | +| autoplay | whether automatically loop the slides | boolean | — | true | +| interval | interval of the auto loop, in milliseconds | number | — | 3000 | +| indicator-position | position of the indicators | string | outside/none | — | +| arrow | when arrows are shown | string | always/hover/never | hover | +| type | type of the Carousel | string | card | — | +| loop | display the items in loop | boolean | - | true | +| direction | display direction | string | horizontal/vertical | horizontal | + +### Carousel Events +| Event Name | Description | Parameters | +|---------|---------|---------| +| change | triggers when the active slide switches | index of the new active slide, index of the old active slide | + +### Carousel Methods +| Method | Description | Parameters | +|---------- |-------------- | -- | +| setActiveItem | manually switch slide | index of the slide to be switched to, starting from 0; or the `name` of corresponding `el-carousel-item` | +| prev | switch to the previous slide | — | +| next | switch to the next slide | — | + +### Carousel-Item Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| name | name of the item, can be used in `setActiveItem` | string | — | — | +| label | text content for the corresponding indicator | string | — | — | diff --git a/examples/docs/en-US/cascader.md b/examples/docs/en-US/cascader.md new file mode 100644 index 0000000..5d13574 --- /dev/null +++ b/examples/docs/en-US/cascader.md @@ -0,0 +1,1987 @@ +## Cascader + +If the options have a clear hierarchical structure, Cascader can be used to view and select them. + +### Basic usage + +There are two ways to expand child option items. + +:::demo Assigning the `options` attribute to an array of options renders a Cascader. The `props.expandTrigger` attribute defines how child options are expanded. +```html +
+ Child options expand when clicked (default) + +
+
+ Child options expand when hovered + +
+ + +``` +::: + +### Disabled option + +Disable an option by setting a `disabled` field in the option object. + +:::demo In this example, the first item in `options` array has a `disabled: true` field, so it is disabled. By default, Cascader checks the `disabled` field in each option object; if you are using another field name to indicate whether an option is disabled, you can assign it in the `props.disabled` attribute (see the API table below for details). And of course, field name `value`, `label` and `children` can also be customized in the same way. +```html + + + +``` +::: + +### Clearable + +Set `clearable` attribute for `el-cascader` and a clear icon will appear when selected and hovered + +:::demo +```html + + + +``` +::: + +### Display only the last level + +The input can display only the last level instead of all levels. + +:::demo The `show-all-levels` attribute defines if all levels are displayed. If it is `false`, only the last level is displayed. +```html + + +``` +::: + +### Multiple Selection + +Set `props.multiple = true` to use multiple selection. + +:::demo When using multiple selection, all selected tags will display by default, You can set `collapse-tags = true` to fold selected tags. +```html +
+ Display all tags (default) + +
+
+ Collapse tags + +
+ + +``` +::: + + +### Select any level of options + +In single selection, only the leaf nodes can be checked, and in multiple selection, check parent nodes will lead to leaf nodes be checked eventually. When enable this feature, it can make parent and child nodes unlinked and you can select any level of options. + +:::demo Set `props.checkStrictly = true` to make checked state of a node not affects its parent nodes and child nodes, and then you can select any level of options. +```html +
+ Select any level of options (Single selection) + +
+
+ Select any level of options (Multiple selection) + +
+ + +``` +::: + +### Dynamic loading + +Dynamic load its child nodes when checked a node. + +:::demo Set `lazy = true` to use dynamic loading, and you have to specify how to load the data source by `lazyload`. There are two parameters of `lazyload`,the first parameter `node` is the node currently clicked, and the `resolve` is a callback that indicate loading is finished which must invoke. To display the status of node more accurately, you can add a `leaf` field (can be modified by `props.leaf`) to indicate whether it is a leaf node. Otherwise, it will be inferred by if has any child nodes. +```html + + + +``` +::: + +### Filterable + +Search and select options with a keyword. + +:::demo Adding `filterable` to `el-cascader` enables filtering. Cascader will match nodes whose label or parent's label (according to `show-all-levels`) includes input keyword. Of course, you can customize search logic by `filter-method` which accepts a function, the first parameter is `node`, the second is `keyword`, and need return a boolean value indicating whether it hits. +```html +
+ Filterable (Single selection) + +
+
+ Filterable (Multiple selection) + +
+ + +``` +::: + +### Custom option content + +You can customize the content of cascader node. + +:::demo You can customize the content of cascader node by `scoped slot`. You'll have access to `node` and `data` in the scope, standing for the Node object and node data of the current node respectively。 +```html + + + + + +``` +::: + +### Cascader panel + +`CascaderPanel` is the core component of `Cascader` which has various of features such as single selection, multiple selection, dynamic loading and so on. + +:::demo Just like `el-cascader`, you can set alternative options by `options`, and enable other features by `props`, see the API form below for details. +```html + + + +``` +::: + +### Cascader Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------- |---------- |------------- |-------- | +| value / v-model | binding value | - | — | — | +| options | data of the options,the key of `value` and `label` can be customize by `Props`.| array | — | — | +| props | configuration options, see the following table. | object | — | — | +| size | size of input | string | medium / small / mini | — | +| placeholder | placeholder of input | string | — | Select | +| disabled | whether Cascader is disabled | boolean | — | false | +| clearable | whether selected value can be cleared | boolean | — | false | +| show-all-levels | whether to display all levels of the selected value in the input | boolean | — | true | +| collapse-tags | whether to collapse tags in multiple selection mode | boolean | - | false | +| separator | option label separator | string | — | ' / ' | +| filterable | whether the options can be searched | boolean | — | — | +| filter-method | customize search logic, the first parameter is `node`, the second is `keyword`, and need return a boolean value indicating whether it hits. | function(node, keyword) | - | - | +| debounce | debounce delay when typing filter keyword, in milliseconds | number | — | 300 | +| before-filter | hook function before filtering with the value to be filtered as its parameter. If `false` is returned or a `Promise` is returned and then is rejected, filtering will be aborted | function(value) | — | — | +| popper-class | custom class name for Cascader's dropdown | string | — | — | + +### Cascader Events +| Event Name | Description | Parameters | +|---------- |-------- |---------- | +| change | triggers when the binding value changes | value | +| expand-change | triggers when expand option changes | an array of the expanding node's parent nodes | +| blur | triggers when Cascader blurs | (event: Event) | +| focus | triggers when Cascader focuses | (event: Event) | +| visible-change | triggers when the dropdown appears/disappears | true when it appears, and false otherwise | +| remove-tag | triggers when remove tag in multiple selection mode | the value of the tag which is removed | + +### Cascader Methods +| Method Name | Description | Parameters | +| ---- | ---- | ---- | +| getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` | + +### Cascader Slots +| Slot Name | Description | +|---------|-------------| +| - | the custom content of cascader node, the parameter is { node, data }, which are current Node object and node data respectively. | +| empty | content when there is no matched options. | + +### CascaderPanel Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------- |---------- |------------- |-------- | +| value / v-model | binding value | - | — | — | +| options | data of the options,the key of `value` and `label` can be customize by `Props`.| array | — | — | +| props | configuration options, see the following table. | object | — | — | + +### CascaderPanel Events +| Event Name | Description | Parameters | +|---------- |-------- |---------- | +| change | triggers when the binding value changes | value | +| expand-change | triggers when expand option changes | an array of the expanding node's parent nodes | + +### CascaderPanel Methods +| Method Name | Description | Parameters | +| ---- | ---- | ---- | +| getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` | +| clearCheckedNodes | clear checked nodes | - | + +### CascaderPanel Slots +| Slot Name | Description | +|---------|-------------| +| - | the custom content of cascader node, the parameter is { node, data }, which are current Node object and node data respectively. | + +### Props +| Attribute | Description | Type | Accepted Values | Default | +| -------- | ----------------- | ------ | ------ | ------ | +| expandTrigger | trigger mode of expanding options | string | click / hover | 'click' | +| multiple | whether multiple selection is enabled | boolean | - | false | +| checkStrictly | whether checked state of a node not affects its parent and child nodes | boolean | - | false | +| emitPath | when checked nodes change, whether to emit an array of node's path, if false, only emit the value of node. | boolean | - | true | +| lazy | whether to dynamic load child nodes, use with `lazyload` attribute | boolean | - | false | +| lazyLoad | method for loading child nodes data, only works when `lazy` is true | function(node, resolve) | - | - | +| value | specify which key of node object is used as the node's value | string | — | 'value' | +| label | specify which key of node object is used as the node's label | string | — | 'label' | +| children | specify which key of node object is used as the node's children | string | — | 'children' | +| disabled | specify which key of node object is used as the node's disabled | string | — | 'disabled' | +| leaf | specify which key of node object is used as the node's leaf field | string | — | 'leaf' | diff --git a/examples/docs/en-US/checkbox.md b/examples/docs/en-US/checkbox.md new file mode 100644 index 0000000..dc67aee --- /dev/null +++ b/examples/docs/en-US/checkbox.md @@ -0,0 +1,284 @@ +## Checkbox + +A group of options for multiple choices. + +### Basic usage + +Checkbox can be used alone to switch between two states. + +:::demo Define `v-model`(bind variable) in `el-checkbox`. The default value is a `Boolean` for single `checkbox`, and it becomes `true` when selected. Content inside the `el-checkbox` tag will become the description following the button of the checkbox. + +```html + + +``` +::: + +### Disabled State + +Disabled state for checkbox. + +:::demo Set the `disabled` attribute. + +```html + + +``` +::: + +### Checkbox group + +It is used for multiple checkboxes which are bound in one group, and indicates whether one option is selected by checking if it is checked. + +:::demo `checkbox-group` element can manage multiple checkboxes in one group by using `v-model` which is bound as an `Array`. Inside the `el-checkbox` element, `label` is the value of the checkbox. If no content is nested in that tag, `label` will be rendered as the description following the button of the checkbox. `label` also corresponds with the element values in the array. It is selected if the specified value exists in the array, and vice versa. + +```html + + + +``` +::: + +### Indeterminate + +The `indeterminate` property can help you to achieve a 'check all' effect. + +:::demo + +```html + + +``` +::: + +### Minimum / Maximum items checked + +The `min` and `max` properties can help you to limit the number of checked items. + +:::demo + +```html + + +``` +::: + +### Button style + +Checkbox with button styles. + +:::demo You just need to change `el-checkbox` element into `el-checkbox-button` element. We also provide `size` attribute. +```html + + +``` +::: + +### With borders + +:::demo The `border` attribute adds a border to Checkboxes. +```html + + + +``` +::: + +### Checkbox Attributes +| Attribute | Description | Type | Options | Default| +|---------- |-------- |---------- |------------- |-------- | +| value / v-model | binding value | string / number / boolean | — | — | +| label | value of the Checkbox when used inside a `checkbox-group` | string / number / boolean | — | — | +| true-label | value of the Checkbox if it's checked | string / number | — | — | +| false-label | value of the Checkbox if it's not checked | string / number | — | — | +| disabled | whether the Checkbox is disabled | boolean | — | false | +| border | whether to add a border around Checkbox | boolean | — | false | +| size | size of the Checkbox, only works when `border` is true | string | medium / small / mini | — | +| name | native 'name' attribute | string | — | — | +| checked | if the Checkbox is checked | boolean | — | false | +| indeterminate | same as `indeterminate` in native checkbox | boolean | — | false | + +### Checkbox Events +| Event Name | Description | Parameters | +|---------- |-------- |---------- | +| change | triggers when the binding value changes | the updated value | + +### Checkbox-group Attributes +| Attribute | Description | Type | Options | Default| +|---------- |-------- |---------- |------------- |-------- | +| value / v-model | binding value | array | — | — | +|size | size of checkbox buttons or bordered checkboxes | string | medium / small / mini | — | +| disabled | whether the nesting checkboxes are disabled | boolean | — | false | +| min | minimum number of checkbox checked | number | — | — | +| max | maximum number of checkbox checked | number | — | — | +|text-color | font color when button is active | string | — | #ffffff | +|fill | border and background color when button is active | string | — | #409EFF | + +### Checkbox-group Events +| Event Name | Description | Parameters | +|---------- |-------- |---------- | +| change | triggers when the binding value changes | the updated value | + +### Checkbox-button Attributes +| Attribute | Description | Type | Options | Default| +|---------- |-------- |---------- |------------- |-------- | +| label | value of the checkbox when used inside a `checkbox-group` | string / number / boolean | — | — | +| true-label | value of the checkbox if it's checked | string / number | — | — | +| false-label | value of the checkbox if it's not checked | string / number | — | — | +| disabled | whether the checkbox is disabled | boolean | — | false | +| name | native 'name' attribute | string | — | — | +| checked | if the checkbox is checked | boolean | — | false | diff --git a/examples/docs/en-US/collapse.md b/examples/docs/en-US/collapse.md new file mode 100644 index 0000000..b8133fd --- /dev/null +++ b/examples/docs/en-US/collapse.md @@ -0,0 +1,131 @@ +## Collapse + +Use Collapse to store contents. + +### Basic usage + +You can expand multiple panels + +:::demo +```html + + +
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;
+
Consistent within interface: all elements should be consistent, such as: design style, icons and texts, position of elements, etc.
+
+ +
Operation feedback: enable the users to clearly perceive their operations by style updates and interactive effects;
+
Visual feedback: reflect current state by updating or rearranging elements of the page.
+
+ +
Simplify the process: keep operating process simple and intuitive;
+
Definite and clear: enunciate your intentions clearly so that the users can quickly understand and make decisions;
+
Easy to identify: the interface should be straightforward, which helps the users to identify and frees them from memorizing and recalling.
+
+ +
Decision making: giving advices about operations is acceptable, but do not make decisions for the users;
+
Controlled consequences: users should be granted the freedom to operate, including canceling, aborting or terminating current operation.
+
+
+ +``` +::: + +### Accordion + +In accordion mode, only one panel can be expanded at once + +:::demo Activate accordion mode using the `accordion` attribute. +```html + + +
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;
+
Consistent within interface: all elements should be consistent, such as: design style, icons and texts, position of elements, etc.
+
+ +
Operation feedback: enable the users to clearly perceive their operations by style updates and interactive effects;
+
Visual feedback: reflect current state by updating or rearranging elements of the page.
+
+ +
Simplify the process: keep operating process simple and intuitive;
+
Definite and clear: enunciate your intentions clearly so that the users can quickly understand and make decisions;
+
Easy to identify: the interface should be straightforward, which helps the users to identify and frees them from memorizing and recalling.
+
+ +
Decision making: giving advices about operations is acceptable, but do not make decisions for the users;
+
Controlled consequences: users should be granted the freedom to operate, including canceling, aborting or terminating current operation.
+
+
+ +``` +::: + +### Custom title + +Besides using the `title` attribute, you can customize panel title with named slots, which makes adding custom content, e.g. icons, possible. + +:::demo +```html + + + +
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;
+
Consistent within interface: all elements should be consistent, such as: design style, icons and texts, position of elements, etc.
+
+ +
Operation feedback: enable the users to clearly perceive their operations by style updates and interactive effects;
+
Visual feedback: reflect current state by updating or rearranging elements of the page.
+
+ +
Simplify the process: keep operating process simple and intuitive;
+
Definite and clear: enunciate your intentions clearly so that the users can quickly understand and make decisions;
+
Easy to identify: the interface should be straightforward, which helps the users to identify and frees them from memorizing and recalling.
+
+ +
Decision making: giving advices about operations is acceptable, but do not make decisions for the users;
+
Controlled consequences: users should be granted the freedom to operate, including canceling, aborting or terminating current operation.
+
+
+``` +::: + +### Collapse Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| value / v-model | currently active panel | string (accordion mode) / array (non-accordion mode) | — | — | +| accordion | whether to activate accordion mode | boolean | — | false | + +### Collapse Events +| Event Name | Description | Parameters | +|---------|---------|---------| +| change | triggers when active panels change | (activeNames: array (non-accordion mode) / string (accordion mode)) | + +### Collapse Item Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| name | unique identification of the panel | string/number | — | — | +| title | title of the panel | string | — | — | +| disabled | disable the collapse item | boolean | — | — | \ No newline at end of file diff --git a/examples/docs/en-US/color-picker.md b/examples/docs/en-US/color-picker.md new file mode 100644 index 0000000..8fa0b6d --- /dev/null +++ b/examples/docs/en-US/color-picker.md @@ -0,0 +1,124 @@ +## ColorPicker + +ColorPicker is a color selector supporting multiple color formats. + +### Basic usage + +:::demo ColorPicker requires a string typed variable to be bound to v-model. +```html +
+ With default value + +
+
+ With no default value + +
+ + +``` +::: + +### Alpha + +:::demo ColorPicker supports alpha channel selecting. To activate alpha selecting, just add the `show-alpha` attribute. +```html + + + +``` +::: + +### Predefined colors + +:::demo ColorPicker supports predefined color options +```html + + + + +``` +::: + + +### Sizes + +:::demo +```html + + + + + + +``` +::: + +### Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------- |---------- |------------- |-------- | +| value / v-model | binding value | string | — | — | +| disabled | whether to disable the ColorPicker | boolean | — | false | +| size | size of ColorPicker | string | — | medium / small / mini | +| show-alpha | whether to display the alpha slider | boolean | — | false | +| color-format | color format of v-model | string | hsl / hsv / hex / rgb | hex (when show-alpha is false)/ rgb (when show-alpha is true) | +| popper-class | custom class name for ColorPicker's dropdown | string | — | — | +| predefine | predefined color options | array | — | — | + +### Events +| Event Name | Description | Parameters | +|---------|--------|---------| +| change | triggers when input value changes | color value | +| active-change | triggers when the current active color changes | active color value | \ No newline at end of file diff --git a/examples/docs/en-US/color.md b/examples/docs/en-US/color.md new file mode 100644 index 0000000..c22d590 --- /dev/null +++ b/examples/docs/en-US/color.md @@ -0,0 +1,251 @@ + + +## Color + +Element uses a specific set of palettes to specify colors to provide a consistent look and feel for the products you build. + +### Main Color + +The main color of Element is bright and friendly blue. + + + +
+ Brand Color
#409EFF
+
+
+
+
+
+
+
+ +### Secondary Color + +Besides the main color, you need to use different scene colors in different scenarios (for example, dangerous color indicates dangerous operation) + + + +
Success
#67C23A
+
+
+
+
+
+
+ +
Warning
#E6A23C
+
+
+
+
+
+
+ +
Danger
#F56C6C
+
+
+
+
+
+
+ +
Info
#909399
+
+
+
+
+
+
+
+ +### Neutral Color + +Neutral colors are for text, background and border colors. You can use different neutral colors to represent the hierarchical structure. + + + +
+
Primary Text
{{textPrimary}}
+
+ Regular Text
{{textRegular}}
+
Secondary Text
{{textSecondary}}
+
Placeholder Text
{{textPlaceholder}}
+
+
+ +
+
Base Border
{{borderBase}}
+
Light Border
{{borderLight}}
+
Lighter Border
{{borderLighter}}
+
Extra Light Border
{{borderExtraLight}}
+
+
+ +
+
Basic Black
{{black}}
+
Basic White
{{white}}
+
Transparent
Transparent
+
+
+
+
diff --git a/examples/docs/en-US/container.md b/examples/docs/en-US/container.md new file mode 100644 index 0000000..1fd23b4 --- /dev/null +++ b/examples/docs/en-US/container.md @@ -0,0 +1,240 @@ +## Container +Container components for scaffolding basic structure of the page: + +``: wrapper container. When nested with a `` or ``, all its child elements will be vertically arranged. Otherwise horizontally. + +``: container for headers. + +``: container for side sections (usually a side nav). + +``: container for main sections. + +``: container for footers. + +:::tip +These components use flex for layout, so please make sure your browser supports it. Besides, ``'s direct child elements have to be one or more of the latter four components. And father element of the latter four components must be a ``. +::: + +### Common layouts + +:::demo +```html + + Header + Main + + + + Header + Main + Footer + + + + Aside + Main + + + + Header + + Aside + Main + + + + + Header + + Aside + + Main + Footer + + + + + + Aside + + Header + Main + + + + + Aside + + Header + Main + Footer + + + + +``` +::: + +### Example + +:::demo +```html + + + + + + + + Option 1 + Option 2 + + + Option 3 + + + + Option 4-1 + + + + + + + Option 1 + Option 2 + + + Option 3 + + + + Option 4-1 + + + + + + + Option 1 + Option 2 + + + Option 3 + + + + Option 4-1 + + + + + + + + + + + View + Add + Delete + + + Tom + + + + + + + + + + + + + + + + + + +``` +::: + +### Container Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| direction | layout direction for child elements | string | horizontal / vertical | vertical when nested with `el-header` or `el-footer`; horizontal otherwise | + +### Header Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| height | height of the header | string | — | 60px | + +### Aside Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| width | width of the side section | string | — | 300px | + +### Footer Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| height | height of the footer | string | — | 60px | \ No newline at end of file diff --git a/examples/docs/en-US/custom-theme.md b/examples/docs/en-US/custom-theme.md new file mode 100644 index 0000000..77514cf --- /dev/null +++ b/examples/docs/en-US/custom-theme.md @@ -0,0 +1,132 @@ +## Custom theme +Element uses BEM-styled CSS so that you can override styles easily. But if you need to replace styles at a large scale, e.g. change the theme color from blue to orange or green, maybe overriding them one by one is not a good idea. We provide four ways to change the style variables. + +### Theme Roller +Use [Online Theme Roller](./#/en-US/theme) to customize all Design Tokens of global variables and components,and preview the new theme in real-time.and it can generate a complete style package based on the new theme for you to download directly (to import new style files in your project, please refer to the 'Import custom theme' part of this section). + +Also, use [Theme Roller Chrome Extension](https://chrome.google.com/webstore/detail/element-theme-roller/lifkjlojflekabbmlddfccdkphlelmim),to customize theme and preview in real-time on any website developed by Element. + + + +### Changing theme color +If you just want to change the theme color of Element, the [theme preview website](https://elementui.github.io/theme-chalk-preview/#/en-US) is recommended. The theme color of Element is bright and friendly blue. By changing it, you can make Element more visually connected to specific projects. + +The above website enables you to preview theme of a new theme color in real-time, and it can generate a complete style package based on the new theme color for you to download directly (to import new style files in your project, please refer to the 'Import custom theme' or 'Import component theme on demand' part of this section). + +### Update SCSS variables in your project +`theme-chalk` is written in SCSS. If your project also uses SCSS, you can directly change Element style variables. Create a new style file, e.g. `element-variables.scss`: + +```html +/* theme color */ +$--color-primary: teal; + +/* icon font path, required */ +$--font-path: '~element-ui/lib/theme-chalk/fonts'; + +@import "~element-ui/packages/theme-chalk/src/index"; +``` + +Then in the entry file of your project, import this style file instead of Element's built CSS: +```JS +import Vue from 'vue' +import Element from 'element-ui' +import './element-variables.scss' + +Vue.use(Element) +``` + +:::tip +Note that it is required to override icon font path to the relative path of Element's font files. +::: + +### CLI theme tool +If you project doesn't use SCSS, you can customize themes with our CLI theme tool: + +#### Install +First install the theme generator globally or locally. Local install is recommended because in this way, when others clone your project, npm will automatically install it for them. +```shell +npm i element-theme -g +``` + +Then install the chalk theme from npm or GitHub. +```shell +# from npm +npm i element-theme-chalk -D + +# from GitHub +npm i https://github.com/ElementUI/theme-chalk -D +``` + +#### Initialize variable file +After successfully installing the above packages, a command named `et` is available in CLI (if the packages are installed locally, use `node_modules/.bin/et` instead). Run `-i` to initialize the variable file which outputs to `element-variables.scss` by default. And you can specify its output directory as you will. + +```shell +et -i [custom output file] + +> ✔ Generator variables file +``` + +In `element-variables.scss` you can find all the variables we used to style Element and they are defined in SCSS format. Here's a snippet: +```css +$--color-primary: #409EFF !default; +$--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */ +$--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */ +$--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */ +$--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */ +$--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */ +$--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */ +$--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */ +$--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: #e6a23c !default; +$--color-danger: #f56c6c !default; +$--color-info: #909399 !default; + +... +``` + +#### Modify variables +Just edit `element-variables.scss`, e.g. changing the theme color to red: +```CSS +$--color-primary: red; +``` + +#### Build theme +After saving the variable file, use `et` to build your theme. You can activate `watch` mode by adding a parameter `-w`. And if you customized the variable file's output, you need to add a parameter `-c` and variable file's name. By default the build theme file is placed inside `./theme`. You can specify its output directory with parameter `-o`. +```shell +et + +> ✔ build theme font +> ✔ build element theme +``` +### Use custom theme +#### Import custom theme +Importing your own theme is just like importing the default theme, only this time you import the file built from "Online Theme Roller" or "CLI tool": + +```javascript +import '../theme/index.css' +import ElementUI from 'element-ui' +import Vue from 'vue' + +Vue.use(ElementUI) +``` + +#### Import component theme on demand +If you are using `babel-plugin-component` for on-demand import, just modify `.babelrc` and specify `styleLibraryName` to the path where your custom theme is located relative to `.babelrc`. Note that `~` is required: +```json +{ + "plugins": [ + [ + "component", + { + "libraryName": "element-ui", + "styleLibraryName": "~theme" + } + ] + ] +} +``` + +If you are unfamiliar with `babel-plugin-component`, please refer to Quick Start. For more details, check out the [project repository](https://github.com/ElementUI/element-theme) of `element-theme`. \ No newline at end of file diff --git a/examples/docs/en-US/date-picker.md b/examples/docs/en-US/date-picker.md new file mode 100644 index 0000000..0b43664 --- /dev/null +++ b/examples/docs/en-US/date-picker.md @@ -0,0 +1,491 @@ + +## DatePicker + +Use Date Picker for date input. + +### Enter Date + +Basic date picker measured by 'day'. + +:::demo The measurement is determined by the `type` attribute. You can enable quick options by creating a `picker-options` object with `shortcuts` property. The disabled date is set by `disabledDate`, which is a function. + +```html + + + +``` +::: + +### Other measurements + +You can choose week, month, year or multiple dates by extending the standard date picker component. + +:::demo + +```html +
+
+ Week + + +
+
+ Month + + +
+
+
+
+ Year + + +
+
+ Dates + + +
+
+ + +``` + +::: + +### Date Range + +Picking a date range is supported. + +:::demo When in range mode, the left and right panels are linked by default. If you want the two panels to switch current months independently, you can use the `unlink-panels` attribute. + +```html + + + +``` + +::: + +### Month Range + +Picking a month range is supported. + +:::demo When in range mode, the left and right panels are linked by default. If you want the two panels to switch current years independently, you can use the `unlink-panels` attribute. +```html + + + +``` +::: + +### Default Value + +If user hasn't picked a date, shows today's calendar by default. You can use `default-value` to set another date. Its value should be parsable by `new Date()`. + +If type is `daterange`, `default-value` sets the left side calendar. + +:::demo +```html + + + +``` +::: + +### Date Formats +Use `format` to control displayed text's format in the input box. Use `value-format` to control binding value's format. + +By default, the component accepts and emits a `Date` object. Below are supported format strings, using UTC 2017-01-02 03:04:05 as an example: + +:::warning +Pay attention to capitalization +::: + +| format | meaning | note | example | +|------|------|------|------|------| +| `yyyy` | year | | 2017 | +| `M` | month | no leading 0 | 1 | +| `MM` | month | | 01 | +| `MMM` | month | | Jan | +| `MMMM` | month | | January | +| `W` | week | only for week picker's `format`; no leading 0 | 1 | +| `WW` | week | only for week picker's `format`| 01 | +| `d` | day | no leading 0 | 2 | +| `dd` | day | | 02 | +| `H` | hour | 24-hour clock; no leading 0 | 3 | +| `HH` | hour | 24-hour clock | 03 | +| `h` | hour | 12-hour clock; must be used with `A` or `a`; no leading 0 | 3 | +| `hh` | hour | 12-hour clock; must be used with `A` or `a` | 03 | +| `m` | minute | no leading 0 | 4 | +| `mm` | minute | | 04 | +| `s` | second | no leading 0 | 5 | +| `ss` | second | | 05 | +| `A` | AM/PM | only for `format`, uppercased | AM | +| `a` | am/pm | only for `format`, lowercased | am | +| `timestamp` | JS timestamp | only for `value-format`; binding value will be a `number` | 1483326245000 | +| `[MM]` | No escape characters | To escape characters, wrap them in square brackets (e.g. [A] [MM]) | MM | + +:::demo +```html + + + +``` +::: + +### Default time for start date and end date + +When picking a date range, you can assign the time part for start date and end date. + +:::demo By default, the time part of start date and end date are both `00:00:00`. Setting `default-time` can change their time respectively. It accepts an array of up to two strings with the format of `12:00:00`. The first string sets the time for the start date, and the second for the end date. +```html + + + +``` +::: + +### Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| value / v-model | binding value | date(DatePicker) / array(DateRangePicker) | — | — | +| readonly | whether DatePicker is read only | boolean | — | false | +| disabled | whether DatePicker is disabled | boolean | — | false | +| size | size of Input | string | large/small/mini | — | +| editable | whether the input is editable | boolean | — | true | +| clearable | whether to show clear button | boolean | — | true | +| placeholder | placeholder in non-range mode | string | — | — | +| 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/dates/datetime/ week/datetimerange/daterange/ monthrange | date | +| format | format of the displayed value in the input box | string | see [date formats](#/en-US/component/date-picker#date-formats) | 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()` | — | +| default-time | optional, the time value to use when selecting date range | string[] | Array with length 2, each item is a string like `12:00:00`. The first item for the start date and then second item for the end date | — | +| value-format | optional, format of binding value. If not specified, the binding value will be a Date object | string | see [date formats](#/en-US/component/date-picker#date-formats) | — | +| name | same as `name` in native input | string | — | — | +| unlink-panels | unlink two date-panels in range-picker | boolean | — | false | +| prefix-icon | Custom prefix icon class | string | — | el-icon-date | +| clear-icon | Custom clear icon class | string | — | el-icon-circle-close | +| validate-event | whether to trigger form validation | boolean | - | true | + +### Picker Options +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| shortcuts | a { text, onClick } object array to set shortcut options, check the table below | object[] | — | — | +| disabledDate | a function determining if a date is disabled with that date as its parameter. Should return a Boolean | function | — | — | +| cellClassName | set custom className | Function(Date) | — | — | +| firstDayOfWeek | first day of week | Number | 1 to 7 | 7 | +| onPick | a callback that triggers when the selected date is changed. Only for `daterange` and `datetimerange`. | Function({ maxDate, minDate }) | - | - | + +### shortcuts +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| text | title of the shortcut | string | — | — | +| onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — | + + +### Events +| Event Name | Description | Parameters | +|---------|--------|---------| +| change | triggers when user confirms the value | component's binding value | +| blur | triggers when Input blurs | component instance | +| focus | triggers when Input focuses | component instance | + +### Methods +| Method | Description | Parameters | +|------|--------|-------| +| focus | focus the Input component | — | + +### Slots +| Name | Description | +|---------|-------------| +| range-separator | custom range separator content | diff --git a/examples/docs/en-US/datetime-picker.md b/examples/docs/en-US/datetime-picker.md new file mode 100644 index 0000000..ef14e13 --- /dev/null +++ b/examples/docs/en-US/datetime-picker.md @@ -0,0 +1,241 @@ +## DateTimePicker + +Select date and time in one picker. + +:::tip +DateTimePicker is derived from DatePicker and TimePicker. For a more detailed explanation on `pickerOptions` and other attributes, you can refer to DatePicker and TimePicker. +::: + +### Date and time + +:::demo You can select date and time in one picker at the same time by setting `type` to `datetime`. The way to use shortcuts is the same as Date Picker. + +```html + + + +``` +::: + +### Date and time range + +:::demo You can select date and time range by setting `type` to `datetimerange`. + +```html + + + +``` +::: + +### Default time value for start date and end date + +:::demo When picking date range on the date panel with type `datetimerange`, `00:00:00` will be used as the default time value for start and end date. We can control it with the `default-time` attribute. `default-time` accepts an array of up to two strings. The first item controls time value of the start date and the second item controls time value of the end date. +```html + + + +``` +::: + +### Attributes +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| value / v-model | binding value | date(DateTimePicker) / array(DateTimeRangePicker) | — | — | +| readonly | whether DatePicker is read only | boolean | — | false | +| disabled | whether DatePicker is disabled | boolean | — | false | +| editable | whether the input is editable | boolean | — | true | +| clearable | whether to show clear button | boolean | — | true | +|size | size of Input | string | large/small/mini | — | +| placeholder | placeholder in non-range mode | string | — | — | +| start-placeholder | placeholder for the start date in range mode | string | — | — | +| 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 | see [date formats](#/en-US/component/date-picker#date-formats) | yyyy-MM-dd HH:mm:ss | +| 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()` | — | +| default-time | the default time value after picking a date | non-range: string / range: string[] | non-range: a string like `12:00:00`, range: array of two strings, and the first item is for the start date and second for the end date. `00:00:00` will be used if not specified | — | +| value-format | optional, format of binding value. If not specified, the binding value will be a Date object | string | see [date formats](#/en-US/component/date-picker#date-formats) | — | +| name | same as `name` in native input | string | — | — | +| unlink-panels | unllink two date-panels in range-picker | boolean | — | false | +| prefix-icon | Custom prefix icon class | string | — | el-icon-date | +| clear-icon | Custom clear icon class | string | — | el-icon-circle-close | + +### Picker Options +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| shortcuts | a { text, onClick } object array to set shortcut options, check the table below | object[] | — | — | +| disabledDate | a function determining if a date is disabled with that date as its parameter. Should return a Boolean | function | — | — | +| cellClassName | set custom className | Function(Date) | — | — | +| firstDayOfWeek | first day of week | Number | 1 to 7 | 7 | + +### shortcuts +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| text | title of the shortcut | string | — | — | +| onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — | + +### Events +| Event Name | Description | Parameters | +|---------|--------|---------| +| change | triggers when user confirms the value | component's binding value | +| blur | triggers when Input blurs | component instance | +| focus | triggers when Input focuses | component instance | + +### Methods +| Method | Description | Parameters | +|------|--------|-------| +| focus | focus the Input component | — | diff --git a/examples/docs/en-US/dialog.md b/examples/docs/en-US/dialog.md new file mode 100644 index 0000000..bddc134 --- /dev/null +++ b/examples/docs/en-US/dialog.md @@ -0,0 +1,240 @@ +## Dialog + +Informs users while preserving the current page state. + +### Basic usage + +Dialog pops up a dialog box, and it's quite customizable. + +:::demo Set the `visible` attribute with a `Boolean`, and Dialog shows when it is `true`. The Dialog has two parts: `body` and `footer`, and the latter requires a `slot` named `footer`. The optional `title` attribute (empty by default) is for defining a title. Finally, this example demonstrates how `before-close` is used. + +```html +click to open the Dialog + + + This is a message + + Cancel + Confirm + + + + +``` +::: + +:::tip +`before-close` only works when user clicks the close icon or the backdrop. If you have buttons that close the Dialog in the `footer` named slot, you can add what you would do with `before-close` in the buttons' click event handler. +::: + +### Customizations + +The content of Dialog can be anything, even a table or a form. This example shows how to use Element Table and Form with Dialog。 + +:::demo + +```html + +open a Table nested Dialog + + + + + + + + + + +open a Form nested Dialog + + + + + + + + + + + + + + + Cancel + Confirm + + + + +``` +::: + +### Nested Dialog +If a Dialog is nested in another Dialog, `append-to-body` is required. +:::demo Normally we do not recommend using nested Dialog. If you need multiple Dialogs rendered on the page, you can simply flat them so that they're siblings to each other. If you must nest a Dialog inside another Dialog, set `append-to-body` of the nested Dialog to true, and it will append to body instead of its parent node, so both Dialogs can be correctly rendered. +```html + + + +``` +::: + +### Centered content +Dialog's content can be centered. + +:::demo Setting `center` to `true` will center dialog's header and footer horizontally. `center` only affects Dialog's header and footer. The body of Dialog can be anything, so sometimes it may not look good when centered. You need to write some CSS if you wish to center the body as well. + +```html +Click to open the Dialog + + + It should be noted that the content will not be aligned in center by default + + Cancel + Confirm + + + + +``` +::: + +:::tip +The content of Dialog is lazily rendered, which means the default slot is not rendered onto the DOM until it is firstly opened. Therefore, if you need to perform a DOM manipulation or access a component using `ref`, do it in the `open` event callback. +::: + +:::tip +If the variable bound to `visible` is managed in Vuex store, the `.sync` can not work properly. In this case, please remove the `.sync` modifier, listen to `open` and `close` events of Dialog, and commit Vuex mutations to update the value of that variable in the event handlers. +::: + +### Attributes + +| Attribute | Description | Type | Accepted Values | Default | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| visible | visibility of Dialog, supports the .sync modifier | boolean | — | false | +| title | title of Dialog. Can also be passed with a named slot (see the following table) | string | — | — | +| width | width of Dialog | string | — | 50% | +| fullscreen | whether the Dialog takes up full screen | boolean | — | false | +| top | value for `margin-top` of Dialog CSS | string | — | 15vh | +| modal | whether a mask is displayed | boolean | — | true | +| modal-append-to-body | whether to append modal to body element. If false, the modal will be appended to Dialog's parent element | boolean | — | true | +| append-to-body | whether to append Dialog itself to body. A nested Dialog should have this attribute set to `true` | boolean | — | false | +| lock-scroll | whether scroll of body is disabled while Dialog is displayed | boolean | — | true | +| custom-class | custom class names for Dialog | string | — | — | +| close-on-click-modal | whether the Dialog can be closed by clicking the mask | boolean | — | true | +| close-on-press-escape | whether the Dialog can be closed by pressing ESC | boolean | — | true | +| show-close | whether to show a close button | boolean | — | true | +| before-close | callback before Dialog closes, and it will prevent Dialog from closing | function(done),done is used to close the Dialog | — | — | +| center | whether to align the header and footer in center | boolean | — | false | +| destroy-on-close | Destroy elements in Dialog when closed | boolean | — | false | + +### Slot + +| Name | Description | +|------|--------| +| — | content of Dialog | +| title | content of the Dialog title | +| footer | content of the Dialog footer | + +### Events +| Event Name | Description | Parameters | +|---------- |-------- |---------- | +| open | triggers when the Dialog opens | — | +| opened | triggers when the Dialog opening animation ends | — | +| close | triggers when the Dialog closes | — | +| closed | triggers when the Dialog closing animation ends | — | diff --git a/examples/docs/en-US/divider.md b/examples/docs/en-US/divider.md new file mode 100644 index 0000000..d419c9b --- /dev/null +++ b/examples/docs/en-US/divider.md @@ -0,0 +1,61 @@ +## Divider + +The dividing line that separates the content. + +### Basic usage + +Divide the text of different paragraphs. + +:::demo +```html + +``` +::: + +### Custom content + +You can customize the content on the divider line. + + +:::demo +```html + +``` +::: + +### Vertical divider + +:::demo +```html + +``` +::: + +### Divider Attributes +| Attribute | Description | Type | Accepted Values | Default | +|------------- |---------------- |---------------- |---------------------- |-------- | +| direction | Set divider's direction | string | horizontal / vertical | horizontal | +| content-position | customize the content on the divider line | String | left / right / center | center | \ No newline at end of file diff --git a/examples/docs/en-US/drawer.md b/examples/docs/en-US/drawer.md new file mode 100644 index 0000000..7e99cdd --- /dev/null +++ b/examples/docs/en-US/drawer.md @@ -0,0 +1,305 @@ +## Drawer + +Sometimes, `Dialog` does not always satisfy our requirements, let's say you have a massive form, or you need space to display something like `terms & conditions`, `Drawer` has almost identical API with `Dialog`, but it introduces different user experience. + +### Basic Usage + +Callout a temporary drawer, from multiple direction + +:::demo You must set `visible` for `Drawer` like `Dialog` does to control the visibility of `Drawer` itself, it's `boolean` type. `Drawer` has to parts: `title` & `body`, the `title` is a named slot, you can also set the title through attribute named `title`, default to an empty string, the `body` part is the main area of `Drawer`, which contains user defined content. When opening, `Drawer` expand itself from the **right corner to left** which size is **30%** of the browser window by default. You can change that default behavior by setting `direction` and `size` attribute. This show case also demonstrated how to use the `before-close` API, check the Attribute section for more detail + +```html + + left to right + right to left + top to bottom + bottom to top + + + + open + + + + Hi, there! + + + +``` +::: + +### No Title + +When you no longer need a title, you can remove title from drawer. + +:::demo Set the `withHeader` attribute to **false**, you can remove the title from drawer, thus your drawer can have more space on screen. If you want to be accessible, make sure to set the `title` attribute. + +```html + + open + + + + Hi there! + + + +``` +::: + +### Customization Content + +Like `Dialog`, `Drawer` can do many diverse interaction as you wanted. + +:::demo + +```html +Open Drawer with nested table +Open Drawer with nested form + + + + + + + + + +
+ + + + + + + + + + + + +
+
+ + +``` +::: + +### Nested Drawer + +You can also have multiple layer of `Drawer` just like `Dialog`. +:::demo If you need multiple Drawer in different layer, you must set the `append-to-body` attribute to **true** + +```html + + + open + + + +
+ Click me! + +

_(:зゝ∠)_

+
+
+
+ + + +``` +::: + +:::tip + +The content inside Drawer should be lazy rendered, which means that the content inside Drawer will not impact the initial render performance, therefore any DOM operation should be performed through `ref` or after `open` event emitted. + +::: + +:::tip + +Drawer provides an API called `destroyOnClose`, which is a flag variable that indicates should destroy the children content inside Drawer after Drawer was closed. You can use this API when you need your `mounted` life cycle to be called every time the Drawer opens. + +::: + +:::tip + +If the variable bound to `visible` is managed in Vuex store, the `.sync` can not work properly. In this case, please remove the `.sync` modifier, listen to `open` and `close` events of Dialog, and commit Vuex mutations to update the value of that variable in the event handlers. + +::: + +### Drawer Attributes + +| Parameter| Description | Type | Acceptable Values | Defaults | +|---------- |-------------- |---------- |-------------------------------- |-------- | +| append-to-body | Controls should Drawer be inserted to DocumentBody Element, nested Drawer must assign this param to **true**| boolean | — | false | +| before-close | If set, closing procedure will be halted | function(done), done is function type that accepts a boolean as parameter, calling done with true or without parameter will abort the close procedure | — | — | +| close-on-press-escape | Indicates whether Drawer can be closed by pressing ESC | boolean | — | true | +| custom-class | Extra class names for Drawer | string | — | — | +| destroy-on-close | Indicates whether children should be destroyed after Drawer closed | boolean | - | false | +| modal | Should show shadowing layer | boolean | — | true | +| modal-append-to-body | Indicates should shadowing layer be insert into DocumentBody element | boolean | — | true | +| direction | Drawer's opening direction | Direction | rtl / ltr / ttb / btt | rtl | +| show-close | Should show close button at the top right of Drawer | boolean | — | true | +| size | Drawer's size, if Drawer is horizontal mode, it effects the width property, otherwise it effects the height property, when size is `number` type, it describes the size by unit of pixels; when size is `string` type, it should be used with `x%` notation, other wise it will be interpreted to pixel unit | number / string | - | '30%' | +| title | Drawer's title, can also be set by named slot, detailed descriptions can be found in the slot form | string | — | — | +| visible | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false | +| wrapperClosable | Indicates whether user can close Drawer by clicking the shadowing layer. | boolean | - | true | +| withHeader | Flag that controls the header section's existance, default to true, when withHeader set to false, both `title attribute` and `title slot` won't work | boolean | - | true | + +### Drawer Slot + +| Name | Description | +|------|--------| +| — | Drawer's Content | +| title | Drawer Title Section | + +### Drawer Methods + +| Name | Description | +| ---- | --- | +| closeDrawer | In order to close Drawer, this method will call `before-close`. | + +### Drawer Events + +| Event Name | Description | Parameter | +|---------- |-------- |---------- | +| open | Triggered before Drawer opening animation begins | — | +| opened | Triggered after Drawer opening animation ended | — | +| close | Triggered before Drawer closing animation begins | — | +| closed | Triggered after Drawer closing animation ended | — | diff --git a/examples/docs/en-US/dropdown.md b/examples/docs/en-US/dropdown.md new file mode 100644 index 0000000..a7d1ad7 --- /dev/null +++ b/examples/docs/en-US/dropdown.md @@ -0,0 +1,303 @@ +## Dropdown +Toggleable menu for displaying lists of links and actions. + +### Basic usage +Hover on the dropdown menu to unfold it for more actions. + +:::demo The triggering element is rendered by the default `slot`, and the dropdown part is rendered by the `slot` named `dropdown`. By default, dropdown list shows when you hover on the triggering element without having to click it. + +```html + + + Dropdown List + + + Action 1 + Action 2 + Action 3 + Action 4 + Action 5 + + + + + +``` + +::: + +### Triggering element + +Use the button to trigger the dropdown list. + +:::demo Use `split-button` to split the triggering element into a button group with the left button being a normal button and right one the actual triggering target. If you wanna insert a separator line between item three and item four, just add a class `divider` to item four. +```html + + + Dropdown List + + + Action 1 + Action 2 + Action 3 + Action 4 + Action 5 + + + + Dropdown List + + Action 1 + Action 2 + Action 3 + Action 4 + Action 5 + + + + + + +``` +::: + +### How to trigger + +Click the triggering element or hover on it. + +:::demo Use the attribute `trigger`. By default, it is `hover`. + +```html + + + hover to trigger + + + Dropdown List + + + Action 1 + Action 2 + Action 3 + Action 4 + Action 5 + + + + + click to trigger + + + Dropdown List + + + Action 1 + Action 2 + Action 3 + Action 4 + Action 5 + + + + + + +``` +::: + +### Menu hiding behavior + +Use `hide-on-click` to define if menu closes on clicking. + +:::demo By default menu will close when you click on menu items, and it can be turned off by setting hide-on-click to false. +```html + + + Dropdown List + + + Action 1 + Action 2 + Action 3 + Action 4 + Action 5 + + + + +``` +::: + +### Command event + +Clicking each dropdown item fires an event whose parameter is assigned by each item. + +:::demo +```html + + + Dropdown List + + + Action 1 + Action 2 + Action 3 + Action 4 + Action 5 + + + + + + +``` +::: + +### Sizes + +Besides default size, Dropdown component provides three additional sizes for you to choose among different scenarios. + +:::demo Use attribute `size` to set additional sizes with `medium`, `small` or `mini`. + +```html + + Default + + Action 1 + Action 2 + Action 3 + Action 4 + + + + + Medium + + Action 1 + Action 2 + Action 3 + Action 4 + + + + + Small + + Action 1 + Action 2 + Action 3 + Action 4 + + + + + Mini + + Action 1 + Action 2 + Action 3 + Action 4 + + +``` +::: + + +### Dropdown Attributes +| Attribute | Description | Type | Accepted Values | Default | +|------------- |---------------- |---------------- |---------------------- |-------- | +| type | menu button type, refer to `Button` Component, only works when `split-button` is true | string | — | — | +| size | menu size, also works on the split button | string | medium / small / mini | — | +| split-button | whether a button group is displayed | boolean | — | false | +| placement | placement of pop menu | string | top/top-start/top-end/bottom/bottom-start/bottom-end | bottom-end | +| trigger | how to trigger | string | hover/click | hover | +| hide-on-click | whether to hide menu after clicking menu-item | boolean | — | true | +| show-timeout | Delay time before show a dropdown (only works when trigger is `hover`) | number | — | 250 | +| hide-timeout | Delay time before hide a dropdown (only works when trigger is `hover`) | number | — | 150 | +| tabindex | [tabindex](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of Dropdown | number | — | 0 | + +### Dropdown Slots + +| Name | Description | +|------|--------| +| — | content of Dropdown. Notice: Must be a valid html dom element (ex. `, + ); + } + }, + + Next: { + render(h) { + return ( + + ); + } + }, + + Sizes: { + mixins: [Locale], + + props: { + pageSizes: Array + }, + + watch: { + pageSizes: { + immediate: true, + handler(newVal, oldVal) { + if (valueEquals(newVal, oldVal)) return; + if (Array.isArray(newVal)) { + this.$parent.internalPageSize = newVal.indexOf(this.$parent.pageSize) > -1 + ? this.$parent.pageSize + : this.pageSizes[0]; + } + } + } + }, + + render(h) { + return ( + + + { + this.pageSizes.map(item => + + + ) + } + + + ); + }, + + components: { + ElSelect, + ElOption + }, + + methods: { + handleChange(val) { + if (val !== this.$parent.internalPageSize) { + this.$parent.internalPageSize = val = parseInt(val, 10); + this.$parent.userChangePageSize = true; + this.$parent.$emit('update:pageSize', val); + this.$parent.$emit('size-change', val); + } + } + } + }, + + Jumper: { + mixins: [Locale], + + components: { ElInput }, + + data() { + return { + userInput: null + }; + }, + + watch: { + '$parent.internalCurrentPage'() { + this.userInput = null; + } + }, + + methods: { + handleKeyup({ keyCode, target }) { + // Chrome, Safari, Firefox triggers change event on Enter + // Hack for IE: https://github.com/ElemeFE/element/issues/11710 + // Drop this method when we no longer supports IE + if (keyCode === 13) { + this.handleChange(target.value); + } + }, + handleInput(value) { + this.userInput = value; + }, + handleChange(value) { + this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(value); + this.$parent.emitChange(); + this.userInput = null; + } + }, + + render(h) { + return ( + + { this.t('el.pagination.goto') } + + { this.t('el.pagination.pageClassifier') } + + ); + } + }, + + Total: { + mixins: [Locale], + + render(h) { + return ( + typeof this.$parent.total === 'number' + ? { this.t('el.pagination.total', { total: this.$parent.total }) } + : '' + ); + } + }, + + Pager + }, + + methods: { + handleCurrentChange(val) { + this.internalCurrentPage = this.getValidCurrentPage(val); + this.userChangePageSize = true; + this.emitChange(); + }, + + prev() { + if (this.disabled) return; + const newVal = this.internalCurrentPage - 1; + this.internalCurrentPage = this.getValidCurrentPage(newVal); + this.$emit('prev-click', this.internalCurrentPage); + this.emitChange(); + }, + + next() { + if (this.disabled) return; + const newVal = this.internalCurrentPage + 1; + this.internalCurrentPage = this.getValidCurrentPage(newVal); + this.$emit('next-click', this.internalCurrentPage); + this.emitChange(); + }, + + getValidCurrentPage(value) { + value = parseInt(value, 10); + + const havePageCount = typeof this.internalPageCount === 'number'; + + let resetValue; + if (!havePageCount) { + if (isNaN(value) || value < 1) resetValue = 1; + } else { + if (value < 1) { + resetValue = 1; + } else if (value > this.internalPageCount) { + resetValue = this.internalPageCount; + } + } + + if (resetValue === undefined && isNaN(value)) { + resetValue = 1; + } else if (resetValue === 0) { + resetValue = 1; + } + + return resetValue === undefined ? value : resetValue; + }, + + emitChange() { + this.$nextTick(() => { + if (this.internalCurrentPage !== this.lastEmittedPage || this.userChangePageSize) { + this.$emit('current-change', this.internalCurrentPage); + this.lastEmittedPage = this.internalCurrentPage; + this.userChangePageSize = false; + } + }); + } + }, + + computed: { + internalPageCount() { + if (typeof this.total === 'number') { + return Math.max(1, Math.ceil(this.total / this.internalPageSize)); + } else if (typeof this.pageCount === 'number') { + return Math.max(1, this.pageCount); + } + return null; + } + }, + + watch: { + currentPage: { + immediate: true, + handler(val) { + this.internalCurrentPage = this.getValidCurrentPage(val); + } + }, + + pageSize: { + immediate: true, + handler(val) { + this.internalPageSize = isNaN(val) ? 10 : val; + } + }, + + internalCurrentPage: { + immediate: true, + handler(newVal) { + this.$emit('update:currentPage', newVal); + this.lastEmittedPage = -1; + } + }, + + internalPageCount(newVal) { + /* istanbul ignore if */ + const oldPage = this.internalCurrentPage; + if (newVal > 0 && oldPage === 0) { + this.internalCurrentPage = 1; + } else if (oldPage > newVal) { + this.internalCurrentPage = newVal === 0 ? 1 : newVal; + this.userChangePageSize && this.emitChange(); + } + this.userChangePageSize = false; + } + } +}; diff --git a/packages/popconfirm/index.js b/packages/popconfirm/index.js new file mode 100644 index 0000000..15db1f0 --- /dev/null +++ b/packages/popconfirm/index.js @@ -0,0 +1,8 @@ +import Popconfirm from './src/main'; + +/* istanbul ignore next */ +Popconfirm.install = function(Vue) { + Vue.component(Popconfirm.name, Popconfirm); +}; + +export default Popconfirm; diff --git a/packages/popconfirm/src/main.vue b/packages/popconfirm/src/main.vue new file mode 100644 index 0000000..aabb6a2 --- /dev/null +++ b/packages/popconfirm/src/main.vue @@ -0,0 +1,104 @@ + + + diff --git a/packages/popover/index.js b/packages/popover/index.js new file mode 100644 index 0000000..54d56eb --- /dev/null +++ b/packages/popover/index.js @@ -0,0 +1,14 @@ +import Popover from './src/main'; +import directive from './src/directive'; +import Vue from 'vue'; + +Vue.directive('popover', directive); + +/* istanbul ignore next */ +Popover.install = function(Vue) { + Vue.directive('popover', directive); + Vue.component(Popover.name, Popover); +}; +Popover.directive = directive; + +export default Popover; diff --git a/packages/popover/src/directive.js b/packages/popover/src/directive.js new file mode 100644 index 0000000..132e372 --- /dev/null +++ b/packages/popover/src/directive.js @@ -0,0 +1,20 @@ +const getReference = (el, binding, vnode) => { + const _ref = binding.expression ? binding.value : binding.arg; + const popper = vnode.context.$refs[_ref]; + if (popper) { + if (Array.isArray(popper)) { + popper[0].$refs.reference = el; + } else { + popper.$refs.reference = el; + } + } +}; + +export default { + bind(el, binding, vnode) { + getReference(el, binding, vnode); + }, + inserted(el, binding, vnode) { + getReference(el, binding, vnode); + } +}; diff --git a/packages/popover/src/main.vue b/packages/popover/src/main.vue new file mode 100644 index 0000000..ab5d060 --- /dev/null +++ b/packages/popover/src/main.vue @@ -0,0 +1,237 @@ + + diff --git a/packages/progress/index.js b/packages/progress/index.js new file mode 100644 index 0000000..6e4f92a --- /dev/null +++ b/packages/progress/index.js @@ -0,0 +1,8 @@ +import ElProgress from './src/progress'; + +/* istanbul ignore next */ +ElProgress.install = function(Vue) { + Vue.component(ElProgress.name, ElProgress); +}; + +export default ElProgress; diff --git a/packages/progress/src/progress.vue b/packages/progress/src/progress.vue new file mode 100644 index 0000000..182f310 --- /dev/null +++ b/packages/progress/src/progress.vue @@ -0,0 +1,227 @@ + + diff --git a/packages/radio-button/index.js b/packages/radio-button/index.js new file mode 100644 index 0000000..3045f9b --- /dev/null +++ b/packages/radio-button/index.js @@ -0,0 +1,8 @@ +import RadioButton from '../radio/src/radio-button.vue'; + +/* istanbul ignore next */ +RadioButton.install = function(Vue) { + Vue.component(RadioButton.name, RadioButton); +}; + +export default RadioButton; diff --git a/packages/radio-group/index.js b/packages/radio-group/index.js new file mode 100644 index 0000000..af3d34b --- /dev/null +++ b/packages/radio-group/index.js @@ -0,0 +1,8 @@ +import RadioGroup from '../radio/src/radio-group.vue'; + +/* istanbul ignore next */ +RadioGroup.install = function(Vue) { + Vue.component(RadioGroup.name, RadioGroup); +}; + +export default RadioGroup; diff --git a/packages/radio/index.js b/packages/radio/index.js new file mode 100644 index 0000000..27178ac --- /dev/null +++ b/packages/radio/index.js @@ -0,0 +1,8 @@ +import Radio from './src/radio'; + +/* istanbul ignore next */ +Radio.install = function(Vue) { + Vue.component(Radio.name, Radio); +}; + +export default Radio; diff --git a/packages/radio/src/radio-button.vue b/packages/radio/src/radio-button.vue new file mode 100644 index 0000000..6b13f2a --- /dev/null +++ b/packages/radio/src/radio-button.vue @@ -0,0 +1,114 @@ + + diff --git a/packages/radio/src/radio-group.vue b/packages/radio/src/radio-group.vue new file mode 100644 index 0000000..342de3a --- /dev/null +++ b/packages/radio/src/radio-group.vue @@ -0,0 +1,111 @@ + + + diff --git a/packages/radio/src/radio.vue b/packages/radio/src/radio.vue new file mode 100644 index 0000000..dfef3ae --- /dev/null +++ b/packages/radio/src/radio.vue @@ -0,0 +1,133 @@ + + diff --git a/packages/rate/index.js b/packages/rate/index.js new file mode 100644 index 0000000..49b3a1b --- /dev/null +++ b/packages/rate/index.js @@ -0,0 +1,8 @@ +import Rate from './src/main'; + +/* istanbul ignore next */ +Rate.install = function(Vue) { + Vue.component(Rate.name, Rate); +}; + +export default Rate; diff --git a/packages/rate/src/main.vue b/packages/rate/src/main.vue new file mode 100644 index 0000000..b70ec86 --- /dev/null +++ b/packages/rate/src/main.vue @@ -0,0 +1,348 @@ + + + diff --git a/packages/row/index.js b/packages/row/index.js new file mode 100644 index 0000000..528566c --- /dev/null +++ b/packages/row/index.js @@ -0,0 +1,9 @@ +import Row from './src/row'; + +/* istanbul ignore next */ +Row.install = function(Vue) { + Vue.component(Row.name, Row); +}; + +export default Row; + diff --git a/packages/row/src/row.js b/packages/row/src/row.js new file mode 100644 index 0000000..5611d7c --- /dev/null +++ b/packages/row/src/row.js @@ -0,0 +1,47 @@ +export default { + name: 'ElRow', + + componentName: 'ElRow', + + props: { + tag: { + type: String, + default: 'div' + }, + gutter: Number, + type: String, + justify: { + type: String, + default: 'start' + }, + align: { + type: String, + default: 'top' + } + }, + + computed: { + style() { + const ret = {}; + + if (this.gutter) { + ret.marginLeft = `-${this.gutter / 2}px`; + ret.marginRight = ret.marginLeft; + } + + return ret; + } + }, + + render(h) { + return h(this.tag, { + class: [ + 'el-row', + this.justify !== 'start' ? `is-justify-${this.justify}` : '', + this.align !== 'top' ? `is-align-${this.align}` : '', + { 'el-row--flex': this.type === 'flex' } + ], + style: this.style + }, this.$slots.default); + } +}; diff --git a/packages/scrollbar/index.js b/packages/scrollbar/index.js new file mode 100644 index 0000000..a7cfcbd --- /dev/null +++ b/packages/scrollbar/index.js @@ -0,0 +1,8 @@ +import Scrollbar from './src/main'; + +/* istanbul ignore next */ +Scrollbar.install = function(Vue) { + Vue.component(Scrollbar.name, Scrollbar); +}; + +export default Scrollbar; diff --git a/packages/scrollbar/src/bar.js b/packages/scrollbar/src/bar.js new file mode 100644 index 0000000..0cf4c7e --- /dev/null +++ b/packages/scrollbar/src/bar.js @@ -0,0 +1,92 @@ +import { on, off } from 'element-ui/src/utils/dom'; +import { renderThumbStyle, BAR_MAP } from './util'; + +/* istanbul ignore next */ +export default { + name: 'Bar', + + props: { + vertical: Boolean, + size: String, + move: Number + }, + + computed: { + bar() { + return BAR_MAP[this.vertical ? 'vertical' : 'horizontal']; + }, + + wrap() { + return this.$parent.wrap; + } + }, + + render(h) { + const { size, move, bar } = this; + + return ( +
+
+
+
+ ); + }, + + methods: { + clickThumbHandler(e) { + // prevent click event of right button + if (e.ctrlKey || e.button === 2) { + return; + } + this.startDrag(e); + this[this.bar.axis] = (e.currentTarget[this.bar.offset] - (e[this.bar.client] - e.currentTarget.getBoundingClientRect()[this.bar.direction])); + }, + + clickTrackHandler(e) { + const offset = Math.abs(e.target.getBoundingClientRect()[this.bar.direction] - e[this.bar.client]); + const thumbHalf = (this.$refs.thumb[this.bar.offset] / 2); + const thumbPositionPercentage = ((offset - thumbHalf) * 100 / this.$el[this.bar.offset]); + + this.wrap[this.bar.scroll] = (thumbPositionPercentage * this.wrap[this.bar.scrollSize] / 100); + }, + + startDrag(e) { + e.stopImmediatePropagation(); + this.cursorDown = true; + + on(document, 'mousemove', this.mouseMoveDocumentHandler); + on(document, 'mouseup', this.mouseUpDocumentHandler); + document.onselectstart = () => false; + }, + + mouseMoveDocumentHandler(e) { + if (this.cursorDown === false) return; + const prevPage = this[this.bar.axis]; + + if (!prevPage) return; + + const offset = ((this.$el.getBoundingClientRect()[this.bar.direction] - e[this.bar.client]) * -1); + const thumbClickPosition = (this.$refs.thumb[this.bar.offset] - prevPage); + const thumbPositionPercentage = ((offset - thumbClickPosition) * 100 / this.$el[this.bar.offset]); + + this.wrap[this.bar.scroll] = (thumbPositionPercentage * this.wrap[this.bar.scrollSize] / 100); + }, + + mouseUpDocumentHandler(e) { + this.cursorDown = false; + this[this.bar.axis] = 0; + off(document, 'mousemove', this.mouseMoveDocumentHandler); + document.onselectstart = null; + } + }, + + destroyed() { + off(document, 'mouseup', this.mouseUpDocumentHandler); + } +}; diff --git a/packages/scrollbar/src/main.js b/packages/scrollbar/src/main.js new file mode 100644 index 0000000..b577370 --- /dev/null +++ b/packages/scrollbar/src/main.js @@ -0,0 +1,130 @@ +// reference https://github.com/noeldelgado/gemini-scrollbar/blob/master/index.js + +import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event'; +import scrollbarWidth from 'element-ui/src/utils/scrollbar-width'; +import { toObject } from 'element-ui/src/utils/util'; +import Bar from './bar'; + +/* istanbul ignore next */ +export default { + name: 'ElScrollbar', + + components: { Bar }, + + props: { + native: Boolean, + wrapStyle: {}, + wrapClass: {}, + viewClass: {}, + viewStyle: {}, + noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能 + tag: { + type: String, + default: 'div' + } + }, + + data() { + return { + sizeWidth: '0', + sizeHeight: '0', + moveX: 0, + moveY: 0 + }; + }, + + computed: { + wrap() { + return this.$refs.wrap; + } + }, + + render(h) { + let gutter = scrollbarWidth(); + let style = this.wrapStyle; + + if (gutter) { + const gutterWith = `-${gutter}px`; + const gutterStyle = `margin-bottom: ${gutterWith}; margin-right: ${gutterWith};`; + + if (Array.isArray(this.wrapStyle)) { + style = toObject(this.wrapStyle); + style.marginRight = style.marginBottom = gutterWith; + } else if (typeof this.wrapStyle === 'string') { + style += gutterStyle; + } else { + style = gutterStyle; + } + } + const view = h(this.tag, { + class: ['el-scrollbar__view', this.viewClass], + style: this.viewStyle, + ref: 'resize' + }, this.$slots.default); + const wrap = ( +
+ { [view] } +
+ ); + let nodes; + + if (!this.native) { + nodes = ([ + wrap, + , + + ]); + } else { + nodes = ([ +
+ { [view] } +
+ ]); + } + return h('div', { class: 'el-scrollbar' }, nodes); + }, + + methods: { + handleScroll() { + const wrap = this.wrap; + + this.moveY = ((wrap.scrollTop * 100) / wrap.clientHeight); + this.moveX = ((wrap.scrollLeft * 100) / wrap.clientWidth); + }, + + update() { + let heightPercentage, widthPercentage; + const wrap = this.wrap; + if (!wrap) return; + + heightPercentage = (wrap.clientHeight * 100 / wrap.scrollHeight); + widthPercentage = (wrap.clientWidth * 100 / wrap.scrollWidth); + + this.sizeHeight = (heightPercentage < 100) ? (heightPercentage + '%') : ''; + this.sizeWidth = (widthPercentage < 100) ? (widthPercentage + '%') : ''; + } + }, + + mounted() { + if (this.native) return; + this.$nextTick(this.update); + !this.noresize && addResizeListener(this.$refs.resize, this.update); + }, + + beforeDestroy() { + if (this.native) return; + !this.noresize && removeResizeListener(this.$refs.resize, this.update); + } +}; diff --git a/packages/scrollbar/src/util.js b/packages/scrollbar/src/util.js new file mode 100644 index 0000000..9dfbf38 --- /dev/null +++ b/packages/scrollbar/src/util.js @@ -0,0 +1,34 @@ +export const BAR_MAP = { + vertical: { + offset: 'offsetHeight', + scroll: 'scrollTop', + scrollSize: 'scrollHeight', + size: 'height', + key: 'vertical', + axis: 'Y', + client: 'clientY', + direction: 'top' + }, + horizontal: { + offset: 'offsetWidth', + scroll: 'scrollLeft', + scrollSize: 'scrollWidth', + size: 'width', + key: 'horizontal', + axis: 'X', + client: 'clientX', + direction: 'left' + } +}; + +export function renderThumbStyle({ move, size, bar }) { + const style = {}; + const translate = `translate${bar.axis}(${ move }%)`; + + style[bar.size] = size; + style.transform = translate; + style.msTransform = translate; + style.webkitTransform = translate; + + return style; +}; diff --git a/packages/select/index.js b/packages/select/index.js new file mode 100644 index 0000000..8c410b7 --- /dev/null +++ b/packages/select/index.js @@ -0,0 +1,8 @@ +import Select from './src/select'; + +/* istanbul ignore next */ +Select.install = function(Vue) { + Vue.component(Select.name, Select); +}; + +export default Select; diff --git a/packages/select/src/navigation-mixin.js b/packages/select/src/navigation-mixin.js new file mode 100644 index 0000000..b32490f --- /dev/null +++ b/packages/select/src/navigation-mixin.js @@ -0,0 +1,54 @@ +export default { + data() { + return { + hoverOption: -1 + }; + }, + + computed: { + optionsAllDisabled() { + return this.options.filter(option => option.visible).every(option => option.disabled); + } + }, + + watch: { + hoverIndex(val) { + if (typeof val === 'number' && val > -1) { + this.hoverOption = this.options[val] || {}; + } + this.options.forEach(option => { + option.hover = this.hoverOption === option; + }); + } + }, + + methods: { + navigateOptions(direction) { + if (!this.visible) { + this.visible = true; + return; + } + if (this.options.length === 0 || this.filteredOptionsCount === 0) return; + if (!this.optionsAllDisabled) { + if (direction === 'next') { + this.hoverIndex++; + if (this.hoverIndex === this.options.length) { + this.hoverIndex = 0; + } + } else if (direction === 'prev') { + this.hoverIndex--; + if (this.hoverIndex < 0) { + this.hoverIndex = this.options.length - 1; + } + } + const option = this.options[this.hoverIndex]; + if (option.disabled === true || + option.groupDisabled === true || + !option.visible) { + this.navigateOptions(direction); + } + this.$nextTick(() => this.scrollToOption(this.hoverOption)); + } + } + } +}; diff --git a/packages/select/src/option-group.vue b/packages/select/src/option-group.vue new file mode 100644 index 0000000..50cddd3 --- /dev/null +++ b/packages/select/src/option-group.vue @@ -0,0 +1,60 @@ + + + diff --git a/packages/select/src/option.vue b/packages/select/src/option.vue new file mode 100644 index 0000000..a343b5b --- /dev/null +++ b/packages/select/src/option.vue @@ -0,0 +1,168 @@ + + + diff --git a/packages/select/src/select-dropdown.vue b/packages/select/src/select-dropdown.vue new file mode 100644 index 0000000..39e4d80 --- /dev/null +++ b/packages/select/src/select-dropdown.vue @@ -0,0 +1,74 @@ + + + diff --git a/packages/select/src/select.vue b/packages/select/src/select.vue new file mode 100644 index 0000000..af8be35 --- /dev/null +++ b/packages/select/src/select.vue @@ -0,0 +1,892 @@ + + + diff --git a/packages/slider/index.js b/packages/slider/index.js new file mode 100644 index 0000000..9374fc4 --- /dev/null +++ b/packages/slider/index.js @@ -0,0 +1,8 @@ +import Slider from './src/main'; + +/* istanbul ignore next */ +Slider.install = function(Vue) { + Vue.component(Slider.name, Slider); +}; + +export default Slider; diff --git a/packages/slider/src/button.vue b/packages/slider/src/button.vue new file mode 100644 index 0000000..5dfa438 --- /dev/null +++ b/packages/slider/src/button.vue @@ -0,0 +1,238 @@ + + + diff --git a/packages/slider/src/main.vue b/packages/slider/src/main.vue new file mode 100644 index 0000000..68d00ad --- /dev/null +++ b/packages/slider/src/main.vue @@ -0,0 +1,427 @@ + + + diff --git a/packages/slider/src/marker.js b/packages/slider/src/marker.js new file mode 100644 index 0000000..2d5f91c --- /dev/null +++ b/packages/slider/src/marker.js @@ -0,0 +1,18 @@ +export default { + name: 'ElMarker', + + props: { + mark: { + type: [String, Object] + } + }, + render() { + let label = typeof this.mark === 'string' ? this.mark : this.mark.label; + + return ( +
+ { label } +
+ ); + } +}; diff --git a/packages/spinner/index.js b/packages/spinner/index.js new file mode 100644 index 0000000..65f8821 --- /dev/null +++ b/packages/spinner/index.js @@ -0,0 +1,8 @@ +import Spinner from './src/spinner'; + +/* istanbul ignore next */ +Spinner.install = function(Vue) { + Vue.component(Spinner.name, Spinner); +}; + +export default Spinner; diff --git a/packages/spinner/src/spinner.vue b/packages/spinner/src/spinner.vue new file mode 100644 index 0000000..2597d11 --- /dev/null +++ b/packages/spinner/src/spinner.vue @@ -0,0 +1,27 @@ + + diff --git a/packages/step/index.js b/packages/step/index.js new file mode 100644 index 0000000..191f80b --- /dev/null +++ b/packages/step/index.js @@ -0,0 +1,8 @@ +import Step from '../steps/src/step'; + +/* istanbul ignore next */ +Step.install = function(Vue) { + Vue.component(Step.name, Step); +}; + +export default Step; diff --git a/packages/steps/README.md b/packages/steps/README.md new file mode 100644 index 0000000..8cc7334 --- /dev/null +++ b/packages/steps/README.md @@ -0,0 +1,69 @@ +# element-steps +> A element-steps component for Vue.js. + +## Demo +http://element-component.github.io/element-steps + +## Installation +```shell +npm i element-steps -D +``` + +## Usage +```javascript +import Vue from 'vue' +import ElStep from 'element-steps' +import 'element-theme-chalk/dist/step.css' + +Vue.use(ElStep) +``` + +or + +```javascript +import Vue from 'vue' +import { ElSteps, ElStep } from 'element-steps' + +Vue.component('el-steps', ElSteps) +Vue.component('el-step', ElStep) +``` + +### Steps Attributes + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | +|---------- |-------- |---------- |------------- |-------- | +| space | 每个 step 的间距,不填写将自适应间距 | Number | — | — | +| direction | 显示方向 | string | vertical/horizontal | horizontal | +| active | 设置当前激活步骤 | number | — | 0 | +| process-status | 设置当前步骤的状态 | string | wait/process/finish/error/success | process | +| finish-status | 设置结束步骤的状态 | string | wait/process/finish/error/success | finish | +| align-center | 标题描述居中对齐 | boolean | - | false | + +### Step Attributes +| 参数 | 说明 | 类型 | 可选值 | 默认值 | +|---------- |-------- |---------- |------------- |-------- | +| title | 标题 | string | — | — | +| description | 描述性文字 | string | — | — | +| icon | 图标 | Element Icon 提供的图标,如果要使用自定义图标可以通过 slot 方式写入 | string | — | + +### Step Slot +| name | 说明 | +|----|----| +| icon | 图标 | +| title | 标题 | +| description | 描述性文字 | + + +## Development +```shell +make dev + +## test +make test + +## build +make build +``` + +# License +[MIT](https://opensource.org/licenses/MIT) diff --git a/packages/steps/index.js b/packages/steps/index.js new file mode 100644 index 0000000..4d630c0 --- /dev/null +++ b/packages/steps/index.js @@ -0,0 +1,8 @@ +import Steps from './src/steps'; + +/* istanbul ignore next */ +Steps.install = function(Vue) { + Vue.component(Steps.name, Steps); +}; + +export default Steps; diff --git a/packages/steps/src/step.vue b/packages/steps/src/step.vue new file mode 100644 index 0000000..bd5eb92 --- /dev/null +++ b/packages/steps/src/step.vue @@ -0,0 +1,184 @@ + + + diff --git a/packages/steps/src/steps.vue b/packages/steps/src/steps.vue new file mode 100644 index 0000000..c6d0657 --- /dev/null +++ b/packages/steps/src/steps.vue @@ -0,0 +1,68 @@ + + + diff --git a/packages/submenu/index.js b/packages/submenu/index.js new file mode 100644 index 0000000..0183785 --- /dev/null +++ b/packages/submenu/index.js @@ -0,0 +1,8 @@ +import ElSubmenu from '../menu/src/submenu'; + +/* istanbul ignore next */ +ElSubmenu.install = function(Vue) { + Vue.component(ElSubmenu.name, ElSubmenu); +}; + +export default ElSubmenu; diff --git a/packages/switch/index.js b/packages/switch/index.js new file mode 100644 index 0000000..d092884 --- /dev/null +++ b/packages/switch/index.js @@ -0,0 +1,9 @@ +import Switch from './src/component'; + +/* istanbul ignore next */ +Switch.install = function(Vue) { + Vue.component(Switch.name, Switch); +}; + +export default Switch; + diff --git a/packages/switch/src/component.vue b/packages/switch/src/component.vue new file mode 100644 index 0000000..88c5483 --- /dev/null +++ b/packages/switch/src/component.vue @@ -0,0 +1,172 @@ + + diff --git a/packages/tab-pane/index.js b/packages/tab-pane/index.js new file mode 100644 index 0000000..30500ba --- /dev/null +++ b/packages/tab-pane/index.js @@ -0,0 +1,8 @@ +import TabPane from '../tabs/src/tab-pane.vue'; + +/* istanbul ignore next */ +TabPane.install = function(Vue) { + Vue.component(TabPane.name, TabPane); +}; + +export default TabPane; diff --git a/packages/table-column/index.js b/packages/table-column/index.js new file mode 100644 index 0000000..2f41ce1 --- /dev/null +++ b/packages/table-column/index.js @@ -0,0 +1,8 @@ +import ElTableColumn from '../table/src/table-column'; + +/* istanbul ignore next */ +ElTableColumn.install = function(Vue) { + Vue.component(ElTableColumn.name, ElTableColumn); +}; + +export default ElTableColumn; diff --git a/packages/table/index.js b/packages/table/index.js new file mode 100644 index 0000000..1b577b3 --- /dev/null +++ b/packages/table/index.js @@ -0,0 +1,8 @@ +import ElTable from './src/table'; + +/* istanbul ignore next */ +ElTable.install = function(Vue) { + Vue.component(ElTable.name, ElTable); +}; + +export default ElTable; diff --git a/packages/table/src/config.js b/packages/table/src/config.js new file mode 100644 index 0000000..ba705ac --- /dev/null +++ b/packages/table/src/config.js @@ -0,0 +1,123 @@ +import { getPropByPath } from 'element-ui/src/utils/util'; + +export const cellStarts = { + default: { + order: '' + }, + selection: { + width: 48, + minWidth: 48, + realWidth: 48, + order: '', + className: 'el-table-column--selection' + }, + expand: { + width: 48, + minWidth: 48, + realWidth: 48, + order: '' + }, + index: { + width: 48, + minWidth: 48, + realWidth: 48, + order: '' + } +}; + +// 这些选项不应该被覆盖 +export const cellForced = { + selection: { + renderHeader: function(h, { store }) { + return 0 && !this.isAllSelected } + nativeOn-click={ this.toggleAllSelection } + value={ this.isAllSelected } />; + }, + renderCell: function(h, { row, column, store, $index }) { + return event.stopPropagation() } + value={ store.isSelected(row) } + disabled={ column.selectable ? !column.selectable.call(null, row, $index) : false } + on-input={ () => { store.commit('rowSelectedChanged', row); } } />; + }, + sortable: false, + resizable: false + }, + index: { + renderHeader: function(h, { column }) { + return column.label || '#'; + }, + renderCell: function(h, { $index, column }) { + let i = $index + 1; + const index = column.index; + + if (typeof index === 'number') { + i = $index + index; + } else if (typeof index === 'function') { + i = index($index); + } + + return
{ i }
; + }, + sortable: false + }, + expand: { + renderHeader: function(h, { column }) { + return column.label || ''; + }, + renderCell: function(h, { row, store }) { + const classes = ['el-table__expand-icon']; + if (store.states.expandRows.indexOf(row) > -1) { + classes.push('el-table__expand-icon--expanded'); + } + const callback = function(e) { + e.stopPropagation(); + store.toggleRowExpansion(row); + }; + return (
+ +
); + }, + sortable: false, + resizable: false, + className: 'el-table__expand-column' + } +}; + +export function defaultRenderCell(h, { row, column, $index }) { + const property = column.property; + const value = property && getPropByPath(row, property).v; + if (column && column.formatter) { + return column.formatter(row, column, value, $index); + } + return value; +} + +export function treeCellPrefix(h, { row, treeNode, store }) { + if (!treeNode) return null; + const ele = []; + const callback = function(e) { + e.stopPropagation(); + store.loadOrToggle(row); + }; + if (treeNode.indent) { + ele.push(); + } + if (typeof treeNode.expanded === 'boolean' && !treeNode.noLazyChildren) { + const expandClasses = ['el-table__expand-icon', treeNode.expanded ? 'el-table__expand-icon--expanded' : '']; + let iconClasses = ['el-icon-arrow-right']; + if (treeNode.loading) { + iconClasses = ['el-icon-loading']; + } + ele.push(
+ +
); + } else { + ele.push(); + } + return ele; +} diff --git a/packages/table/src/dropdown.js b/packages/table/src/dropdown.js new file mode 100644 index 0000000..37d2b9c --- /dev/null +++ b/packages/table/src/dropdown.js @@ -0,0 +1,28 @@ +import Vue from 'vue'; +var dropdowns = []; + +!Vue.prototype.$isServer && document.addEventListener('click', function(event) { + dropdowns.forEach(function(dropdown) { + var target = event.target; + if (!dropdown || !dropdown.$el) return; + if (target === dropdown.$el || dropdown.$el.contains(target)) { + return; + } + dropdown.handleOutsideClick && dropdown.handleOutsideClick(event); + }); +}); + +export default { + open(instance) { + if (instance) { + dropdowns.push(instance); + } + }, + + close(instance) { + var index = dropdowns.indexOf(instance); + if (index !== -1) { + dropdowns.splice(instance, 1); + } + } +}; diff --git a/packages/table/src/filter-panel.vue b/packages/table/src/filter-panel.vue new file mode 100644 index 0000000..3220d6d --- /dev/null +++ b/packages/table/src/filter-panel.vue @@ -0,0 +1,194 @@ + + + diff --git a/packages/table/src/layout-observer.js b/packages/table/src/layout-observer.js new file mode 100644 index 0000000..605a0f2 --- /dev/null +++ b/packages/table/src/layout-observer.js @@ -0,0 +1,68 @@ +export default { + created() { + this.tableLayout.addObserver(this); + }, + + destroyed() { + this.tableLayout.removeObserver(this); + }, + + computed: { + tableLayout() { + let layout = this.layout; + if (!layout && this.table) { + layout = this.table.layout; + } + if (!layout) { + throw new Error('Can not find table layout.'); + } + return layout; + } + }, + + mounted() { + this.onColumnsChange(this.tableLayout); + this.onScrollableChange(this.tableLayout); + }, + + updated() { + if (this.__updated__) return; + this.onColumnsChange(this.tableLayout); + this.onScrollableChange(this.tableLayout); + this.__updated__ = true; + }, + + methods: { + onColumnsChange(layout) { + const cols = this.$el.querySelectorAll('colgroup > col'); + if (!cols.length) return; + const flattenColumns = layout.getFlattenColumns(); + const columnsMap = {}; + flattenColumns.forEach((column) => { + columnsMap[column.id] = column; + }); + for (let i = 0, j = cols.length; i < j; i++) { + const col = cols[i]; + const name = col.getAttribute('name'); + const column = columnsMap[name]; + if (column) { + col.setAttribute('width', column.realWidth || column.width); + } + } + }, + + onScrollableChange(layout) { + const cols = this.$el.querySelectorAll('colgroup > col[name=gutter]'); + for (let i = 0, j = cols.length; i < j; i++) { + const col = cols[i]; + col.setAttribute('width', layout.scrollY ? layout.gutterWidth : '0'); + } + const ths = this.$el.querySelectorAll('th.gutter'); + for (let i = 0, j = ths.length; i < j; i++) { + const th = ths[i]; + th.style.width = layout.scrollY ? layout.gutterWidth + 'px' : '0'; + th.style.display = layout.scrollY ? '' : 'none'; + } + } + } +}; diff --git a/packages/table/src/store/current.js b/packages/table/src/store/current.js new file mode 100644 index 0000000..19e31ff --- /dev/null +++ b/packages/table/src/store/current.js @@ -0,0 +1,76 @@ +import { arrayFind } from 'element-ui/src/utils/util'; +import { getRowIdentity } from '../util'; + +export default { + data() { + return { + states: { + // 不可响应的,设置 currentRowKey 时,data 不一定存在,也许无法算出正确的 currentRow + // 把该值缓存一下,当用户点击修改 currentRow 时,把该值重置为 null + _currentRowKey: null, + currentRow: null + } + }; + }, + + methods: { + setCurrentRowKey(key) { + this.assertRowKey(); + this.states._currentRowKey = key; + this.setCurrentRowByKey(key); + }, + + restoreCurrentRowKey() { + this.states._currentRowKey = null; + }, + + setCurrentRowByKey(key) { + const { states } = this; + const { data = [], rowKey } = states; + let currentRow = null; + if (rowKey) { + currentRow = arrayFind(data, item => getRowIdentity(item, rowKey) === key); + } + states.currentRow = currentRow; + }, + + updateCurrentRow(currentRow) { + const { states, table } = this; + const oldCurrentRow = states.currentRow; + if (currentRow && currentRow !== oldCurrentRow) { + states.currentRow = currentRow; + table.$emit('current-change', currentRow, oldCurrentRow); + return; + } + if (!currentRow && oldCurrentRow) { + states.currentRow = null; + table.$emit('current-change', null, oldCurrentRow); + } + }, + + updateCurrentRowData() { + const { states, table } = this; + const { rowKey, _currentRowKey } = states; + // data 为 null 时,解构时的默认值会被忽略 + const data = states.data || []; + const oldCurrentRow = states.currentRow; + + // 当 currentRow 不在 data 中时尝试更新数据 + if (data.indexOf(oldCurrentRow) === -1 && oldCurrentRow) { + if (rowKey) { + const currentRowKey = getRowIdentity(oldCurrentRow, rowKey); + this.setCurrentRowByKey(currentRowKey); + } else { + states.currentRow = null; + } + if (states.currentRow === null) { + table.$emit('current-change', null, oldCurrentRow); + } + } else if (_currentRowKey) { + // 把初始时下设置的 rowKey 转化成 rowData + this.setCurrentRowByKey(_currentRowKey); + this.restoreCurrentRowKey(); + } + } + } +}; diff --git a/packages/table/src/store/expand.js b/packages/table/src/store/expand.js new file mode 100644 index 0000000..65b7ce8 --- /dev/null +++ b/packages/table/src/store/expand.js @@ -0,0 +1,65 @@ +import { toggleRowStatus, getKeysMap, getRowIdentity } from '../util'; + +export default { + data() { + return { + states: { + defaultExpandAll: false, + expandRows: [] + } + }; + }, + + methods: { + updateExpandRows() { + const { data = [], rowKey, defaultExpandAll, expandRows } = this.states; + if (defaultExpandAll) { + this.states.expandRows = data.slice(); + } else if (rowKey) { + // TODO:这里的代码可以优化 + const expandRowsMap = getKeysMap(expandRows, rowKey); + this.states.expandRows = data.reduce((prev, row) => { + const rowId = getRowIdentity(row, rowKey); + const rowInfo = expandRowsMap[rowId]; + if (rowInfo) { + prev.push(row); + } + return prev; + }, []); + } else { + this.states.expandRows = []; + } + }, + + toggleRowExpansion(row, expanded) { + const changed = toggleRowStatus(this.states.expandRows, row, expanded); + if (changed) { + this.table.$emit('expand-change', row, this.states.expandRows.slice()); + this.scheduleLayout(); + } + }, + + setExpandRowKeys(rowKeys) { + this.assertRowKey(); + // TODO:这里的代码可以优化 + const { data, rowKey } = this.states; + const keysMap = getKeysMap(data, rowKey); + this.states.expandRows = rowKeys.reduce((prev, cur) => { + const info = keysMap[cur]; + if (info) { + prev.push(info.row); + } + return prev; + }, []); + }, + + isRowExpanded(row) { + const { expandRows = [], rowKey } = this.states; + if (rowKey) { + const expandMap = getKeysMap(expandRows, rowKey); + return !!expandMap[getRowIdentity(row, rowKey)]; + } + return expandRows.indexOf(row) !== -1; + } + } +}; diff --git a/packages/table/src/store/helper.js b/packages/table/src/store/helper.js new file mode 100644 index 0000000..b27ee89 --- /dev/null +++ b/packages/table/src/store/helper.js @@ -0,0 +1,41 @@ +import Store from './index'; +import debounce from 'throttle-debounce/debounce'; + +export function createStore(table, initialState = {}) { + if (!table) { + throw new Error('Table is required.'); + } + + const store = new Store(); + store.table = table; + // fix https://github.com/ElemeFE/element/issues/14075 + // related pr https://github.com/ElemeFE/element/pull/14146 + store.toggleAllSelection = debounce(10, store._toggleAllSelection); + Object.keys(initialState).forEach(key => { + store.states[key] = initialState[key]; + }); + return store; +} + +export function mapStates(mapper) { + const res = {}; + Object.keys(mapper).forEach(key => { + const value = mapper[key]; + let fn; + if (typeof value === 'string') { + fn = function() { + return this.store.states[value]; + }; + } else if (typeof value === 'function') { + fn = function() { + return value.call(this, this.store.states); + }; + } else { + console.error('invalid value type'); + } + if (fn) { + res[key] = fn; + } + }); + return res; +}; diff --git a/packages/table/src/store/index.js b/packages/table/src/store/index.js new file mode 100644 index 0000000..0bf4936 --- /dev/null +++ b/packages/table/src/store/index.js @@ -0,0 +1,147 @@ +import Vue from 'vue'; +import Watcher from './watcher'; +import { arrayFind } from 'element-ui/src/utils/util'; + +Watcher.prototype.mutations = { + setData(states, data) { + const dataInstanceChanged = states._data !== data; + states._data = data; + + this.execQuery(); + // 数据变化,更新部分数据。 + // 没有使用 computed,而是手动更新部分数据 https://github.com/vuejs/vue/issues/6660#issuecomment-331417140 + this.updateCurrentRowData(); + this.updateExpandRows(); + if (states.reserveSelection) { + this.assertRowKey(); + this.updateSelectionByRowKey(); + } else { + if (dataInstanceChanged) { + this.clearSelection(); + } else { + this.cleanSelection(); + } + } + this.updateAllSelected(); + + this.updateTableScrollY(); + }, + + insertColumn(states, column, index, parent) { + let array = states._columns; + if (parent) { + array = parent.children; + if (!array) array = parent.children = []; + } + + if (typeof index !== 'undefined') { + array.splice(index, 0, column); + } else { + array.push(column); + } + + if (column.type === 'selection') { + states.selectable = column.selectable; + states.reserveSelection = column.reserveSelection; + } + + if (this.table.$ready) { + this.updateColumns(); // hack for dynamics insert column + this.scheduleLayout(); + } + }, + + removeColumn(states, column, parent) { + let array = states._columns; + if (parent) { + array = parent.children; + if (!array) array = parent.children = []; + } + if (array) { + array.splice(array.indexOf(column), 1); + } + + if (this.table.$ready) { + this.updateColumns(); // hack for dynamics remove column + this.scheduleLayout(); + } + }, + + sort(states, options) { + const { prop, order, init } = options; + if (prop) { + const column = arrayFind(states.columns, column => column.property === prop); + if (column) { + column.order = order; + this.updateSort(column, prop, order); + this.commit('changeSortCondition', { init }); + } + } + }, + + changeSortCondition(states, options) { + // 修复 pr https://github.com/ElemeFE/element/pull/15012 导致的 bug + const { sortingColumn: column, sortProp: prop, sortOrder: order } = states; + if (order === null) { + states.sortingColumn = null; + states.sortProp = null; + } + const ingore = { filter: true }; + this.execQuery(ingore); + + if (!options || !(options.silent || options.init)) { + this.table.$emit('sort-change', { + column, + prop, + order + }); + } + + this.updateTableScrollY(); + }, + + filterChange(states, options) { + let { column, values, silent } = options; + const newFilters = this.updateFilters(column, values); + + this.execQuery(); + + if (!silent) { + this.table.$emit('filter-change', newFilters); + } + + this.updateTableScrollY(); + }, + + toggleAllSelection() { + this.toggleAllSelection(); + }, + + rowSelectedChanged(states, row) { + this.toggleRowSelection(row); + this.updateAllSelected(); + }, + + setHoverRow(states, row) { + states.hoverRow = row; + }, + + setCurrentRow(states, row) { + this.updateCurrentRow(row); + } +}; + +Watcher.prototype.commit = function(name, ...args) { + const mutations = this.mutations; + if (mutations[name]) { + mutations[name].apply(this, [this.states].concat(args)); + } else { + throw new Error(`Action not found: ${name}`); + } +}; + +Watcher.prototype.updateTableScrollY = function() { + Vue.nextTick(this.table.updateScrollY); +}; + +export default Watcher; diff --git a/packages/table/src/store/tree.js b/packages/table/src/store/tree.js new file mode 100644 index 0000000..7558588 --- /dev/null +++ b/packages/table/src/store/tree.js @@ -0,0 +1,208 @@ +import { walkTreeNode, getRowIdentity } from '../util'; + +export default { + data() { + return { + states: { + // defaultExpandAll 存在于 expand.js 中,这里不重复添加 + // 在展开行中,expandRowKeys 会被转化成 expandRows,expandRowKeys 这个属性只是记录了 TreeTable 行的展开 + // TODO: 拆分为独立的 TreeTable,统一用法 + expandRowKeys: [], + treeData: {}, + indent: 16, + lazy: false, + lazyTreeNodeMap: {}, + lazyColumnIdentifier: 'hasChildren', + childrenColumnName: 'children' + } + }; + }, + + computed: { + // 嵌入型的数据,watch 无法是检测到变化 https://github.com/ElemeFE/element/issues/14998 + // TODO: 使用 computed 解决该问题,是否会造成性能问题? + // @return { id: { level, children } } + normalizedData() { + if (!this.states.rowKey) return {}; + const data = this.states.data || []; + return this.normalize(data); + }, + // @return { id: { children } } + // 针对懒加载的情形,不处理嵌套数据 + normalizedLazyNode() { + const { rowKey, lazyTreeNodeMap, lazyColumnIdentifier } = this.states; + const keys = Object.keys(lazyTreeNodeMap); + const res = {}; + if (!keys.length) return res; + keys.forEach(key => { + if (lazyTreeNodeMap[key].length) { + const item = { children: [] }; + lazyTreeNodeMap[key].forEach(row => { + const currentRowKey = getRowIdentity(row, rowKey); + item.children.push(currentRowKey); + if (row[lazyColumnIdentifier] && !res[currentRowKey]) { + res[currentRowKey] = { children: [] }; + } + }); + res[key] = item; + } + }); + return res; + } + }, + + watch: { + normalizedData: 'updateTreeData', + normalizedLazyNode: 'updateTreeData' + }, + + methods: { + normalize(data) { + const { + childrenColumnName, + lazyColumnIdentifier, + rowKey, + lazy + } = this.states; + const res = {}; + walkTreeNode( + data, + (parent, children, level) => { + const parentId = getRowIdentity(parent, rowKey); + if (Array.isArray(children)) { + res[parentId] = { + children: children.map(row => getRowIdentity(row, rowKey)), + level + }; + } else if (lazy) { + // 当 children 不存在且 lazy 为 true,该节点即为懒加载的节点 + res[parentId] = { + children: [], + lazy: true, + level + }; + } + }, + childrenColumnName, + lazyColumnIdentifier + ); + return res; + }, + + updateTreeData() { + const nested = this.normalizedData; + const normalizedLazyNode = this.normalizedLazyNode; + const keys = Object.keys(nested); + const newTreeData = {}; + if (keys.length) { + const { + treeData: oldTreeData, + defaultExpandAll, + expandRowKeys, + lazy + } = this.states; + const rootLazyRowKeys = []; + const getExpanded = (oldValue, key) => { + const included = + defaultExpandAll || + (expandRowKeys && expandRowKeys.indexOf(key) !== -1); + return !!((oldValue && oldValue.expanded) || included); + }; + // 合并 expanded 与 display,确保数据刷新后,状态不变 + keys.forEach(key => { + const oldValue = oldTreeData[key]; + const newValue = { ...nested[key] }; + newValue.expanded = getExpanded(oldValue, key); + if (newValue.lazy) { + const { loaded = false, loading = false } = oldValue || {}; + newValue.loaded = !!loaded; + newValue.loading = !!loading; + rootLazyRowKeys.push(key); + } + newTreeData[key] = newValue; + }); + // 根据懒加载数据更新 treeData + const lazyKeys = Object.keys(normalizedLazyNode); + if (lazy && lazyKeys.length && rootLazyRowKeys.length) { + lazyKeys.forEach(key => { + const oldValue = oldTreeData[key]; + const lazyNodeChildren = normalizedLazyNode[key].children; + if (rootLazyRowKeys.indexOf(key) !== -1) { + // 懒加载的 root 节点,更新一下原有的数据,原来的 children 一定是空数组 + if (newTreeData[key].children.length !== 0) { + throw new Error('[ElTable]children must be an empty array.'); + } + newTreeData[key].children = lazyNodeChildren; + } else { + const { loaded = false, loading = false } = oldValue || {}; + newTreeData[key] = { + lazy: true, + loaded: !!loaded, + loading: !!loading, + expanded: getExpanded(oldValue, key), + children: lazyNodeChildren, + level: '' + }; + } + }); + } + } + this.states.treeData = newTreeData; + this.updateTableScrollY(); + }, + + updateTreeExpandKeys(value) { + this.states.expandRowKeys = value; + this.updateTreeData(); + }, + + toggleTreeExpansion(row, expanded) { + this.assertRowKey(); + + const { rowKey, treeData } = this.states; + const id = getRowIdentity(row, rowKey); + const data = id && treeData[id]; + if (id && data && ('expanded' in data)) { + const oldExpanded = data.expanded; + expanded = typeof expanded === 'undefined' ? !data.expanded : expanded; + treeData[id].expanded = expanded; + if (oldExpanded !== expanded) { + this.table.$emit('expand-change', row, expanded); + } + this.updateTableScrollY(); + } + }, + + loadOrToggle(row) { + this.assertRowKey(); + const { lazy, treeData, rowKey } = this.states; + const id = getRowIdentity(row, rowKey); + const data = treeData[id]; + if (lazy && data && 'loaded' in data && !data.loaded) { + this.loadData(row, id, data); + } else { + this.toggleTreeExpansion(row); + } + }, + + loadData(row, key, treeNode) { + const { load } = this.table; + const { lazyTreeNodeMap, treeData } = this.states; + if (load && !treeData[key].loaded) { + treeData[key].loading = true; + load(row, treeNode, data => { + if (!Array.isArray(data)) { + throw new Error('[ElTable] data must be an array'); + } + treeData[key].loading = false; + treeData[key].loaded = true; + treeData[key].expanded = true; + if (data.length) { + this.$set(lazyTreeNodeMap, key, data); + } + this.table.$emit('expand-change', row, true); + }); + } + } + } +}; diff --git a/packages/table/src/store/watcher.js b/packages/table/src/store/watcher.js new file mode 100644 index 0000000..fa13bdc --- /dev/null +++ b/packages/table/src/store/watcher.js @@ -0,0 +1,381 @@ +import Vue from 'vue'; +import merge from 'element-ui/src/utils/merge'; +import { getKeysMap, getRowIdentity, getColumnById, getColumnByKey, orderBy, toggleRowStatus } from '../util'; +import expand from './expand'; +import current from './current'; +import tree from './tree'; + +const sortData = (data, states) => { + const sortingColumn = states.sortingColumn; + if (!sortingColumn || typeof sortingColumn.sortable === 'string') { + return data; + } + return orderBy(data, states.sortProp, states.sortOrder, sortingColumn.sortMethod, sortingColumn.sortBy); +}; + +const doFlattenColumns = (columns) => { + const result = []; + columns.forEach((column) => { + if (column.children) { + result.push.apply(result, doFlattenColumns(column.children)); + } else { + result.push(column); + } + }); + return result; +}; + +export default Vue.extend({ + data() { + return { + states: { + // 3.0 版本后要求必须设置该属性 + rowKey: null, + + // 渲染的数据来源,是对 table 中的 data 过滤排序后的结果 + data: [], + + // 是否包含固定列 + isComplex: false, + + // 列 + _columns: [], // 不可响应的 + originColumns: [], + columns: [], + fixedColumns: [], + rightFixedColumns: [], + leafColumns: [], + fixedLeafColumns: [], + rightFixedLeafColumns: [], + leafColumnsLength: 0, + fixedLeafColumnsLength: 0, + rightFixedLeafColumnsLength: 0, + + // 选择 + isAllSelected: false, + selection: [], + reserveSelection: false, + selectOnIndeterminate: false, + selectable: null, + + // 过滤 + filters: {}, // 不可响应的 + filteredData: null, + + // 排序 + sortingColumn: null, + sortProp: null, + sortOrder: null, + + hoverRow: null + } + }; + }, + + mixins: [expand, current, tree], + + methods: { + // 检查 rowKey 是否存在 + assertRowKey() { + const rowKey = this.states.rowKey; + if (!rowKey) throw new Error('[ElTable] prop row-key is required'); + }, + + // 更新列 + updateColumns() { + const states = this.states; + const _columns = states._columns || []; + states.fixedColumns = _columns.filter((column) => column.fixed === true || column.fixed === 'left'); + states.rightFixedColumns = _columns.filter((column) => column.fixed === 'right'); + + if (states.fixedColumns.length > 0 && _columns[0] && _columns[0].type === 'selection' && !_columns[0].fixed) { + _columns[0].fixed = true; + states.fixedColumns.unshift(_columns[0]); + } + + const notFixedColumns = _columns.filter(column => !column.fixed); + states.originColumns = [].concat(states.fixedColumns).concat(notFixedColumns).concat(states.rightFixedColumns); + + const leafColumns = doFlattenColumns(notFixedColumns); + const fixedLeafColumns = doFlattenColumns(states.fixedColumns); + const rightFixedLeafColumns = doFlattenColumns(states.rightFixedColumns); + + states.leafColumnsLength = leafColumns.length; + states.fixedLeafColumnsLength = fixedLeafColumns.length; + states.rightFixedLeafColumnsLength = rightFixedLeafColumns.length; + + states.columns = [].concat(fixedLeafColumns).concat(leafColumns).concat(rightFixedLeafColumns); + states.isComplex = states.fixedColumns.length > 0 || states.rightFixedColumns.length > 0; + }, + + // 更新 DOM + scheduleLayout(needUpdateColumns) { + if (needUpdateColumns) { + this.updateColumns(); + } + this.table.debouncedUpdateLayout(); + }, + + // 选择 + isSelected(row) { + const { selection = [] } = this.states; + return selection.indexOf(row) > -1; + }, + + clearSelection() { + const states = this.states; + states.isAllSelected = false; + const oldSelection = states.selection; + if (oldSelection.length) { + states.selection = []; + this.table.$emit('selection-change', []); + } + }, + + cleanSelection() { + const states = this.states; + const { data, rowKey, selection } = states; + let deleted; + if (rowKey) { + deleted = []; + const selectedMap = getKeysMap(selection, rowKey); + const dataMap = getKeysMap(data, rowKey); + for (let key in selectedMap) { + if (selectedMap.hasOwnProperty(key) && !dataMap[key]) { + deleted.push(selectedMap[key].row); + } + } + } else { + deleted = selection.filter(item => data.indexOf(item) === -1); + } + if (deleted.length) { + const newSelection = selection.filter(item => deleted.indexOf(item) === -1); + states.selection = newSelection; + this.table.$emit('selection-change', newSelection.slice()); + } + }, + + toggleRowSelection(row, selected, emitChange = true) { + const changed = toggleRowStatus(this.states.selection, row, selected); + if (changed) { + const newSelection = (this.states.selection || []).slice(); + // 调用 API 修改选中值,不触发 select 事件 + if (emitChange) { + this.table.$emit('select', newSelection, row); + } + this.table.$emit('selection-change', newSelection); + } + }, + + _toggleAllSelection() { + const states = this.states; + const { data = [], selection } = states; + // when only some rows are selected (but not all), select or deselect all of them + // depending on the value of selectOnIndeterminate + const value = states.selectOnIndeterminate + ? !states.isAllSelected + : !(states.isAllSelected || selection.length); + states.isAllSelected = value; + + let selectionChanged = false; + data.forEach((row, index) => { + if (states.selectable) { + if (states.selectable.call(null, row, index) && toggleRowStatus(selection, row, value)) { + selectionChanged = true; + } + } else { + if (toggleRowStatus(selection, row, value)) { + selectionChanged = true; + } + } + }); + + if (selectionChanged) { + this.table.$emit('selection-change', selection ? selection.slice() : []); + } + this.table.$emit('select-all', selection); + }, + + updateSelectionByRowKey() { + const states = this.states; + const { selection, rowKey, data } = states; + const selectedMap = getKeysMap(selection, rowKey); + data.forEach(row => { + const rowId = getRowIdentity(row, rowKey); + const rowInfo = selectedMap[rowId]; + if (rowInfo) { + selection[rowInfo.index] = row; + } + }); + }, + + updateAllSelected() { + const states = this.states; + const { selection, rowKey, selectable } = states; + // data 为 null 时,解构时的默认值会被忽略 + const data = states.data || []; + if (data.length === 0) { + states.isAllSelected = false; + return; + } + + let selectedMap; + if (rowKey) { + selectedMap = getKeysMap(selection, rowKey); + } + const isSelected = function(row) { + if (selectedMap) { + return !!selectedMap[getRowIdentity(row, rowKey)]; + } else { + return selection.indexOf(row) !== -1; + } + }; + let isAllSelected = true; + let selectedCount = 0; + for (let i = 0, j = data.length; i < j; i++) { + const item = data[i]; + const isRowSelectable = selectable && selectable.call(null, item, i); + if (!isSelected(item)) { + if (!selectable || isRowSelectable) { + isAllSelected = false; + break; + } + } else { + selectedCount++; + } + } + + if (selectedCount === 0) isAllSelected = false; + states.isAllSelected = isAllSelected; + }, + + // 过滤与排序 + updateFilters(columns, values) { + if (!Array.isArray(columns)) { + columns = [columns]; + } + const states = this.states; + const filters = {}; + columns.forEach(col => { + states.filters[col.id] = values; + filters[col.columnKey || col.id] = values; + }); + + return filters; + }, + + updateSort(column, prop, order) { + if (this.states.sortingColumn && this.states.sortingColumn !== column) { + this.states.sortingColumn.order = null; + } + this.states.sortingColumn = column; + this.states.sortProp = prop; + this.states.sortOrder = order; + }, + + execFilter() { + const states = this.states; + const { _data, filters } = states; + let data = _data; + + Object.keys(filters).forEach((columnId) => { + const values = states.filters[columnId]; + if (!values || values.length === 0) return; + const column = getColumnById(this.states, columnId); + if (column && column.filterMethod) { + data = data.filter((row) => { + return values.some(value => column.filterMethod.call(null, value, row, column)); + }); + } + }); + + states.filteredData = data; + }, + + execSort() { + const states = this.states; + states.data = sortData(states.filteredData, states); + }, + + // 根据 filters 与 sort 去过滤 data + execQuery(ignore) { + if (!(ignore && ignore.filter)) { + this.execFilter(); + } + this.execSort(); + }, + + clearFilter(columnKeys) { + const states = this.states; + const { tableHeader, fixedTableHeader, rightFixedTableHeader } = this.table.$refs; + + let panels = {}; + if (tableHeader) panels = merge(panels, tableHeader.filterPanels); + if (fixedTableHeader) panels = merge(panels, fixedTableHeader.filterPanels); + if (rightFixedTableHeader) panels = merge(panels, rightFixedTableHeader.filterPanels); + + const keys = Object.keys(panels); + if (!keys.length) return; + + if (typeof columnKeys === 'string') { + columnKeys = [columnKeys]; + } + + if (Array.isArray(columnKeys)) { + const columns = columnKeys.map(key => getColumnByKey(states, key)); + keys.forEach(key => { + const column = columns.find(col => col.id === key); + if (column) { + // TODO: 优化这里的代码 + panels[key].filteredValue = []; + } + }); + this.commit('filterChange', { + column: columns, + values: [], + silent: true, + multi: true + }); + } else { + keys.forEach(key => { + // TODO: 优化这里的代码 + panels[key].filteredValue = []; + }); + + states.filters = {}; + this.commit('filterChange', { + column: {}, + values: [], + silent: true + }); + } + }, + + clearSort() { + const states = this.states; + if (!states.sortingColumn) return; + + this.updateSort(null, null, null); + this.commit('changeSortCondition', { + silent: true + }); + }, + + // 适配层,expand-row-keys 在 Expand 与 TreeTable 中都有使用 + setExpandRowKeysAdapter(val) { + // 这里会触发额外的计算,但为了兼容性,暂时这么做 + this.setExpandRowKeys(val); + this.updateTreeExpandKeys(val); + }, + + // 展开行与 TreeTable 都要使用 + toggleRowExpansionAdapter(row, expanded) { + const hasExpandColumn = this.states.columns.some(({ type }) => type === 'expand'); + if (hasExpandColumn) { + this.toggleRowExpansion(row, expanded); + } else { + this.toggleTreeExpansion(row, expanded); + } + } + } +}); diff --git a/packages/table/src/table-body.js b/packages/table/src/table-body.js new file mode 100644 index 0000000..4be819a --- /dev/null +++ b/packages/table/src/table-body.js @@ -0,0 +1,483 @@ +import { arrayFindIndex } from 'element-ui/src/utils/util'; +import { getCell, getColumnByCell, getRowIdentity } from './util'; +import { getStyle, hasClass, removeClass, addClass } from 'element-ui/src/utils/dom'; +import ElCheckbox from 'element-ui/packages/checkbox'; +import ElTooltip from 'element-ui/packages/tooltip'; +import debounce from 'throttle-debounce/debounce'; +import LayoutObserver from './layout-observer'; +import { mapStates } from './store/helper'; + +export default { + name: 'ElTableBody', + + mixins: [LayoutObserver], + + components: { + ElCheckbox, + ElTooltip + }, + + props: { + store: { + required: true + }, + stripe: Boolean, + context: {}, + rowClassName: [String, Function], + rowStyle: [Object, Function], + fixed: String, + highlight: Boolean + }, + + render(h) { + const data = this.data || []; + return ( + + + { + this.columns.map(column => ) + } + + + { + data.reduce((acc, row) => { + return acc.concat(this.wrappedRowRender(row, acc.length)); + }, []) + } + + +
+ ); + }, + + computed: { + table() { + return this.$parent; + }, + + ...mapStates({ + data: 'data', + columns: 'columns', + treeIndent: 'indent', + leftFixedLeafCount: 'fixedLeafColumnsLength', + rightFixedLeafCount: 'rightFixedLeafColumnsLength', + columnsCount: states => states.columns.length, + leftFixedCount: states => states.fixedColumns.length, + rightFixedCount: states => states.rightFixedColumns.length, + hasExpandColumn: states => states.columns.some(({ type }) => type === 'expand') + }), + + firstDefaultColumnIndex() { + return arrayFindIndex(this.columns, ({ type }) => type === 'default'); + } + }, + + watch: { + // don't trigger getter of currentRow in getCellClass. see https://jsfiddle.net/oe2b4hqt/ + // update DOM manually. see https://github.com/ElemeFE/element/pull/13954/files#diff-9b450c00d0a9dec0ffad5a3176972e40 + 'store.states.hoverRow'(newVal, oldVal) { + if (!this.store.states.isComplex || this.$isServer) return; + let raf = window.requestAnimationFrame; + if (!raf) { + raf = (fn) => setTimeout(fn, 16); + } + raf(() => { + const rows = this.$el.querySelectorAll('.el-table__row'); + const oldRow = rows[oldVal]; + const newRow = rows[newVal]; + if (oldRow) { + removeClass(oldRow, 'hover-row'); + } + if (newRow) { + addClass(newRow, 'hover-row'); + } + }); + } + }, + + data() { + return { + tooltipContent: '' + }; + }, + + created() { + this.activateTooltip = debounce(50, tooltip => tooltip.handleShowPopper()); + }, + + methods: { + getKeyOfRow(row, index) { + const rowKey = this.table.rowKey; + if (rowKey) { + return getRowIdentity(row, rowKey); + } + return index; + }, + + isColumnHidden(index) { + if (this.fixed === true || this.fixed === 'left') { + return index >= this.leftFixedLeafCount; + } else if (this.fixed === 'right') { + return index < this.columnsCount - this.rightFixedLeafCount; + } else { + return (index < this.leftFixedLeafCount) || (index >= this.columnsCount - this.rightFixedLeafCount); + } + }, + + getSpan(row, column, rowIndex, columnIndex) { + let rowspan = 1; + let colspan = 1; + const fn = this.table.spanMethod; + if (typeof fn === 'function') { + const result = fn({ + row, + column, + rowIndex, + columnIndex + }); + if (Array.isArray(result)) { + rowspan = result[0]; + colspan = result[1]; + } else if (typeof result === 'object') { + rowspan = result.rowspan; + colspan = result.colspan; + } + } + return { rowspan, colspan }; + }, + + getRowStyle(row, rowIndex) { + const rowStyle = this.table.rowStyle; + if (typeof rowStyle === 'function') { + return rowStyle.call(null, { + row, + rowIndex + }); + } + return rowStyle || null; + }, + + getRowClass(row, rowIndex) { + const classes = ['el-table__row']; + if (this.table.highlightCurrentRow && row === this.store.states.currentRow) { + classes.push('current-row'); + } + + if (this.stripe && rowIndex % 2 === 1) { + classes.push('el-table__row--striped'); + } + const rowClassName = this.table.rowClassName; + if (typeof rowClassName === 'string') { + classes.push(rowClassName); + } else if (typeof rowClassName === 'function') { + classes.push(rowClassName.call(null, { + row, + rowIndex + })); + } + + if (this.store.states.expandRows.indexOf(row) > -1) { + classes.push('expanded'); + } + + return classes; + }, + + getCellStyle(rowIndex, columnIndex, row, column) { + const cellStyle = this.table.cellStyle; + if (typeof cellStyle === 'function') { + return cellStyle.call(null, { + rowIndex, + columnIndex, + row, + column + }); + } + return cellStyle; + }, + + getCellClass(rowIndex, columnIndex, row, column) { + const classes = [column.id, column.align, column.className]; + + if (this.isColumnHidden(columnIndex)) { + classes.push('is-hidden'); + } + + const cellClassName = this.table.cellClassName; + if (typeof cellClassName === 'string') { + classes.push(cellClassName); + } else if (typeof cellClassName === 'function') { + classes.push(cellClassName.call(null, { + rowIndex, + columnIndex, + row, + column + })); + } + + return classes.join(' '); + }, + + getColspanRealWidth(columns, colspan, index) { + if (colspan < 1) { + return columns[index].realWidth; + } + const widthArr = columns.map(({ realWidth }) => realWidth).slice(index, index + colspan); + return widthArr.reduce((acc, width) => acc + width, -1); + }, + + handleCellMouseEnter(event, row) { + const table = this.table; + const cell = getCell(event); + + if (cell) { + const column = getColumnByCell(table, cell); + const hoverState = table.hoverState = {cell, column, row}; + table.$emit('cell-mouse-enter', hoverState.row, hoverState.column, hoverState.cell, event); + } + + // 判断是否text-overflow, 如果是就显示tooltip + const cellChild = event.target.querySelector('.cell'); + if (!(hasClass(cellChild, 'el-tooltip') && cellChild.childNodes.length)) { + return; + } + // use range width instead of scrollWidth to determine whether the text is overflowing + // to address a potential FireFox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1074543#c3 + const range = document.createRange(); + range.setStart(cellChild, 0); + range.setEnd(cellChild, cellChild.childNodes.length); + const rangeWidth = range.getBoundingClientRect().width; + const padding = (parseInt(getStyle(cellChild, 'paddingLeft'), 10) || 0) + + (parseInt(getStyle(cellChild, 'paddingRight'), 10) || 0); + if ((rangeWidth + padding > cellChild.offsetWidth || cellChild.scrollWidth > cellChild.offsetWidth) && this.$refs.tooltip) { + const tooltip = this.$refs.tooltip; + // TODO 会引起整个 Table 的重新渲染,需要优化 + this.tooltipContent = cell.innerText || cell.textContent; + tooltip.referenceElm = cell; + tooltip.$refs.popper && (tooltip.$refs.popper.style.display = 'none'); + tooltip.doDestroy(); + tooltip.setExpectedState(true); + this.activateTooltip(tooltip); + } + }, + + handleCellMouseLeave(event) { + const tooltip = this.$refs.tooltip; + if (tooltip) { + tooltip.setExpectedState(false); + tooltip.handleClosePopper(); + } + const cell = getCell(event); + if (!cell) return; + + const oldHoverState = this.table.hoverState || {}; + this.table.$emit('cell-mouse-leave', oldHoverState.row, oldHoverState.column, oldHoverState.cell, event); + }, + + handleMouseEnter: debounce(30, function(index) { + this.store.commit('setHoverRow', index); + }), + + handleMouseLeave: debounce(30, function() { + this.store.commit('setHoverRow', null); + }), + + handleContextMenu(event, row) { + this.handleEvent(event, row, 'contextmenu'); + }, + + handleDoubleClick(event, row) { + this.handleEvent(event, row, 'dblclick'); + }, + + handleClick(event, row) { + this.store.commit('setCurrentRow', row); + this.handleEvent(event, row, 'click'); + }, + + handleEvent(event, row, name) { + const table = this.table; + const cell = getCell(event); + let column; + if (cell) { + column = getColumnByCell(table, cell); + if (column) { + table.$emit(`cell-${name}`, row, column, cell, event); + } + } + table.$emit(`row-${name}`, row, column, event); + }, + + rowRender(row, $index, treeRowData) { + const { treeIndent, columns, firstDefaultColumnIndex } = this; + const columnsHidden = columns.map((column, index) => this.isColumnHidden(index)); + const rowClasses = this.getRowClass(row, $index); + let display = true; + if (treeRowData) { + rowClasses.push('el-table__row--level-' + treeRowData.level); + display = treeRowData.display; + } + // 指令 v-show 会覆盖 row-style 中 display + // 使用 :style 代替 v-show https://github.com/ElemeFE/element/issues/16995 + let displayStyle = display ? null : { + display: 'none' + }; + return ( this.handleDoubleClick($event, row) } + on-click={ ($event) => this.handleClick($event, row) } + on-contextmenu={ ($event) => this.handleContextMenu($event, row) } + on-mouseenter={ _ => this.handleMouseEnter($index) } + on-mouseleave={ this.handleMouseLeave }> + { + columns.map((column, cellIndex) => { + const { rowspan, colspan } = this.getSpan(row, column, $index, cellIndex); + if (!rowspan || !colspan) { + return null; + } + const columnData = { ...column }; + columnData.realWidth = this.getColspanRealWidth(columns, colspan, cellIndex); + const data = { + store: this.store, + _self: this.context || this.table.$vnode.context, + column: columnData, + row, + $index + }; + if (cellIndex === firstDefaultColumnIndex && treeRowData) { + data.treeNode = { + indent: treeRowData.level * treeIndent, + level: treeRowData.level + }; + if (typeof treeRowData.expanded === 'boolean') { + data.treeNode.expanded = treeRowData.expanded; + // 表明是懒加载 + if ('loading' in treeRowData) { + data.treeNode.loading = treeRowData.loading; + } + if ('noLazyChildren' in treeRowData) { + data.treeNode.noLazyChildren = treeRowData.noLazyChildren; + } + } + } + return ( + this.handleCellMouseEnter($event, row) } + on-mouseleave={ this.handleCellMouseLeave }> + { + column.renderCell.call( + this._renderProxy, + this.$createElement, + data, + columnsHidden[cellIndex] + ) + } + + ); + }) + } + ); + }, + + wrappedRowRender(row, $index) { + const store = this.store; + const { isRowExpanded, assertRowKey } = store; + const { treeData, lazyTreeNodeMap, childrenColumnName, rowKey } = store.states; + if (this.hasExpandColumn && isRowExpanded(row)) { + const renderExpanded = this.table.renderExpanded; + const tr = this.rowRender(row, $index); + if (!renderExpanded) { + console.error('[Element Error]renderExpanded is required.'); + return tr; + } + // 使用二维数组,避免修改 $index + return [[ + tr, + + + { renderExpanded(this.$createElement, { row, $index, store: this.store }) } + + ]]; + } else if (Object.keys(treeData).length) { + assertRowKey(); + // TreeTable 时,rowKey 必须由用户设定,不使用 getKeyOfRow 计算 + // 在调用 rowRender 函数时,仍然会计算 rowKey,不太好的操作 + const key = getRowIdentity(row, rowKey); + let cur = treeData[key]; + let treeRowData = null; + if (cur) { + treeRowData = { + expanded: cur.expanded, + level: cur.level, + display: true + }; + if (typeof cur.lazy === 'boolean') { + if (typeof cur.loaded === 'boolean' && cur.loaded) { + treeRowData.noLazyChildren = !(cur.children && cur.children.length); + } + treeRowData.loading = cur.loading; + } + } + const tmp = [this.rowRender(row, $index, treeRowData)]; + // 渲染嵌套数据 + if (cur) { + // currentRow 记录的是 index,所以还需主动增加 TreeTable 的 index + let i = 0; + const traverse = (children, parent) => { + if (!(children && children.length && parent)) return; + children.forEach(node => { + // 父节点的 display 状态影响子节点的显示状态 + const innerTreeRowData = { + display: parent.display && parent.expanded, + level: parent.level + 1 + }; + const childKey = getRowIdentity(node, rowKey); + if (childKey === undefined || childKey === null) { + throw new Error('for nested data item, row-key is required.'); + } + cur = { ...treeData[childKey] }; + // 对于当前节点,分成有无子节点两种情况。 + // 如果包含子节点的,设置 expanded 属性。 + // 对于它子节点的 display 属性由它本身的 expanded 与 display 共同决定。 + if (cur) { + innerTreeRowData.expanded = cur.expanded; + // 懒加载的某些节点,level 未知 + cur.level = cur.level || innerTreeRowData.level; + cur.display = !!(cur.expanded && innerTreeRowData.display); + if (typeof cur.lazy === 'boolean') { + if (typeof cur.loaded === 'boolean' && cur.loaded) { + innerTreeRowData.noLazyChildren = !(cur.children && cur.children.length); + } + innerTreeRowData.loading = cur.loading; + } + } + i++; + tmp.push(this.rowRender(node, $index + i, innerTreeRowData)); + if (cur) { + const nodes = lazyTreeNodeMap[childKey] || node[childrenColumnName]; + traverse(nodes, cur); + } + }); + }; + // 对于 root 节点,display 一定为 true + cur.display = true; + const nodes = lazyTreeNodeMap[key] || row[childrenColumnName]; + traverse(nodes, cur); + } + return tmp; + } else { + return this.rowRender(row, $index); + } + } + } +}; diff --git a/packages/table/src/table-column.js b/packages/table/src/table-column.js new file mode 100644 index 0000000..528eff1 --- /dev/null +++ b/packages/table/src/table-column.js @@ -0,0 +1,319 @@ +import { cellStarts, cellForced, defaultRenderCell, treeCellPrefix } from './config'; +import { mergeOptions, parseWidth, parseMinWidth, compose } from './util'; +import ElCheckbox from 'element-ui/packages/checkbox'; + +let columnIdSeed = 1; + +export default { + name: 'ElTableColumn', + + props: { + type: { + type: String, + default: 'default' + }, + label: String, + className: String, + labelClassName: String, + property: String, + prop: String, + width: {}, + minWidth: {}, + renderHeader: Function, + sortable: { + type: [Boolean, String], + default: false + }, + sortMethod: Function, + sortBy: [String, Function, Array], + resizable: { + type: Boolean, + default: true + }, + columnKey: String, + align: String, + headerAlign: String, + showTooltipWhenOverflow: Boolean, + showOverflowTooltip: Boolean, + fixed: [Boolean, String], + formatter: Function, + selectable: Function, + reserveSelection: Boolean, + filterMethod: Function, + filteredValue: Array, + filters: Array, + filterPlacement: String, + filterMultiple: { + type: Boolean, + default: true + }, + index: [Number, Function], + sortOrders: { + type: Array, + default() { + return ['ascending', 'descending', null]; + }, + validator(val) { + return val.every(order => ['ascending', 'descending', null].indexOf(order) > -1); + } + } + }, + + data() { + return { + isSubColumn: false, + columns: [] + }; + }, + + computed: { + owner() { + let parent = this.$parent; + while (parent && !parent.tableId) { + parent = parent.$parent; + } + return parent; + }, + + columnOrTableParent() { + let parent = this.$parent; + while (parent && !parent.tableId && !parent.columnId) { + parent = parent.$parent; + } + return parent; + }, + + realWidth() { + return parseWidth(this.width); + }, + + realMinWidth() { + return parseMinWidth(this.minWidth); + }, + + realAlign() { + return this.align ? 'is-' + this.align : null; + }, + + realHeaderAlign() { + return this.headerAlign ? 'is-' + this.headerAlign : this.realAlign; + } + }, + + methods: { + getPropsData(...props) { + return props.reduce((prev, cur) => { + if (Array.isArray(cur)) { + cur.forEach((key) => { + prev[key] = this[key]; + }); + } + return prev; + }, {}); + }, + + getColumnElIndex(children, child) { + return [].indexOf.call(children, child); + }, + + setColumnWidth(column) { + if (this.realWidth) { + column.width = this.realWidth; + } + if (this.realMinWidth) { + column.minWidth = this.realMinWidth; + } + if (!column.minWidth) { + column.minWidth = 80; + } + column.realWidth = column.width === undefined ? column.minWidth : column.width; + return column; + }, + + setColumnForcedProps(column) { + // 对于特定类型的 column,某些属性不允许设置 + const type = column.type; + const source = cellForced[type] || {}; + Object.keys(source).forEach(prop => { + let value = source[prop]; + if (value !== undefined) { + column[prop] = prop === 'className' ? `${column[prop]} ${value}` : value; + } + }); + return column; + }, + + setColumnRenders(column) { + // renderHeader 属性不推荐使用。 + if (this.renderHeader) { + console.warn('[Element Warn][TableColumn]Comparing to render-header, scoped-slot header is easier to use. We recommend users to use scoped-slot header.'); + } else if (column.type !== 'selection') { + column.renderHeader = (h, scope) => { + const renderHeader = this.$scopedSlots.header; + return renderHeader ? renderHeader(scope) : column.label; + }; + } + + let originRenderCell = column.renderCell; + // TODO: 这里的实现调整 + if (column.type === 'expand') { + // 对于展开行,renderCell 不允许配置的。在上一步中已经设置过,这里需要简单封装一下。 + column.renderCell = (h, data) => (
+ { originRenderCell(h, data) } +
); + this.owner.renderExpanded = (h, data) => { + return this.$scopedSlots.default + ? this.$scopedSlots.default(data) + : this.$slots.default; + }; + } else { + originRenderCell = originRenderCell || defaultRenderCell; + // 对 renderCell 进行包装 + column.renderCell = (h, data) => { + let children = null; + if (this.$scopedSlots.default) { + children = this.$scopedSlots.default(data); + } else { + children = originRenderCell(h, data); + } + const prefix = treeCellPrefix(h, data); + const props = { + class: 'cell', + style: {} + }; + if (column.showOverflowTooltip) { + props.class += ' el-tooltip'; + props.style = {width: (data.column.realWidth || data.column.width) - 1 + 'px'}; + } + return (
+ { prefix } + { children } +
); + }; + } + return column; + }, + + registerNormalWatchers() { + const props = ['label', 'property', 'filters', 'filterMultiple', 'sortable', 'index', 'formatter', 'className', 'labelClassName', 'showOverflowTooltip']; + // 一些属性具有别名 + const aliases = { + prop: 'property', + realAlign: 'align', + realHeaderAlign: 'headerAlign', + realWidth: 'width' + }; + const allAliases = props.reduce((prev, cur) => { + prev[cur] = cur; + return prev; + }, aliases); + + Object.keys(allAliases).forEach(key => { + const columnKey = aliases[key]; + + this.$watch(key, (newVal) => { + this.columnConfig[columnKey] = newVal; + }); + }); + }, + + registerComplexWatchers() { + const props = ['fixed']; + const aliases = { + realWidth: 'width', + realMinWidth: 'minWidth' + }; + const allAliases = props.reduce((prev, cur) => { + prev[cur] = cur; + return prev; + }, aliases); + + Object.keys(allAliases).forEach(key => { + const columnKey = aliases[key]; + + this.$watch(key, (newVal) => { + this.columnConfig[columnKey] = newVal; + const updateColumns = columnKey === 'fixed'; + this.owner.store.scheduleLayout(updateColumns); + }); + }); + } + }, + + components: { + ElCheckbox + }, + + beforeCreate() { + this.row = {}; + this.column = {}; + this.$index = 0; + this.columnId = ''; + }, + + created() { + const parent = this.columnOrTableParent; + this.isSubColumn = this.owner !== parent; + this.columnId = (parent.tableId || parent.columnId) + '_column_' + columnIdSeed++; + + const type = this.type || 'default'; + const sortable = this.sortable === '' ? true : this.sortable; + const defaults = { + ...cellStarts[type], + id: this.columnId, + type: type, + property: this.prop || this.property, + align: this.realAlign, + headerAlign: this.realHeaderAlign, + showOverflowTooltip: this.showOverflowTooltip || this.showTooltipWhenOverflow, + // filter 相关属性 + filterable: this.filters || this.filterMethod, + filteredValue: [], + filterPlacement: '', + isColumnGroup: false, + filterOpened: false, + // sort 相关属性 + sortable: sortable, + // index 列 + index: this.index + }; + + const basicProps = ['columnKey', 'label', 'className', 'labelClassName', 'type', 'renderHeader', 'formatter', 'fixed', 'resizable']; + const sortProps = ['sortMethod', 'sortBy', 'sortOrders']; + const selectProps = ['selectable', 'reserveSelection']; + const filterProps = ['filterMethod', 'filters', 'filterMultiple', 'filterOpened', 'filteredValue', 'filterPlacement']; + + let column = this.getPropsData(basicProps, sortProps, selectProps, filterProps); + column = mergeOptions(defaults, column); + + // 注意 compose 中函数执行的顺序是从右到左 + const chains = compose(this.setColumnRenders, this.setColumnWidth, this.setColumnForcedProps); + column = chains(column); + + this.columnConfig = column; + + // 注册 watcher + this.registerNormalWatchers(); + this.registerComplexWatchers(); + }, + + mounted() { + const owner = this.owner; + const parent = this.columnOrTableParent; + const children = this.isSubColumn ? parent.$el.children : parent.$refs.hiddenColumns.children; + const columnIndex = this.getColumnElIndex(children, this.$el); + + owner.store.commit('insertColumn', this.columnConfig, columnIndex, this.isSubColumn ? parent.columnConfig : null); + }, + + destroyed() { + if (!this.$parent) return; + const parent = this.$parent; + this.owner.store.commit('removeColumn', this.columnConfig, this.isSubColumn ? parent.columnConfig : null); + }, + + render(h) { + // slots 也要渲染,需要计算合并表头 + return h('div', this.$slots.default); + } +}; diff --git a/packages/table/src/table-footer.js b/packages/table/src/table-footer.js new file mode 100644 index 0000000..8d51c97 --- /dev/null +++ b/packages/table/src/table-footer.js @@ -0,0 +1,153 @@ +import LayoutObserver from './layout-observer'; +import { mapStates } from './store/helper'; + +export default { + name: 'ElTableFooter', + + mixins: [LayoutObserver], + + render(h) { + let sums = []; + if (this.summaryMethod) { + sums = this.summaryMethod({ columns: this.columns, data: this.store.states.data }); + } else { + this.columns.forEach((column, index) => { + if (index === 0) { + sums[index] = this.sumText; + return; + } + const values = this.store.states.data.map(item => Number(item[column.property])); + const precisions = []; + let notNumber = true; + values.forEach(value => { + if (!isNaN(value)) { + notNumber = false; + let decimal = ('' + value).split('.')[1]; + precisions.push(decimal ? decimal.length : 0); + } + }); + const precision = Math.max.apply(null, precisions); + if (!notNumber) { + sums[index] = values.reduce((prev, curr) => { + const value = Number(curr); + if (!isNaN(value)) { + return parseFloat((prev + curr).toFixed(Math.min(precision, 20))); + } else { + return prev; + } + }, 0); + } else { + sums[index] = ''; + } + }); + } + + return ( + + + { + this.columns.map(column => ) + } + { + this.hasGutter ? : '' + } + + + + { + this.columns.map((column, cellIndex) => ) + } + { + this.hasGutter ? : '' + } + + + + ); + }, + + props: { + fixed: String, + store: { + required: true + }, + summaryMethod: Function, + sumText: String, + border: Boolean, + defaultSort: { + type: Object, + default() { + return { + prop: '', + order: '' + }; + } + } + }, + + computed: { + table() { + return this.$parent; + }, + + hasGutter() { + return !this.fixed && this.tableLayout.gutterWidth; + }, + + ...mapStates({ + columns: 'columns', + isAllSelected: 'isAllSelected', + leftFixedLeafCount: 'fixedLeafColumnsLength', + rightFixedLeafCount: 'rightFixedLeafColumnsLength', + columnsCount: states => states.columns.length, + leftFixedCount: states => states.fixedColumns.length, + rightFixedCount: states => states.rightFixedColumns.length + }) + }, + + methods: { + isCellHidden(index, columns, column) { + if (this.fixed === true || this.fixed === 'left') { + return index >= this.leftFixedLeafCount; + } else if (this.fixed === 'right') { + let before = 0; + for (let i = 0; i < index; i++) { + before += columns[i].colSpan; + } + return before < this.columnsCount - this.rightFixedLeafCount; + } else if (!this.fixed && column.fixed) { // hide cell when footer instance is not fixed and column is fixed + return true; + } else { + return (index < this.leftFixedCount) || (index >= this.columnsCount - this.rightFixedCount); + } + }, + + getRowClasses(column, cellIndex) { + const classes = [column.id, column.align, column.labelClassName]; + if (column.className) { + classes.push(column.className); + } + if (this.isCellHidden(cellIndex, this.columns, column)) { + classes.push('is-hidden'); + } + if (!column.children) { + classes.push('is-leaf'); + } + return classes; + } + } +}; diff --git a/packages/table/src/table-header.js b/packages/table/src/table-header.js new file mode 100644 index 0000000..6562669 --- /dev/null +++ b/packages/table/src/table-header.js @@ -0,0 +1,510 @@ +import Vue from 'vue'; +import { hasClass, addClass, removeClass } from 'element-ui/src/utils/dom'; +import ElCheckbox from 'element-ui/packages/checkbox'; +import FilterPanel from './filter-panel.vue'; +import LayoutObserver from './layout-observer'; +import { mapStates } from './store/helper'; + +const getAllColumns = (columns) => { + const result = []; + columns.forEach((column) => { + if (column.children) { + result.push(column); + result.push.apply(result, getAllColumns(column.children)); + } else { + result.push(column); + } + }); + return result; +}; + +const convertToRows = (originColumns) => { + let maxLevel = 1; + const traverse = (column, parent) => { + if (parent) { + column.level = parent.level + 1; + if (maxLevel < column.level) { + maxLevel = column.level; + } + } + if (column.children) { + let colSpan = 0; + column.children.forEach((subColumn) => { + traverse(subColumn, column); + colSpan += subColumn.colSpan; + }); + column.colSpan = colSpan; + } else { + column.colSpan = 1; + } + }; + + originColumns.forEach((column) => { + column.level = 1; + traverse(column); + }); + + const rows = []; + for (let i = 0; i < maxLevel; i++) { + rows.push([]); + } + + const allColumns = getAllColumns(originColumns); + + allColumns.forEach((column) => { + if (!column.children) { + column.rowSpan = maxLevel - column.level + 1; + } else { + column.rowSpan = 1; + } + rows[column.level - 1].push(column); + }); + + return rows; +}; + +export default { + name: 'ElTableHeader', + + mixins: [LayoutObserver], + + render(h) { + const originColumns = this.store.states.originColumns; + const columnRows = convertToRows(originColumns, this.columns); + // 是否拥有多级表头 + const isGroup = columnRows.length > 1; + if (isGroup) this.$parent.isGroup = true; + return ( + + + { + this.columns.map(column => ) + } + { + this.hasGutter ? : '' + } + + + { + this._l(columnRows, (columns, rowIndex) => + + { + columns.map((column, cellIndex) => ()) + } + { + this.hasGutter ? : '' + } + + ) + } + +
this.handleMouseMove($event, column) } + on-mouseout={ this.handleMouseOut } + on-mousedown={ ($event) => this.handleMouseDown($event, column) } + on-click={ ($event) => this.handleHeaderClick($event, column) } + on-contextmenu={ ($event) => this.handleHeaderContextMenu($event, column) } + style={ this.getHeaderCellStyle(rowIndex, cellIndex, columns, column) } + class={ this.getHeaderCellClass(rowIndex, cellIndex, columns, column) } + key={ column.id }> +
0 ? 'highlight' : '', column.labelClassName] }> + { + column.renderHeader + ? column.renderHeader.call(this._renderProxy, h, { column, $index: cellIndex, store: this.store, _self: this.$parent.$vnode.context }) + : column.label + } + { + column.sortable ? ( this.handleSortClick($event, column) }> + this.handleSortClick($event, column, 'ascending') }> + + this.handleSortClick($event, column, 'descending') }> + + ) : '' + } + { + column.filterable ? ( this.handleFilterClick($event, column) }> + + ) : '' + } +
+
+ ); + }, + + props: { + fixed: String, + store: { + required: true + }, + border: Boolean, + defaultSort: { + type: Object, + default() { + return { + prop: '', + order: '' + }; + } + } + }, + + components: { + ElCheckbox + }, + + computed: { + table() { + return this.$parent; + }, + + hasGutter() { + return !this.fixed && this.tableLayout.gutterWidth; + }, + + ...mapStates({ + columns: 'columns', + isAllSelected: 'isAllSelected', + leftFixedLeafCount: 'fixedLeafColumnsLength', + rightFixedLeafCount: 'rightFixedLeafColumnsLength', + columnsCount: states => states.columns.length, + leftFixedCount: states => states.fixedColumns.length, + rightFixedCount: states => states.rightFixedColumns.length + }) + }, + + created() { + this.filterPanels = {}; + }, + + mounted() { + // nextTick 是有必要的 https://github.com/ElemeFE/element/pull/11311 + this.$nextTick(() => { + const { prop, order } = this.defaultSort; + const init = true; + this.store.commit('sort', { prop, order, init }); + }); + }, + + beforeDestroy() { + const panels = this.filterPanels; + for (let prop in panels) { + if (panels.hasOwnProperty(prop) && panels[prop]) { + panels[prop].$destroy(true); + } + } + }, + + methods: { + isCellHidden(index, columns) { + let start = 0; + for (let i = 0; i < index; i++) { + start += columns[i].colSpan; + } + const after = start + columns[index].colSpan - 1; + if (this.fixed === true || this.fixed === 'left') { + return after >= this.leftFixedLeafCount; + } else if (this.fixed === 'right') { + return start < this.columnsCount - this.rightFixedLeafCount; + } else { + return (after < this.leftFixedLeafCount) || (start >= this.columnsCount - this.rightFixedLeafCount); + } + }, + + getHeaderRowStyle(rowIndex) { + const headerRowStyle = this.table.headerRowStyle; + if (typeof headerRowStyle === 'function') { + return headerRowStyle.call(null, { rowIndex }); + } + return headerRowStyle; + }, + + getHeaderRowClass(rowIndex) { + const classes = []; + + const headerRowClassName = this.table.headerRowClassName; + if (typeof headerRowClassName === 'string') { + classes.push(headerRowClassName); + } else if (typeof headerRowClassName === 'function') { + classes.push(headerRowClassName.call(null, { rowIndex })); + } + + return classes.join(' '); + }, + + getHeaderCellStyle(rowIndex, columnIndex, row, column) { + const headerCellStyle = this.table.headerCellStyle; + if (typeof headerCellStyle === 'function') { + return headerCellStyle.call(null, { + rowIndex, + columnIndex, + row, + column + }); + } + return headerCellStyle; + }, + + getHeaderCellClass(rowIndex, columnIndex, row, column) { + const classes = [column.id, column.order, column.headerAlign, column.className, column.labelClassName]; + + if (rowIndex === 0 && this.isCellHidden(columnIndex, row)) { + classes.push('is-hidden'); + } + + if (!column.children) { + classes.push('is-leaf'); + } + + if (column.sortable) { + classes.push('is-sortable'); + } + + const headerCellClassName = this.table.headerCellClassName; + if (typeof headerCellClassName === 'string') { + classes.push(headerCellClassName); + } else if (typeof headerCellClassName === 'function') { + classes.push(headerCellClassName.call(null, { + rowIndex, + columnIndex, + row, + column + })); + } + + return classes.join(' '); + }, + + toggleAllSelection(event) { + event.stopPropagation(); + this.store.commit('toggleAllSelection'); + }, + + handleFilterClick(event, column) { + event.stopPropagation(); + const target = event.target; + let cell = target.tagName === 'TH' ? target : target.parentNode; + if (hasClass(cell, 'noclick')) return; + cell = cell.querySelector('.el-table__column-filter-trigger') || cell; + const table = this.$parent; + + let filterPanel = this.filterPanels[column.id]; + + if (filterPanel && column.filterOpened) { + filterPanel.showPopper = false; + return; + } + + if (!filterPanel) { + filterPanel = new Vue(FilterPanel); + this.filterPanels[column.id] = filterPanel; + if (column.filterPlacement) { + filterPanel.placement = column.filterPlacement; + } + filterPanel.table = table; + filterPanel.cell = cell; + filterPanel.column = column; + !this.$isServer && filterPanel.$mount(document.createElement('div')); + } + + setTimeout(() => { + filterPanel.showPopper = true; + }, 16); + }, + + handleHeaderClick(event, column) { + if (!column.filters && column.sortable) { + this.handleSortClick(event, column); + } else if (column.filterable && !column.sortable) { + this.handleFilterClick(event, column); + } + + this.$parent.$emit('header-click', column, event); + }, + + handleHeaderContextMenu(event, column) { + this.$parent.$emit('header-contextmenu', column, event); + }, + + handleMouseDown(event, column) { + if (this.$isServer) return; + if (column.children && column.children.length > 0) return; + /* istanbul ignore if */ + if (this.draggingColumn && this.border) { + this.dragging = true; + + this.$parent.resizeProxyVisible = true; + + const table = this.$parent; + const tableEl = table.$el; + const tableLeft = tableEl.getBoundingClientRect().left; + const columnEl = this.$el.querySelector(`th.${column.id}`); + const columnRect = columnEl.getBoundingClientRect(); + const minLeft = columnRect.left - tableLeft + 30; + + addClass(columnEl, 'noclick'); + + this.dragState = { + startMouseLeft: event.clientX, + startLeft: columnRect.right - tableLeft, + startColumnLeft: columnRect.left - tableLeft, + tableLeft + }; + + const resizeProxy = table.$refs.resizeProxy; + resizeProxy.style.left = this.dragState.startLeft + 'px'; + + document.onselectstart = function() { return false; }; + document.ondragstart = function() { return false; }; + + const handleMouseMove = (event) => { + const deltaLeft = event.clientX - this.dragState.startMouseLeft; + const proxyLeft = this.dragState.startLeft + deltaLeft; + + resizeProxy.style.left = Math.max(minLeft, proxyLeft) + 'px'; + }; + + const handleMouseUp = () => { + if (this.dragging) { + const { + startColumnLeft, + startLeft + } = this.dragState; + const finalLeft = parseInt(resizeProxy.style.left, 10); + const columnWidth = finalLeft - startColumnLeft; + column.width = column.realWidth = columnWidth; + table.$emit('header-dragend', column.width, startLeft - startColumnLeft, column, event); + + this.store.scheduleLayout(); + + document.body.style.cursor = ''; + this.dragging = false; + this.draggingColumn = null; + this.dragState = {}; + + table.resizeProxyVisible = false; + } + + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + document.onselectstart = null; + document.ondragstart = null; + + setTimeout(function() { + removeClass(columnEl, 'noclick'); + }, 0); + }; + + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + } + }, + + handleMouseMove(event, column) { + if (column.children && column.children.length > 0) return; + let target = event.target; + while (target && target.tagName !== 'TH') { + target = target.parentNode; + } + + if (!column || !column.resizable) return; + + if (!this.dragging && this.border) { + let rect = target.getBoundingClientRect(); + + const bodyStyle = document.body.style; + if (rect.width > 12 && rect.right - event.pageX < 8) { + bodyStyle.cursor = 'col-resize'; + if (hasClass(target, 'is-sortable')) { + target.style.cursor = 'col-resize'; + } + this.draggingColumn = column; + } else if (!this.dragging) { + bodyStyle.cursor = ''; + if (hasClass(target, 'is-sortable')) { + target.style.cursor = 'pointer'; + } + this.draggingColumn = null; + } + } + }, + + handleMouseOut() { + if (this.$isServer) return; + document.body.style.cursor = ''; + }, + + toggleOrder({ order, sortOrders }) { + if (order === '') return sortOrders[0]; + const index = sortOrders.indexOf(order || null); + return sortOrders[index > sortOrders.length - 2 ? 0 : index + 1]; + }, + + handleSortClick(event, column, givenOrder) { + event.stopPropagation(); + let order = column.order === givenOrder + ? null + : (givenOrder || this.toggleOrder(column)); + + let target = event.target; + while (target && target.tagName !== 'TH') { + target = target.parentNode; + } + + if (target && target.tagName === 'TH') { + if (hasClass(target, 'noclick')) { + removeClass(target, 'noclick'); + return; + } + } + + if (!column.sortable) return; + + const states = this.store.states; + let sortProp = states.sortProp; + let sortOrder; + const sortingColumn = states.sortingColumn; + + if (sortingColumn !== column || (sortingColumn === column && sortingColumn.order === null)) { + if (sortingColumn) { + sortingColumn.order = null; + } + states.sortingColumn = column; + sortProp = column.property; + } + + if (!order) { + sortOrder = column.order = null; + } else { + sortOrder = column.order = order; + } + + states.sortProp = sortProp; + states.sortOrder = sortOrder; + + this.store.commit('changeSortCondition'); + } + }, + + data() { + return { + draggingColumn: null, + dragging: false, + dragState: {} + }; + } +}; diff --git a/packages/table/src/table-layout.js b/packages/table/src/table-layout.js new file mode 100644 index 0000000..6365dc9 --- /dev/null +++ b/packages/table/src/table-layout.js @@ -0,0 +1,250 @@ +import Vue from 'vue'; +import scrollbarWidth from 'element-ui/src/utils/scrollbar-width'; +import { parseHeight } from './util'; + +class TableLayout { + constructor(options) { + this.observers = []; + this.table = null; + this.store = null; + this.columns = null; + this.fit = true; + this.showHeader = true; + + this.height = null; + this.scrollX = false; + this.scrollY = false; + this.bodyWidth = null; + this.fixedWidth = null; + this.rightFixedWidth = null; + this.tableHeight = null; + this.headerHeight = 44; // Table Header Height + this.appendHeight = 0; // Append Slot Height + this.footerHeight = 44; // Table Footer Height + this.viewportHeight = null; // Table Height - Scroll Bar Height + this.bodyHeight = null; // Table Height - Table Header Height + this.fixedBodyHeight = null; // Table Height - Table Header Height - Scroll Bar Height + this.gutterWidth = scrollbarWidth(); + + for (let name in options) { + if (options.hasOwnProperty(name)) { + this[name] = options[name]; + } + } + + if (!this.table) { + throw new Error('table is required for Table Layout'); + } + if (!this.store) { + throw new Error('store is required for Table Layout'); + } + } + + updateScrollY() { + const height = this.height; + if (height === null) return false; + const bodyWrapper = this.table.bodyWrapper; + if (this.table.$el && bodyWrapper) { + const body = bodyWrapper.querySelector('.el-table__body'); + const prevScrollY = this.scrollY; + const scrollY = body.offsetHeight > this.bodyHeight; + this.scrollY = scrollY; + return prevScrollY !== scrollY; + } + return false; + } + + setHeight(value, prop = 'height') { + if (Vue.prototype.$isServer) return; + const el = this.table.$el; + value = parseHeight(value); + this.height = value; + + if (!el && (value || value === 0)) return Vue.nextTick(() => this.setHeight(value, prop)); + + if (typeof value === 'number') { + el.style[prop] = value + 'px'; + this.updateElsHeight(); + } else if (typeof value === 'string') { + el.style[prop] = value; + this.updateElsHeight(); + } + } + + setMaxHeight(value) { + this.setHeight(value, 'max-height'); + } + + getFlattenColumns() { + const flattenColumns = []; + const columns = this.table.columns; + columns.forEach((column) => { + if (column.isColumnGroup) { + flattenColumns.push.apply(flattenColumns, column.columns); + } else { + flattenColumns.push(column); + } + }); + + return flattenColumns; + } + + updateElsHeight() { + if (!this.table.$ready) return Vue.nextTick(() => this.updateElsHeight()); + const { headerWrapper, appendWrapper, footerWrapper } = this.table.$refs; + this.appendHeight = appendWrapper ? appendWrapper.offsetHeight : 0; + + if (this.showHeader && !headerWrapper) return; + + // fix issue (https://github.com/ElemeFE/element/pull/16956) + const headerTrElm = headerWrapper ? headerWrapper.querySelector('.el-table__header tr') : null; + const noneHeader = this.headerDisplayNone(headerTrElm); + + const headerHeight = this.headerHeight = !this.showHeader ? 0 : headerWrapper.offsetHeight; + if (this.showHeader && !noneHeader && headerWrapper.offsetWidth > 0 && (this.table.columns || []).length > 0 && headerHeight < 2) { + return Vue.nextTick(() => this.updateElsHeight()); + } + const tableHeight = this.tableHeight = this.table.$el.clientHeight; + const footerHeight = this.footerHeight = footerWrapper ? footerWrapper.offsetHeight : 0; + if (this.height !== null) { + this.bodyHeight = tableHeight - headerHeight - footerHeight + (footerWrapper ? 1 : 0); + } + this.fixedBodyHeight = this.scrollX ? (this.bodyHeight - this.gutterWidth) : this.bodyHeight; + + const noData = !(this.store.states.data && this.store.states.data.length); + this.viewportHeight = this.scrollX ? tableHeight - (noData ? 0 : this.gutterWidth) : tableHeight; + + this.updateScrollY(); + this.notifyObservers('scrollable'); + } + + headerDisplayNone(elm) { + if (!elm) return true; + let headerChild = elm; + while (headerChild.tagName !== 'DIV') { + if (getComputedStyle(headerChild).display === 'none') { + return true; + } + headerChild = headerChild.parentElement; + } + return false; + } + + updateColumnsWidth() { + if (Vue.prototype.$isServer) return; + const fit = this.fit; + const bodyWidth = this.table.$el.clientWidth; + let bodyMinWidth = 0; + + const flattenColumns = this.getFlattenColumns(); + let flexColumns = flattenColumns.filter((column) => typeof column.width !== 'number'); + + flattenColumns.forEach((column) => { // Clean those columns whose width changed from flex to unflex + if (typeof column.width === 'number' && column.realWidth) column.realWidth = null; + }); + + if (flexColumns.length > 0 && fit) { + flattenColumns.forEach((column) => { + bodyMinWidth += column.width || column.minWidth || 80; + }); + + const scrollYWidth = this.scrollY ? this.gutterWidth : 0; + + if (bodyMinWidth <= bodyWidth - scrollYWidth) { // DON'T HAVE SCROLL BAR + this.scrollX = false; + + const totalFlexWidth = bodyWidth - scrollYWidth - bodyMinWidth; + + if (flexColumns.length === 1) { + flexColumns[0].realWidth = (flexColumns[0].minWidth || 80) + totalFlexWidth; + } else { + const allColumnsWidth = flexColumns.reduce((prev, column) => prev + (column.minWidth || 80), 0); + const flexWidthPerPixel = totalFlexWidth / allColumnsWidth; + let noneFirstWidth = 0; + + flexColumns.forEach((column, index) => { + if (index === 0) return; + const flexWidth = Math.floor((column.minWidth || 80) * flexWidthPerPixel); + noneFirstWidth += flexWidth; + column.realWidth = (column.minWidth || 80) + flexWidth; + }); + + flexColumns[0].realWidth = (flexColumns[0].minWidth || 80) + totalFlexWidth - noneFirstWidth; + } + } else { // HAVE HORIZONTAL SCROLL BAR + this.scrollX = true; + flexColumns.forEach(function(column) { + column.realWidth = column.minWidth; + }); + } + + this.bodyWidth = Math.max(bodyMinWidth, bodyWidth); + this.table.resizeState.width = this.bodyWidth; + } else { + flattenColumns.forEach((column) => { + if (!column.width && !column.minWidth) { + column.realWidth = 80; + } else { + column.realWidth = column.width || column.minWidth; + } + + bodyMinWidth += column.realWidth; + }); + this.scrollX = bodyMinWidth > bodyWidth; + + this.bodyWidth = bodyMinWidth; + } + + const fixedColumns = this.store.states.fixedColumns; + + if (fixedColumns.length > 0) { + let fixedWidth = 0; + fixedColumns.forEach(function(column) { + fixedWidth += column.realWidth || column.width; + }); + + this.fixedWidth = fixedWidth; + } + + const rightFixedColumns = this.store.states.rightFixedColumns; + if (rightFixedColumns.length > 0) { + let rightFixedWidth = 0; + rightFixedColumns.forEach(function(column) { + rightFixedWidth += column.realWidth || column.width; + }); + + this.rightFixedWidth = rightFixedWidth; + } + + this.notifyObservers('columns'); + } + + addObserver(observer) { + this.observers.push(observer); + } + + removeObserver(observer) { + const index = this.observers.indexOf(observer); + if (index !== -1) { + this.observers.splice(index, 1); + } + } + + notifyObservers(event) { + const observers = this.observers; + observers.forEach((observer) => { + switch (event) { + case 'columns': + observer.onColumnsChange(this); + break; + case 'scrollable': + observer.onScrollableChange(this); + break; + default: + throw new Error(`Table Layout don't have event ${event}.`); + } + }); + } +} + +export default TableLayout; diff --git a/packages/table/src/table.vue b/packages/table/src/table.vue new file mode 100644 index 0000000..e0061e6 --- /dev/null +++ b/packages/table/src/table.vue @@ -0,0 +1,694 @@ + + + diff --git a/packages/table/src/util.js b/packages/table/src/util.js new file mode 100644 index 0000000..7bbec8d --- /dev/null +++ b/packages/table/src/util.js @@ -0,0 +1,255 @@ +import { getValueByPath } from 'element-ui/src/utils/util'; + +export const getCell = function(event) { + let cell = event.target; + + while (cell && cell.tagName.toUpperCase() !== 'HTML') { + if (cell.tagName.toUpperCase() === 'TD') { + return cell; + } + cell = cell.parentNode; + } + + return null; +}; + +const isObject = function(obj) { + return obj !== null && typeof obj === 'object'; +}; + +export const orderBy = function(array, sortKey, reverse, sortMethod, sortBy) { + if (!sortKey && !sortMethod && (!sortBy || Array.isArray(sortBy) && !sortBy.length)) { + return array; + } + if (typeof reverse === 'string') { + reverse = reverse === 'descending' ? -1 : 1; + } else { + reverse = (reverse && reverse < 0) ? -1 : 1; + } + const getKey = sortMethod ? null : function(value, index) { + if (sortBy) { + if (!Array.isArray(sortBy)) { + sortBy = [sortBy]; + } + return sortBy.map(function(by) { + if (typeof by === 'string') { + return getValueByPath(value, by); + } else { + return by(value, index, array); + } + }); + } + if (sortKey !== '$key') { + if (isObject(value) && '$value' in value) value = value.$value; + } + return [isObject(value) ? getValueByPath(value, sortKey) : value]; + }; + const compare = function(a, b) { + if (sortMethod) { + return sortMethod(a.value, b.value); + } + for (let i = 0, len = a.key.length; i < len; i++) { + if (a.key[i] < b.key[i]) { + return -1; + } + if (a.key[i] > b.key[i]) { + return 1; + } + } + return 0; + }; + return array.map(function(value, index) { + return { + value: value, + index: index, + key: getKey ? getKey(value, index) : null + }; + }).sort(function(a, b) { + let order = compare(a, b); + if (!order) { + // make stable https://en.wikipedia.org/wiki/Sorting_algorithm#Stability + order = a.index - b.index; + } + return order * reverse; + }).map(item => item.value); +}; + +export const getColumnById = function(table, columnId) { + let column = null; + table.columns.forEach(function(item) { + if (item.id === columnId) { + column = item; + } + }); + return column; +}; + +export const getColumnByKey = function(table, columnKey) { + let column = null; + for (let i = 0; i < table.columns.length; i++) { + const item = table.columns[i]; + if (item.columnKey === columnKey) { + column = item; + break; + } + } + return column; +}; + +export const getColumnByCell = function(table, cell) { + const matches = (cell.className || '').match(/el-table_[^\s]+/gm); + if (matches) { + return getColumnById(table, matches[0]); + } + return null; +}; + +export const getRowIdentity = (row, rowKey) => { + if (!row) throw new Error('row is required when get row identity'); + if (typeof rowKey === 'string') { + if (rowKey.indexOf('.') < 0) { + return row[rowKey]; + } + let key = rowKey.split('.'); + let current = row; + for (let i = 0; i < key.length; i++) { + current = current[key[i]]; + } + return current; + } else if (typeof rowKey === 'function') { + return rowKey.call(null, row); + } +}; + +export const getKeysMap = function(array, rowKey) { + const arrayMap = {}; + (array || []).forEach((row, index) => { + arrayMap[getRowIdentity(row, rowKey)] = { row, index }; + }); + return arrayMap; +}; + +function hasOwn(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} + +export function mergeOptions(defaults, config) { + const options = {}; + let key; + for (key in defaults) { + options[key] = defaults[key]; + } + for (key in config) { + if (hasOwn(config, key)) { + const value = config[key]; + if (typeof value !== 'undefined') { + options[key] = value; + } + } + } + return options; +} + +export function parseWidth(width) { + if (width !== undefined) { + width = parseInt(width, 10); + if (isNaN(width)) { + width = null; + } + } + return width; +} + +export function parseMinWidth(minWidth) { + if (typeof minWidth !== 'undefined') { + minWidth = parseWidth(minWidth); + if (isNaN(minWidth)) { + minWidth = 80; + } + } + return minWidth; +}; + +export function parseHeight(height) { + if (typeof height === 'number') { + return height; + } + if (typeof height === 'string') { + if (/^\d+(?:px)?$/.test(height)) { + return parseInt(height, 10); + } else { + return height; + } + } + return null; +} + +// https://github.com/reduxjs/redux/blob/master/src/compose.js +export function compose(...funcs) { + if (funcs.length === 0) { + return arg => arg; + } + if (funcs.length === 1) { + return funcs[0]; + } + return funcs.reduce((a, b) => (...args) => a(b(...args))); +} + +export function toggleRowStatus(statusArr, row, newVal) { + let changed = false; + const index = statusArr.indexOf(row); + const included = index !== -1; + + const addRow = () => { + statusArr.push(row); + changed = true; + }; + const removeRow = () => { + statusArr.splice(index, 1); + changed = true; + }; + + if (typeof newVal === 'boolean') { + if (newVal && !included) { + addRow(); + } else if (!newVal && included) { + removeRow(); + } + } else { + if (included) { + removeRow(); + } else { + addRow(); + } + } + return changed; +} + +export function walkTreeNode(root, cb, childrenKey = 'children', lazyKey = 'hasChildren') { + const isNil = (array) => !(Array.isArray(array) && array.length); + + function _walker(parent, children, level) { + cb(parent, children, level); + children.forEach(item => { + if (item[lazyKey]) { + cb(item, null, level + 1); + return; + } + const children = item[childrenKey]; + if (!isNil(children)) { + _walker(item, children, level + 1); + } + }); + } + + root.forEach(item => { + if (item[lazyKey]) { + cb(item, null, 0); + return; + } + const children = item[childrenKey]; + if (!isNil(children)) { + _walker(item, children, 0); + } + }); +} diff --git a/packages/tabs/index.js b/packages/tabs/index.js new file mode 100644 index 0000000..3f72195 --- /dev/null +++ b/packages/tabs/index.js @@ -0,0 +1,8 @@ +import ElTabs from './src/tabs'; + +/* istanbul ignore next */ +ElTabs.install = function(Vue) { + Vue.component(ElTabs.name, ElTabs); +}; + +export default ElTabs; diff --git a/packages/tabs/src/tab-bar.vue b/packages/tabs/src/tab-bar.vue new file mode 100644 index 0000000..39a106e --- /dev/null +++ b/packages/tabs/src/tab-bar.vue @@ -0,0 +1,57 @@ + + diff --git a/packages/tabs/src/tab-nav.vue b/packages/tabs/src/tab-nav.vue new file mode 100644 index 0000000..19096f2 --- /dev/null +++ b/packages/tabs/src/tab-nav.vue @@ -0,0 +1,294 @@ + diff --git a/packages/tabs/src/tab-pane.vue b/packages/tabs/src/tab-pane.vue new file mode 100644 index 0000000..2e3ed75 --- /dev/null +++ b/packages/tabs/src/tab-pane.vue @@ -0,0 +1,56 @@ + + diff --git a/packages/tabs/src/tabs.vue b/packages/tabs/src/tabs.vue new file mode 100644 index 0000000..6d1b093 --- /dev/null +++ b/packages/tabs/src/tabs.vue @@ -0,0 +1,191 @@ + diff --git a/packages/tag/index.js b/packages/tag/index.js new file mode 100644 index 0000000..1f5a716 --- /dev/null +++ b/packages/tag/index.js @@ -0,0 +1,8 @@ +import ElTag from './src/tag'; + +/* istanbul ignore next */ +ElTag.install = function(Vue) { + Vue.component(ElTag.name, ElTag); +}; + +export default ElTag; diff --git a/packages/tag/src/tag.vue b/packages/tag/src/tag.vue new file mode 100644 index 0000000..7aa0bb5 --- /dev/null +++ b/packages/tag/src/tag.vue @@ -0,0 +1,58 @@ + diff --git a/packages/theme-chalk/.gitignore b/packages/theme-chalk/.gitignore new file mode 100644 index 0000000..6ddbcfa --- /dev/null +++ b/packages/theme-chalk/.gitignore @@ -0,0 +1,3 @@ +node_modules +lib +npm-debug* diff --git a/packages/theme-chalk/README.md b/packages/theme-chalk/README.md new file mode 100644 index 0000000..ad6fce8 --- /dev/null +++ b/packages/theme-chalk/README.md @@ -0,0 +1,33 @@ +# element-theme-chalk +> element component chalk theme. + + +## Installation +```shell +npm i element-theme-chalk -S +``` + +## Usage + +Use Sass import +```css +@import 'element-theme-chalk'; +``` + +Or Use webpack +```javascript +import 'element-theme-chalk'; +``` + +Or +```html + +``` + +## Import on demand +```javascript +import 'element-theme-chalk/lib/input.css'; +import 'element-theme-chalk/lib/select.css'; + +// ... +``` diff --git a/packages/theme-chalk/gulpfile.js b/packages/theme-chalk/gulpfile.js new file mode 100644 index 0000000..e1c5479 --- /dev/null +++ b/packages/theme-chalk/gulpfile.js @@ -0,0 +1,25 @@ +'use strict'; + +const { series, src, dest } = require('gulp'); +const sass = require('gulp-sass'); +const autoprefixer = require('gulp-autoprefixer'); +const cssmin = require('gulp-cssmin'); + +function compile() { + return src('./src/*.scss') + .pipe(sass.sync()) + .pipe(autoprefixer({ + browsers: ['ie > 9', 'last 2 versions'], + cascade: false + })) + .pipe(cssmin()) + .pipe(dest('./lib')); +} + +function copyfont() { + return src('./src/fonts/**') + .pipe(cssmin()) + .pipe(dest('./lib/fonts')); +} + +exports.build = series(compile, copyfont); diff --git a/packages/theme-chalk/package.json b/packages/theme-chalk/package.json new file mode 100644 index 0000000..c448166 --- /dev/null +++ b/packages/theme-chalk/package.json @@ -0,0 +1,35 @@ +{ + "name": "element-theme-chalk", + "version": "2.15.1", + "description": "Element component chalk theme.", + "main": "lib/index.css", + "style": "lib/index.css", + "files": [ + "lib", + "src" + ], + "scripts": { + "build": "gulp build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ElementUI/theme-chalk.git" + }, + "keywords": [ + "element", + "theme" + ], + "author": "yi.shyang@ele.me", + "license": "MIT", + "bugs": { + "url": "https://github.com/ElementUI/theme-chalk/issues" + }, + "homepage": "https://github.com/ElementUI/theme-chalk#readme", + "devDependencies": { + "gulp": "^3.9.1", + "gulp-cssmin": "^0.1.7", + "gulp-sass": "^3.1.0", + "gulp-autoprefixer": "^4.0.0" + }, + "dependencies": {} +} diff --git a/packages/theme-chalk/src/alert.scss b/packages/theme-chalk/src/alert.scss new file mode 100644 index 0000000..500560b --- /dev/null +++ b/packages/theme-chalk/src/alert.scss @@ -0,0 +1,147 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(alert) { + width: 100%; + padding: $--alert-padding; + margin: 0; + box-sizing: border-box; + border-radius: $--alert-border-radius; + position: relative; + background-color: $--color-white; + overflow: hidden; + opacity: 1; + display: flex; + align-items: center; + transition: opacity .2s; + + @include when(light) { + .el-alert__closebtn { + color: $--color-text-placeholder; + } + } + + @include when(dark) { + .el-alert__closebtn { + color: $--color-white; + } + .el-alert__description { + color: $--color-white; + } + } + + @include when(center) { + justify-content: center; + } + + @include m(success) { + &.is-light { + background-color: $--alert-success-color; + color: $--color-success; + + .el-alert__description { + color: $--color-success; + } + } + + &.is-dark { + background-color: $--color-success; + color: $--color-white; + } + } + + @include m(info) { + &.is-light { + background-color: $--alert-info-color; + color: $--color-info; + } + + &.is-dark { + background-color: $--color-info; + color: $--color-white; + } + + .el-alert__description { + color: $--color-info; + } + } + + @include m(warning) { + &.is-light { + background-color: $--alert-warning-color; + color: $--color-warning; + + .el-alert__description { + color: $--color-warning; + } + } + + &.is-dark { + background-color: $--color-warning; + color: $--color-white; + } + } + + @include m(error) { + &.is-light { + background-color: $--alert-danger-color; + color: $--color-danger; + + .el-alert__description { + color: $--color-danger; + } + } + + &.is-dark { + background-color: $--color-danger; + color: $--color-white; + } + } + + @include e(content) { + display: table-cell; + padding: 0 8px; + } + + @include e(icon) { + font-size: $--alert-icon-size; + width: $--alert-icon-size; + @include when(big) { + font-size: $--alert-icon-large-size; + width: $--alert-icon-large-size; + } + } + + @include e(title) { + font-size: $--alert-title-font-size; + line-height: 18px; + @include when(bold) { + font-weight: bold; + } + } + + & .el-alert__description { + font-size: $--alert-description-font-size; + margin: 5px 0 0 0; + } + + @include e(closebtn) { + font-size: $--alert-close-font-size; + opacity: 1; + position: absolute; + top: 12px; + right: 15px; + cursor: pointer; + + @include when(customed) { + font-style: normal; + font-size: $--alert-close-customed-font-size; + top: 9px; + } + } +} + +.el-alert-fade-enter, +.el-alert-fade-leave-active { + opacity: 0; +} diff --git a/packages/theme-chalk/src/aside.scss b/packages/theme-chalk/src/aside.scss new file mode 100644 index 0000000..b82749f --- /dev/null +++ b/packages/theme-chalk/src/aside.scss @@ -0,0 +1,7 @@ +@import "mixins/mixins"; + +@include b(aside) { + overflow: auto; + box-sizing: border-box; + flex-shrink: 0; +} diff --git a/packages/theme-chalk/src/autocomplete.scss b/packages/theme-chalk/src/autocomplete.scss new file mode 100644 index 0000000..d9c6e19 --- /dev/null +++ b/packages/theme-chalk/src/autocomplete.scss @@ -0,0 +1,80 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "common/var"; +@import "./input.scss"; +@import "./scrollbar.scss"; +@import "./popper"; + +@include b(autocomplete) { + position: relative; + display: inline-block; +} + +@include b(autocomplete-suggestion) { + margin: 5px 0; + box-shadow: $--box-shadow-light; + border-radius: $--border-radius-base; + border: 1px solid $--border-color-light; + box-sizing: border-box; + background-color: $--color-white; + + @include e(wrap) { + max-height: 280px; + padding: 10px 0; + box-sizing: border-box; + } + + @include e(list) { + margin: 0; + padding: 0; + } + + & li { + padding: 0 20px; + margin: 0; + line-height: 34px; + cursor: pointer; + color: $--color-text-regular; + font-size: $--font-size-base; + list-style: none; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + &:hover { + background-color: $--select-option-hover-background; + } + + &.highlighted { + background-color: $--select-option-hover-background; + } + + &.divider { + margin-top: 6px; + border-top: 1px solid $--color-black; + } + + &.divider:last-child { + margin-bottom: -6px; + } + } + + @include when(loading) { + li { + text-align: center; + height: 100px; + line-height: 100px; + font-size: 20px; + color: #999; + @include utils-vertical-center; + + &:hover { + background-color: $--color-white; + } + } + + & .el-icon-loading { + vertical-align: middle; + } + } +} diff --git a/packages/theme-chalk/src/avatar.scss b/packages/theme-chalk/src/avatar.scss new file mode 100644 index 0000000..d5ed1eb --- /dev/null +++ b/packages/theme-chalk/src/avatar.scss @@ -0,0 +1,51 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(avatar) { + display: inline-block; + box-sizing: border-box; + text-align: center; + overflow: hidden; + color: $--avatar-font-color; + background: $--avatar-background-color; + width: $--avatar-large-size; + height: $--avatar-large-size; + line-height: $--avatar-large-size; + font-size: $--avatar-text-font-size; + + >img { + display: block; + height: 100%; + vertical-align: middle; + } + + @include m(circle) { + border-radius: 50%; + } + + @include m(square) { + border-radius: $--avatar-border-radius; + } + + @include m(icon) { + font-size: $--avatar-icon-font-size; + } + + @include m(large) { + width: $--avatar-large-size; + height: $--avatar-large-size; + line-height: $--avatar-large-size; + } + + @include m(medium) { + width: $--avatar-medium-size; + height: $--avatar-medium-size; + line-height: $--avatar-medium-size; + } + + @include m(small) { + width: $--avatar-small-size; + height: $--avatar-small-size; + line-height: $--avatar-small-size; + } +} diff --git a/packages/theme-chalk/src/backtop.scss b/packages/theme-chalk/src/backtop.scss new file mode 100644 index 0000000..f415243 --- /dev/null +++ b/packages/theme-chalk/src/backtop.scss @@ -0,0 +1,22 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(backtop) { + position: fixed; + background-color: $--backtop-background-color; + width: 40px; + height: 40px; + border-radius: 50%; + color: $--backtop-font-color; + display: flex; + align-items: center; + justify-content: center; + font-size: 20px; + box-shadow: 0 0 6px rgba(0,0,0, .12); + cursor: pointer; + z-index: 5; + + &:hover { + background-color: $--backtop-hover-background-color + } +} diff --git a/packages/theme-chalk/src/badge.scss b/packages/theme-chalk/src/badge.scss new file mode 100644 index 0000000..4776e67 --- /dev/null +++ b/packages/theme-chalk/src/badge.scss @@ -0,0 +1,57 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(badge) { + position: relative; + vertical-align: middle; + display: inline-block; + + @include e(content) { + background-color: $--badge-background-color; + border-radius: $--badge-radius; + color: $--color-white; + display: inline-block; + font-size: $--badge-font-size; + height: $--badge-size; + line-height: $--badge-size; + padding: 0 $--badge-padding; + text-align: center; + white-space: nowrap; + border: 1px solid $--color-white; + + @include when(fixed) { + position: absolute; + top: 0; + right: #{1 + $--badge-size / 2}; + transform: translateY(-50%) translateX(100%); + + @include when(dot) { + right: 5px; + } + } + + @include when(dot) { + height: 8px; + width: 8px; + padding: 0; + right: 0; + border-radius: 50%; + } + + @each $type in (primary, success, warning, info, danger) { + @include m($type) { + @if $type == primary { + background-color: $--color-primary; + } @else if $type == success { + background-color: $--color-success; + } @else if $type == warning { + background-color: $--color-warning; + } @else if $type == info { + background-color: $--color-info; + } @else { + background-color: $--color-danger; + } + } + } + } +} diff --git a/packages/theme-chalk/src/base.scss b/packages/theme-chalk/src/base.scss new file mode 100644 index 0000000..380b79f --- /dev/null +++ b/packages/theme-chalk/src/base.scss @@ -0,0 +1,2 @@ +@import "common/transition.scss"; +@import "icon.scss"; diff --git a/packages/theme-chalk/src/breadcrumb-item.scss b/packages/theme-chalk/src/breadcrumb-item.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/breadcrumb.scss b/packages/theme-chalk/src/breadcrumb.scss new file mode 100644 index 0000000..3c3c3e1 --- /dev/null +++ b/packages/theme-chalk/src/breadcrumb.scss @@ -0,0 +1,55 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "common/var"; + +@include b(breadcrumb) { + font-size: 14px; + line-height: 1; + @include utils-clearfix; + + @include e(separator) { + margin: 0 9px; + font-weight: bold; + color: $--color-text-placeholder; + + &[class*=icon] { + margin: 0 6px; + font-weight: normal; + } + } + + @include e(item) { + float: left; + + @include e(inner) { + color: $--color-text-regular; + + &.is-link, & a { + font-weight: bold; + text-decoration: none; + transition: $--color-transition-base; + color: $--color-text-primary; + + &:hover { + color: $--color-primary; + cursor: pointer; + } + } + } + + &:last-child { + .el-breadcrumb__inner, + .el-breadcrumb__inner a { + &, &:hover { + font-weight: normal; + color: $--color-text-regular; + cursor: text; + } + } + + .el-breadcrumb__separator { + display: none; + } + } + } +} diff --git a/packages/theme-chalk/src/button-group.scss b/packages/theme-chalk/src/button-group.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/button.scss b/packages/theme-chalk/src/button.scss new file mode 100644 index 0000000..52c8767 --- /dev/null +++ b/packages/theme-chalk/src/button.scss @@ -0,0 +1,260 @@ +@charset "UTF-8"; +@import "common/var"; +@import "mixins/button"; +@import "mixins/mixins"; +@import "mixins/utils"; + +@include b(button) { + display: inline-block; + line-height: 1; + white-space: nowrap; + cursor: pointer; + background: $--button-default-background-color; + border: $--border-base; + border-color: $--button-default-border-color; + color: $--button-default-font-color; + -webkit-appearance: none; + text-align: center; + box-sizing: border-box; + outline: none; + margin: 0; + transition: .1s; + font-weight: $--button-font-weight; + @include utils-user-select(none); + & + & { + margin-left: 10px; + } + + @include button-size($--button-padding-vertical, $--button-padding-horizontal, $--button-font-size, $--button-border-radius); + + &:hover, + &:focus { + color: $--color-primary; + border-color: $--color-primary-light-7; + background-color: $--color-primary-light-9; + } + + &:active { + color: mix($--color-black, $--color-primary, $--button-active-shade-percent); + border-color: mix($--color-black, $--color-primary, $--button-active-shade-percent); + outline: none; + } + + &::-moz-focus-inner { + border: 0; + } + + & [class*="el-icon-"] { + & + span { + margin-left: 5px; + } + } + + @include when(plain) { + &:hover, + &:focus { + background: $--color-white; + border-color: $--color-primary; + color: $--color-primary; + } + + &:active { + background: $--color-white; + border-color: mix($--color-black, $--color-primary, $--button-active-shade-percent); + color: mix($--color-black, $--color-primary, $--button-active-shade-percent); + outline: none; + } + } + + @include when(active) { + color: mix($--color-black, $--color-primary, $--button-active-shade-percent); + border-color: mix($--color-black, $--color-primary, $--button-active-shade-percent); + } + + @include when(disabled) { + &, + &:hover, + &:focus { + color: $--button-disabled-font-color; + cursor: not-allowed; + background-image: none; + background-color: $--button-disabled-background-color; + border-color: $--button-disabled-border-color; + } + + &.el-button--text { + background-color: transparent; + } + + &.is-plain { + &, + &:hover, + &:focus { + background-color: $--color-white; + border-color: $--button-disabled-border-color; + color: $--button-disabled-font-color; + } + } + } + + @include when(loading) { + position: relative; + pointer-events: none; + + &:before { + pointer-events: none; + content: ''; + position: absolute; + left: -1px; + top: -1px; + right: -1px; + bottom: -1px; + border-radius: inherit; + background-color: rgba(255,255,255,.35); + } + } + @include when(round) { + border-radius: 20px; + padding: 12px 23px; + } + @include when(circle) { + border-radius: 50%; + padding: $--button-padding-vertical; + } + @include m(primary) { + @include button-variant($--button-primary-font-color, $--button-primary-background-color, $--button-primary-border-color); + } + @include m(success) { + @include button-variant($--button-success-font-color, $--button-success-background-color, $--button-success-border-color); + } + @include m(warning) { + @include button-variant($--button-warning-font-color, $--button-warning-background-color, $--button-warning-border-color); + } + @include m(danger) { + @include button-variant($--button-danger-font-color, $--button-danger-background-color, $--button-danger-border-color); + } + @include m(info) { + @include button-variant($--button-info-font-color, $--button-info-background-color, $--button-info-border-color); + } + @include m(medium) { + @include button-size($--button-medium-padding-vertical, $--button-medium-padding-horizontal, $--button-medium-font-size, $--button-medium-border-radius); + @include when(circle) { + padding: $--button-medium-padding-vertical; + } + } + @include m(small) { + @include button-size($--button-small-padding-vertical, $--button-small-padding-horizontal, $--button-small-font-size, $--button-small-border-radius); + @include when(circle) { + padding: $--button-small-padding-vertical; + } + } + @include m(mini) { + @include button-size($--button-mini-padding-vertical, $--button-mini-padding-horizontal, $--button-mini-font-size, $--button-mini-border-radius); + @include when(circle) { + padding: $--button-mini-padding-vertical; + } + } + @include m(text) { + border-color: transparent; + color: $--color-primary; + background: transparent; + padding-left: 0; + padding-right: 0; + + &:hover, + &:focus { + color: mix($--color-white, $--color-primary, $--button-hover-tint-percent); + border-color: transparent; + background-color: transparent; + } + &:active { + color: mix($--color-black, $--color-primary, $--button-active-shade-percent); + border-color: transparent; + background-color: transparent; + } + + &.is-disabled, + &.is-disabled:hover, + &.is-disabled:focus { + border-color: transparent; + } + } +} + +@include b(button-group) { + @include utils-clearfix; + display: inline-block; + vertical-align: middle; + + & > .el-button { + float: left; + position: relative; + & + .el-button { + margin-left: 0; + } + &.is-disabled { + z-index: 1; + } + &:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + &:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + &:first-child:last-child { + border-top-right-radius: $--button-border-radius; + border-bottom-right-radius: $--button-border-radius; + border-top-left-radius: $--button-border-radius; + border-bottom-left-radius: $--button-border-radius; + + &.is-round { + border-radius: 20px; + } + + &.is-circle { + border-radius: 50%; + } + } + &:not(:first-child):not(:last-child) { + border-radius: 0; + } + &:not(:last-child) { + margin-right: -1px; + } + + &:hover, + &:focus, + &:active { + z-index: 1; + } + + @include when(active) { + z-index: 1; + } + } + + & > .el-dropdown { + & > .el-button { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-left-color: rgba($--color-white, 0.5); + } + } + + @each $type in (primary, success, warning, danger, info) { + .el-button--#{$type} { + &:first-child { + border-right-color: rgba($--color-white, 0.5); + } + &:last-child { + border-left-color: rgba($--color-white, 0.5); + } + &:not(:first-child):not(:last-child) { + border-left-color: rgba($--color-white, 0.5); + border-right-color: rgba($--color-white, 0.5); + } + } + } +} diff --git a/packages/theme-chalk/src/calendar.scss b/packages/theme-chalk/src/calendar.scss new file mode 100644 index 0000000..1364861 --- /dev/null +++ b/packages/theme-chalk/src/calendar.scss @@ -0,0 +1,79 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "button"; +@import "button-group"; + +@include b(calendar) { + background-color:#fff; + + @include e(header) { + display: flex; + justify-content: space-between; + padding: 12px 20px; + border-bottom: $--table-border; + } + + @include e(title) { + color: #000000; + align-self: center; + } + + @include e(body) { + padding: 12px 20px 35px; + } +} + +@include b(calendar-table) { + table-layout: fixed; + width: 100%; + + thead th { + padding: 12px 0; + color: $--color-text-regular; + font-weight: normal; + } + + &:not(.is-range) { + td.prev, + td.next { + color: $--color-text-placeholder; + } + } + + td { + border-bottom: $--calendar-border; + border-right: $--calendar-border; + vertical-align: top; + transition: background-color 0.2s ease; + + @include when(selected) { + background-color: $--calendar-selected-background-color; + } + + @include when(today) { + color: $--color-primary; + } + } + + tr:first-child td { + border-top: $--calendar-border; + } + + tr td:first-child { + border-left: $--calendar-border; + } + + tr.el-calendar-table__row--hide-border td { + border-top: none; + } + + @include b(calendar-day) { + box-sizing: border-box; + padding: 8px; + height: $--calendar-cell-width; + &:hover { + cursor: pointer; + background-color: $--calendar-selected-background-color; + } + } +} diff --git a/packages/theme-chalk/src/card.scss b/packages/theme-chalk/src/card.scss new file mode 100644 index 0000000..1a5b247 --- /dev/null +++ b/packages/theme-chalk/src/card.scss @@ -0,0 +1,32 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(card) { + border-radius: $--card-border-radius; + border: 1px solid $--card-border-color; + background-color: $--color-white; + overflow: hidden; + color: $--color-text-primary; + transition: 0.3s; + + @include when(always-shadow) { + box-shadow: $--box-shadow-light; + } + + @include when(hover-shadow) { + &:hover, + &:focus { + box-shadow: $--box-shadow-light; + } + } + + @include e(header) { + padding: #{$--card-padding - 2 $--card-padding}; + border-bottom: 1px solid $--card-border-color; + box-sizing: border-box; + } + + @include e(body) { + padding: $--card-padding; + } +} diff --git a/packages/theme-chalk/src/carousel-item.scss b/packages/theme-chalk/src/carousel-item.scss new file mode 100644 index 0000000..6280ebd --- /dev/null +++ b/packages/theme-chalk/src/carousel-item.scss @@ -0,0 +1,50 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(carousel) { + @include e(item) { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: inline-block; + overflow: hidden; + z-index: #{$--index-normal - 1}; + + @include when(active) { + z-index: #{$--index-normal + 1}; + } + + @include when(animating) { + transition: transform .4s ease-in-out; + } + + @include m(card) { + width: 50%; + transition: transform .4s ease-in-out; + &.is-in-stage { + cursor: pointer; + z-index: $--index-normal; + &:hover .el-carousel__mask, + &.is-hover .el-carousel__mask { + opacity: 0.12; + } + } + &.is-active { + z-index: #{$--index-normal + 1}; + } + } + } + + @include e(mask) { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + background-color: $--color-white; + opacity: 0.24; + transition: .2s; + } +} \ No newline at end of file diff --git a/packages/theme-chalk/src/carousel.scss b/packages/theme-chalk/src/carousel.scss new file mode 100644 index 0000000..cfca962 --- /dev/null +++ b/packages/theme-chalk/src/carousel.scss @@ -0,0 +1,161 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(carousel) { + position: relative; + + @include m(horizontal) { + overflow-x: hidden; + } + + @include m(vertical) { + overflow-y: hidden; + } + + @include e(container) { + position: relative; + height: 300px; + } + + @include e(arrow) { + border: none; + outline: none; + padding: 0; + margin: 0; + height: $--carousel-arrow-size; + width: $--carousel-arrow-size; + cursor: pointer; + transition: .3s; + border-radius: 50%; + background-color: $--carousel-arrow-background; + color: $--color-white; + position: absolute; + top: 50%; + z-index: 10; + transform: translateY(-50%); + text-align: center; + font-size: $--carousel-arrow-font-size; + + @include m(left) { + left: 16px; + } + + @include m(right) { + right: 16px; + } + + &:hover { + background-color: $--carousel-arrow-hover-background; + } + + & i { + cursor: pointer; + } + } + + @include e(indicators) { + position: absolute; + list-style: none; + margin: 0; + padding: 0; + z-index: #{$--index-normal + 1}; + + @include m(horizontal) { + bottom: 0; + left: 50%; + transform: translateX(-50%); + } + + @include m(vertical) { + right: 0; + top: 50%; + transform: translateY(-50%); + } + + @include m(outside) { + bottom: #{$--carousel-indicator-height + $--carousel-indicator-padding-vertical * 2}; + text-align: center; + position: static; + transform: none; + .el-carousel__indicator:hover button { + opacity: 0.64; + } + button { + background-color: $--carousel-indicator-out-color; + opacity: 0.24; + } + } + + @include m(labels) { + left: 0; + right: 0; + transform: none; + text-align: center; + + .el-carousel__button { + height: auto; + width: auto; + padding: 2px 18px; + font-size: 12px; + } + + .el-carousel__indicator { + padding: 6px 4px; + } + } + } + + @include e(indicator) { + background-color: transparent; + cursor: pointer; + + &:hover button { + opacity: 0.72; + } + + @include m(horizontal) { + display: inline-block; + padding: $--carousel-indicator-padding-vertical $--carousel-indicator-padding-horizontal; + } + + @include m(vertical) { + padding: $--carousel-indicator-padding-horizontal $--carousel-indicator-padding-vertical; + .el-carousel__button { + width: $--carousel-indicator-height; + height: #{$--carousel-indicator-width / 2}; + } + } + + @include when(active) { + button { + opacity: 1; + } + } + } + + @include e(button) { + display: block; + opacity: 0.48; + width: $--carousel-indicator-width; + height: $--carousel-indicator-height; + background-color: $--color-white; + border: none; + outline: none; + padding: 0; + margin: 0; + cursor: pointer; + transition: .3s; + } +} + +.carousel-arrow-left-enter, +.carousel-arrow-left-leave-active { + transform: translateY(-50%) translateX(-10px); + opacity: 0; +} + +.carousel-arrow-right-enter, +.carousel-arrow-right-leave-active { + transform: translateY(-50%) translateX(10px); + opacity: 0; +} diff --git a/packages/theme-chalk/src/cascader-panel.scss b/packages/theme-chalk/src/cascader-panel.scss new file mode 100644 index 0000000..7fca5a0 --- /dev/null +++ b/packages/theme-chalk/src/cascader-panel.scss @@ -0,0 +1,120 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "./checkbox"; +@import "./radio"; +@import "./scrollbar"; + +@include b(cascader-panel) { + display: flex; + border-radius: $--cascader-menu-radius; + font-size: $--cascader-menu-font-size; + + @include when(bordered) { + border: $--cascader-menu-border; + border-radius: $--cascader-menu-radius; + } +} + +@include b(cascader-menu) { + min-width: 180px; + box-sizing: border-box; + color: $--cascader-menu-font-color; + border-right: $--cascader-menu-border; + + &:last-child { + border-right: none; + .el-cascader-node { + padding-right: 20px; + } + } + + @include e(wrap) { + height: 204px; + } + + @include e(list) { + position: relative; + min-height: 100%; + margin: 0; + padding: 6px 0; + list-style: none; + box-sizing: border-box; + } + + @include e(hover-zone) { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + } + + @include e(empty-text) { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; + color: $--cascader-color-empty; + } +} + +@include b(cascader-node) { + position: relative; + display: flex; + align-items: center; + padding: 0 30px 0 20px; + height: 34px; + line-height: 34px; + outline: none; + + &.is-selectable.in-active-path { + color: $--cascader-menu-font-color; + } + + &.in-active-path, + &.is-selectable.in-checked-path, + &.is-active { + color: $--cascader-menu-selected-font-color; + font-weight: bold; + } + + &:not(.is-disabled) { + cursor: pointer; + &:hover, &:focus { + background: $--cascader-node-background-hover; + } + } + + @include when(disabled) { + color: $--cascader-node-color-disabled; + cursor: not-allowed; + } + + @include e(prefix) { + position: absolute; + left: 10px; + } + + @include e(postfix) { + position: absolute; + right: 10px; + } + + @include e(label) { + flex: 1; + padding: 0 10px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + > .el-radio { + margin-right: 0; + + .el-radio__label { + padding-left: 0; + } + } +} diff --git a/packages/theme-chalk/src/cascader.scss b/packages/theme-chalk/src/cascader.scss new file mode 100644 index 0000000..5c883ea --- /dev/null +++ b/packages/theme-chalk/src/cascader.scss @@ -0,0 +1,182 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "./input"; +@import "./popper"; +@import "./tag"; +@import "./cascader-panel"; + +@include b(cascader) { + display: inline-block; + position: relative; + font-size: $--font-size-base; + line-height: $--input-height; + + &:not(.is-disabled):hover { + .el-input__inner { + cursor: pointer; + border-color: $--input-hover-border; + } + } + + .el-input { + cursor: pointer; + + .el-input__inner { + text-overflow: ellipsis; + + &:focus { + border-color: $--input-focus-border; + } + } + + .el-icon-arrow-down { + transition: transform .3s; + font-size: 14px; + + @include when(reverse) { + transform: rotateZ(180deg); + } + } + + .el-icon-circle-close:hover { + color: $--input-clear-hover-color; + } + + @include when(focus) { + .el-input__inner { + border-color: $--input-focus-border; + } + } + } + + @include m(medium) { + font-size: $--input-medium-font-size; + line-height: $--input-medium-height; + } + + @include m(small) { + font-size: $--input-small-font-size; + line-height: $--input-small-height; + } + + @include m(mini) { + font-size: $--input-mini-font-size; + line-height: $--input-mini-height; + } + + @include when(disabled) { + .el-cascader__label { + z-index: #{$--index-normal + 1}; + color: $--disabled-color-base; + } + } + + @include e(dropdown) { + margin: 5px 0; + font-size: $--cascader-menu-font-size; + background: $--cascader-menu-fill; + border: $--cascader-menu-border; + border-radius: $--cascader-menu-radius; + box-shadow: $--cascader-menu-shadow; + } + + @include e(tags) { + position: absolute; + left: 0; + right: 30px; + top: 50%; + transform: translateY(-50%); + display: flex; + flex-wrap: wrap; + line-height: normal; + text-align: left; + box-sizing: border-box; + + .el-tag { + display: inline-flex; + align-items: center; + max-width: 100%; + margin: 2px 0 2px 6px; + text-overflow: ellipsis; + background: $--cascader-tag-background; + + &:not(.is-hit) { + border-color: transparent; + } + + > span { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + } + + .el-icon-close { + flex: none; + background-color: $--color-text-placeholder; + color: $--color-white; + + &:hover { + background-color: $--color-text-secondary; + } + } + } + } + + @include e(suggestion-panel) { + border-radius: $--cascader-menu-radius; + } + + @include e(suggestion-list) { + max-height: 204px; + margin: 0; + padding: 6px 0; + font-size: $--font-size-base; + color: $--cascader-menu-font-color; + text-align: center; + } + + @include e(suggestion-item) { + display: flex; + justify-content: space-between; + align-items: center; + height: 34px; + padding: 0 15px; + text-align: left; + outline: none; + cursor: pointer; + + &:hover, &:focus { + background: $--cascader-node-background-hover; + } + + &.is-checked { + color: $--cascader-menu-selected-font-color; + font-weight: bold; + } + + > span { + margin-right: 10px; + } + } + + @include e(empty-text) { + margin: 10px 0; + color: $--cascader-color-empty; + } + + @include e(search-input) { + flex: 1; + height: 24px; + min-width: 60px; + margin: 2px 0 2px 15px; + padding: 0; + color: $--cascader-menu-font-color; + border: none; + outline: none; + box-sizing: border-box; + + &::placeholder { + color: $--color-text-placeholder; + } + } +} diff --git a/packages/theme-chalk/src/checkbox-button.scss b/packages/theme-chalk/src/checkbox-button.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/checkbox-group.scss b/packages/theme-chalk/src/checkbox-group.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/checkbox.scss b/packages/theme-chalk/src/checkbox.scss new file mode 100644 index 0000000..7c1b938 --- /dev/null +++ b/packages/theme-chalk/src/checkbox.scss @@ -0,0 +1,359 @@ +@import "common/var"; +@import "mixins/mixins"; +@import "mixins/_button"; +@import "mixins/utils"; + +@include b(checkbox) { + color: $--checkbox-font-color; + font-weight: $--checkbox-font-weight; + font-size: $--font-size-base; + position: relative; + cursor: pointer; + display: inline-block; + white-space: nowrap; + user-select: none; + margin-right: 30px; + + @include when(bordered) { + padding: $--checkbox-bordered-padding; + border-radius: $--border-radius-base; + border: $--border-base; + box-sizing: border-box; + line-height: normal; + height: $--checkbox-bordered-height; + + &.is-checked { + border-color: $--color-primary; + } + + &.is-disabled { + border-color: $--border-color-lighter; + cursor: not-allowed; + } + + & + .el-checkbox.is-bordered { + margin-left: 10px; + } + + &.el-checkbox--medium { + padding: $--checkbox-bordered-medium-padding; + border-radius: $--button-medium-border-radius; + height: $--checkbox-bordered-medium-height; + + .el-checkbox__label { + line-height: 17px; + font-size: $--button-medium-font-size; + } + + .el-checkbox__inner { + height: $--checkbox-bordered-medium-input-height; + width: $--checkbox-bordered-medium-input-width; + } + } + + &.el-checkbox--small { + padding: $--checkbox-bordered-small-padding; + border-radius: $--button-small-border-radius; + height: $--checkbox-bordered-small-height; + + .el-checkbox__label { + line-height: 15px; + font-size: $--button-small-font-size; + } + + .el-checkbox__inner { + height: $--checkbox-bordered-small-input-height; + width: $--checkbox-bordered-small-input-width; + + &::after { + height: 6px; + width: 2px; + } + } + } + + &.el-checkbox--mini { + padding: $--checkbox-bordered-mini-padding; + border-radius: $--button-mini-border-radius; + height: $--checkbox-bordered-mini-height; + + .el-checkbox__label { + line-height: 12px; + font-size: $--button-mini-font-size; + } + + .el-checkbox__inner { + height: $--checkbox-bordered-mini-input-height; + width: $--checkbox-bordered-mini-input-width; + &::after { + height: 6px; + width: 2px; + } + } + } + } + + @include e(input) { + white-space: nowrap; + cursor: pointer; + outline: none; + display: inline-block; + line-height: 1; + position: relative; + vertical-align: middle; + + @include when(disabled) { + .el-checkbox__inner { + background-color: $--checkbox-disabled-input-fill; + border-color: $--checkbox-disabled-border-color; + cursor: not-allowed; + + &::after { + cursor: not-allowed; + border-color: $--checkbox-disabled-icon-color; + } + + & + .el-checkbox__label { + cursor: not-allowed; + } + } + + &.is-checked { + .el-checkbox__inner { + background-color: $--checkbox-disabled-checked-input-fill; + border-color: $--checkbox-disabled-checked-input-border-color; + + &::after { + border-color: $--checkbox-disabled-checked-icon-color; + } + } + } + + &.is-indeterminate { + .el-checkbox__inner { + background-color: $--checkbox-disabled-checked-input-fill; + border-color: $--checkbox-disabled-checked-input-border-color; + + &::before { + background-color: $--checkbox-disabled-checked-icon-color; + border-color: $--checkbox-disabled-checked-icon-color; + } + } + } + + & + span.el-checkbox__label { + color: $--disabled-color-base; + cursor: not-allowed; + } + } + + @include when(checked) { + .el-checkbox__inner { + background-color: $--checkbox-checked-background-color; + border-color: $--checkbox-checked-input-border-color; + + &::after { + transform: rotate(45deg) scaleY(1); + } + } + + & + .el-checkbox__label { + color: $--checkbox-checked-font-color; + } + } + @include when(focus) { /*focus时 视觉上区分*/ + .el-checkbox__inner { + border-color: $--checkbox-input-border-color-hover; + } + } + @include when(indeterminate) { + .el-checkbox__inner { + background-color: $--checkbox-checked-background-color; + border-color: $--checkbox-checked-input-border-color; + + &::before { + content: ''; + position: absolute; + display: block; + background-color: $--checkbox-checked-icon-color; + height: 2px; + transform: scale(0.5); + left: 0; + right: 0; + top: 5px; + } + + &::after { + display: none; + } + } + } + } + @include e(inner) { + display: inline-block; + position: relative; + border: $--checkbox-input-border; + border-radius: $--checkbox-border-radius; + box-sizing: border-box; + width: $--checkbox-input-width; + height: $--checkbox-input-height; + background-color: $--checkbox-background-color; + z-index: $--index-normal; + transition: border-color .25s cubic-bezier(.71,-.46,.29,1.46), + background-color .25s cubic-bezier(.71,-.46,.29,1.46); + + &:hover { + border-color: $--checkbox-input-border-color-hover; + } + + &::after { + box-sizing: content-box; + content: ""; + border: 1px solid $--checkbox-checked-icon-color; + border-left: 0; + border-top: 0; + height: 7px; + left: 4px; + position: absolute; + top: 1px; + transform: rotate(45deg) scaleY(0); + width: 3px; + transition: transform .15s ease-in .05s; + transform-origin: center; + } + } + + @include e(original) { + opacity: 0; + outline: none; + position: absolute; + margin: 0; + width: 0; + height: 0; + z-index: -1; + } + + @include e(label) { + display: inline-block; + padding-left: 10px; + line-height: 19px; + font-size: $--checkbox-font-size; + } + + &:last-of-type { + margin-right: 0; + } +} + +@include b(checkbox-button) { + position: relative; + display: inline-block; + + @include e(inner) { + display: inline-block; + line-height: 1; + font-weight: $--checkbox-font-weight; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + background: $--button-default-background-color; + border: $--border-base; + border-left: 0; + color: $--button-default-font-color; + -webkit-appearance: none; + text-align: center; + box-sizing: border-box; + outline: none; + margin: 0; + position: relative; + transition: $--all-transition; + @include utils-user-select(none); + + @include button-size($--button-padding-vertical, $--button-padding-horizontal, $--button-font-size, 0); + + &:hover { + color: $--color-primary; + } + + & [class*="el-icon-"] { + line-height: 0.9; + + & + span { + margin-left: 5px; + } + } + } + + @include e(original) { + opacity: 0; + outline: none; + position: absolute; + margin: 0; + z-index: -1; + } + + &.is-checked { + & .el-checkbox-button__inner { + color: $--checkbox-button-checked-font-color; + background-color: $--checkbox-button-checked-background-color; + border-color: $--checkbox-button-checked-border-color; + box-shadow: -1px 0 0 0 $--color-primary-light-4; + } + &:first-child .el-checkbox-button__inner { + border-left-color: $--checkbox-button-checked-border-color; + } + } + + &.is-disabled { + & .el-checkbox-button__inner { + color: $--button-disabled-font-color; + cursor: not-allowed; + background-image: none; + background-color: $--button-disabled-background-color; + border-color: $--button-disabled-border-color; + box-shadow: none; + } + &:first-child .el-checkbox-button__inner { + border-left-color: $--button-disabled-border-color; + } + } + + &:first-child { + .el-checkbox-button__inner { + border-left: $--border-base; + border-radius: $--border-radius-base 0 0 $--border-radius-base; + box-shadow: none !important; + } + } + + &.is-focus { + & .el-checkbox-button__inner { + border-color: $--checkbox-button-checked-border-color; + } + } + + &:last-child { + .el-checkbox-button__inner { + border-radius: 0 $--border-radius-base $--border-radius-base 0; + } + } + @include m(medium) { + .el-checkbox-button__inner { + @include button-size($--button-medium-padding-vertical, $--button-medium-padding-horizontal, $--button-medium-font-size, 0); + } + } + @include m(small) { + .el-checkbox-button__inner { + @include button-size($--button-small-padding-vertical, $--button-small-padding-horizontal, $--button-small-font-size, 0); + } + } + @include m(mini) { + .el-checkbox-button__inner { + @include button-size($--button-mini-padding-vertical, $--button-mini-padding-horizontal, $--button-mini-font-size, 0); + } + } +} + +@include b(checkbox-group) { + font-size: 0; +} diff --git a/packages/theme-chalk/src/col.scss b/packages/theme-chalk/src/col.scss new file mode 100644 index 0000000..c2a3387 --- /dev/null +++ b/packages/theme-chalk/src/col.scss @@ -0,0 +1,156 @@ +@import "./common/var.scss"; +@import "./mixins/mixins.scss"; + +[class*="el-col-"] { + float: left; + box-sizing: border-box; +} + +.el-col-0 { + display: none; +} + +@for $i from 0 through 24 { + .el-col-#{$i} { + width: (1 / 24 * $i * 100) * 1%; + } + + .el-col-offset-#{$i} { + margin-left: (1 / 24 * $i * 100) * 1%; + } + + .el-col-pull-#{$i} { + position: relative; + right: (1 / 24 * $i * 100) * 1%; + } + + .el-col-push-#{$i} { + position: relative; + left: (1 / 24 * $i * 100) * 1%; + } +} + +@include res(xs) { + .el-col-xs-0 { + display: none; + } + @for $i from 0 through 24 { + .el-col-xs-#{$i} { + width: (1 / 24 * $i * 100) * 1%; + } + + .el-col-xs-offset-#{$i} { + margin-left: (1 / 24 * $i * 100) * 1%; + } + + .el-col-xs-pull-#{$i} { + position: relative; + right: (1 / 24 * $i * 100) * 1%; + } + + .el-col-xs-push-#{$i} { + position: relative; + left: (1 / 24 * $i * 100) * 1%; + } + } +} + +@include res(sm) { + .el-col-sm-0 { + display: none; + } + @for $i from 0 through 24 { + .el-col-sm-#{$i} { + width: (1 / 24 * $i * 100) * 1%; + } + + .el-col-sm-offset-#{$i} { + margin-left: (1 / 24 * $i * 100) * 1%; + } + + .el-col-sm-pull-#{$i} { + position: relative; + right: (1 / 24 * $i * 100) * 1%; + } + + .el-col-sm-push-#{$i} { + position: relative; + left: (1 / 24 * $i * 100) * 1%; + } + } +} + +@include res(md) { + .el-col-md-0 { + display: none; + } + @for $i from 0 through 24 { + .el-col-md-#{$i} { + width: (1 / 24 * $i * 100) * 1%; + } + + .el-col-md-offset-#{$i} { + margin-left: (1 / 24 * $i * 100) * 1%; + } + + .el-col-md-pull-#{$i} { + position: relative; + right: (1 / 24 * $i * 100) * 1%; + } + + .el-col-md-push-#{$i} { + position: relative; + left: (1 / 24 * $i * 100) * 1%; + } + } +} + +@include res(lg) { + .el-col-lg-0 { + display: none; + } + @for $i from 0 through 24 { + .el-col-lg-#{$i} { + width: (1 / 24 * $i * 100) * 1%; + } + + .el-col-lg-offset-#{$i} { + margin-left: (1 / 24 * $i * 100) * 1%; + } + + .el-col-lg-pull-#{$i} { + position: relative; + right: (1 / 24 * $i * 100) * 1%; + } + + .el-col-lg-push-#{$i} { + position: relative; + left: (1 / 24 * $i * 100) * 1%; + } + } +} + +@include res(xl) { + .el-col-xl-0 { + display: none; + } + @for $i from 0 through 24 { + .el-col-xl-#{$i} { + width: (1 / 24 * $i * 100) * 1%; + } + + .el-col-xl-offset-#{$i} { + margin-left: (1 / 24 * $i * 100) * 1%; + } + + .el-col-xl-pull-#{$i} { + position: relative; + right: (1 / 24 * $i * 100) * 1%; + } + + .el-col-xl-push-#{$i} { + position: relative; + left: (1 / 24 * $i * 100) * 1%; + } + } +} \ No newline at end of file diff --git a/packages/theme-chalk/src/collapse-item.scss b/packages/theme-chalk/src/collapse-item.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/collapse.scss b/packages/theme-chalk/src/collapse.scss new file mode 100644 index 0000000..ffe78f3 --- /dev/null +++ b/packages/theme-chalk/src/collapse.scss @@ -0,0 +1,63 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "common/transition"; + +@include b(collapse) { + border-top: 1px solid $--collapse-border-color; + border-bottom: 1px solid $--collapse-border-color; +} +@include b(collapse-item) { + @include when(disabled) { + .el-collapse-item__header { + color: $--font-color-disabled-base; + cursor: not-allowed; + } + } + @include e(header) { + display: flex; + align-items: center; + height: $--collapse-header-height; + line-height: $--collapse-header-height; + background-color: $--collapse-header-background-color; + color: $--collapse-header-font-color; + cursor: pointer; + border-bottom: 1px solid $--collapse-border-color; + font-size: $--collapse-header-font-size; + font-weight: 500; + transition: border-bottom-color .3s; + outline: none; + @include e(arrow) { + margin: 0 8px 0 auto; + transition: transform .3s; + font-weight: 300; + @include when(active) { + transform: rotate(90deg); + } + } + &.focusing:focus:not(:hover){ + color: $--color-primary; + } + @include when(active) { + border-bottom-color: transparent; + } + } + + @include e(wrap) { + will-change: height; + background-color: $--collapse-content-background-color; + overflow: hidden; + box-sizing: border-box; + border-bottom: 1px solid $--collapse-border-color; + } + + @include e(content) { + padding-bottom: 25px; + font-size: $--collapse-content-font-size; + color: $--collapse-content-font-color; + line-height: 1.769230769230769; + } + + &:last-child { + margin-bottom: -1px; + } +} diff --git a/packages/theme-chalk/src/color-picker.scss b/packages/theme-chalk/src/color-picker.scss new file mode 100644 index 0000000..ee92d9f --- /dev/null +++ b/packages/theme-chalk/src/color-picker.scss @@ -0,0 +1,384 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(color-predefine) { + display: flex; + font-size: 12px; + margin-top: 8px; + width: 280px; + + @include e(colors) { + display: flex; + flex: 1; + flex-wrap: wrap; + } + + @include e(color-selector) { + margin: 0 0 8px 8px; + width: 20px; + height: 20px; + border-radius: 4px; + cursor: pointer; + + &:nth-child(10n + 1) { + margin-left: 0; + } + + &.selected { + box-shadow: 0 0 3px 2px $--color-primary; + } + + > div { + display: flex; + height: 100%; + border-radius: 3px; + } + + @include when(alpha) { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); + } + } +} + +@include b(color-hue-slider) { + position: relative; + box-sizing: border-box; + width: 280px; + height: 12px; + background-color: #f00; + padding: 0 2px; + + @include e(bar) { + position: relative; + background: linear-gradient( + to right, #f00 0%, + #ff0 17%, #0f0 33%, + #0ff 50%, #00f 67%, + #f0f 83%, #f00 100%); + height: 100%; + } + + @include e(thumb) { + position: absolute; + cursor: pointer; + box-sizing: border-box; + left: 0; + top: 0; + width: 4px; + height: 100%; + border-radius: 1px; + background: #fff; + border: 1px solid #f0f0f0; + box-shadow: 0 0 2px rgba(0, 0, 0, 0.6); + z-index: 1; + } + + @include when(vertical) { + width: 12px; + height: 180px; + padding: 2px 0; + + .el-color-hue-slider__bar { + background: linear-gradient( + to bottom, #f00 0%, + #ff0 17%, #0f0 33%, + #0ff 50%, #00f 67%, + #f0f 83%, #f00 100%); + } + + .el-color-hue-slider__thumb { + left: 0; + top: 0; + width: 100%; + height: 4px; + } + } +} + +@include b(color-svpanel) { + position: relative; + width: 280px; + height: 180px; + + @include e(('white', 'black')) { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + } + + @include e('white') { + background: linear-gradient(to right, #fff, rgba(255,255,255,0)); + } + + @include e('black') { + background: linear-gradient(to top, #000, rgba(0,0,0,0)); + } + + @include e(cursor) { + position: absolute; + + > div { + cursor: head; + width: 4px; + height: 4px; + box-shadow: 0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0,0,0,0.3), 0 0 1px 2px rgba(0,0,0,0.4); + border-radius: 50%; + transform: translate(-2px, -2px); + } + } +} + +@include b(color-alpha-slider) { + position: relative; + box-sizing: border-box; + width: 280px; + height: 12px; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); + + @include e(bar) { + position: relative; + background: linear-gradient( + to right, rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 1) 100%); + height: 100%; + } + + @include e(thumb) { + position: absolute; + cursor: pointer; + box-sizing: border-box; + left: 0; + top: 0; + width: 4px; + height: 100%; + border-radius: 1px; + background: #fff; + border: 1px solid #f0f0f0; + box-shadow: 0 0 2px rgba(0, 0, 0, 0.6); + z-index: 1; + } + + @include when(vertical) { + width: 20px; + height: 180px; + + .el-color-alpha-slider__bar { + background: linear-gradient( + to bottom, rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 1) 100%); + } + + .el-color-alpha-slider__thumb { + left: 0; + top: 0; + width: 100%; + height: 4px; + } + } +} + +@include b(color-dropdown) { + width: 300px; + + @include e(main-wrapper) { + margin-bottom: 6px; + + &::after { + content: ""; + display: table; + clear: both; + } + } + + @include e(btns) { + margin-top: 6px; + text-align: right; + } + + @include e(value) { + float: left; + line-height: 26px; + font-size: 12px; + color: $--color-black; + width: 160px; + } + + @include e(btn) { + border: 1px solid #dcdcdc; + color: #333; + line-height: 24px; + border-radius: 2px; + padding: 0 20px; + cursor: pointer; + background-color: transparent; + outline: none; + font-size: 12px; + + &[disabled] { + color: #cccccc; + cursor: not-allowed; + } + &:hover { + color: $--color-primary; + border-color: $--color-primary; + } + } + + @include e(link-btn) { + cursor: pointer; + color: $--color-primary; + text-decoration: none; + padding: 15px; + font-size: 12px; + &:hover { + color: tint($--color-primary, $--button-hover-tint-percent); + } + } +} + +@include b(color-picker) { + display: inline-block; + position: relative; + line-height: normal; + height: 40px; + + @include when(disabled) { + .el-color-picker__trigger { + cursor: not-allowed; + } + } + + @include m(medium) { + height: 36px; + + .el-color-picker__trigger { + height: 36px; + width: 36px; + } + + .el-color-picker__mask { + height: 34px; + width: 34px; + } + } + + @include m(small) { + height: 32px; + + .el-color-picker__trigger { + height: 32px; + width: 32px; + } + + .el-color-picker__mask { + height: 30px; + width: 30px; + } + + .el-color-picker__icon, + .el-color-picker__empty { + transform: translate3d(-50%, -50%, 0) scale(0.8); + } + } + + @include m(mini) { + height: 28px; + + .el-color-picker__trigger { + height: 28px; + width: 28px; + } + + .el-color-picker__mask { + height: 26px; + width: 26px; + } + + .el-color-picker__icon, + .el-color-picker__empty { + transform: translate3d(-50%, -50%, 0) scale(0.8); + } + } + + @include e(mask) { + height: 38px; + width: 38px; + border-radius: 4px; + position: absolute; + top: 1px; + left: 1px; + z-index: 1; + cursor: not-allowed; + background-color: rgba(255, 255, 255, .7); + } + + @include e(trigger) { + display: inline-block; + box-sizing: border-box; + height: 40px; + width: 40px; + padding: 4px; + border: 1px solid #e6e6e6; + border-radius: 4px; + font-size: 0; + position: relative; + cursor: pointer; + } + + @include e(color) { + position: relative; + display: block; + box-sizing: border-box; + border: 1px solid #999; + border-radius: $--border-radius-small; + width: 100%; + height: 100%; + text-align: center; + + @include when(alpha) { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); + } + } + + @include e(color-inner) { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + } + + @include e(empty) { + font-size: 12px; + color: #999; + position: absolute; + top: 50%; + left: 50%; + transform: translate3d(-50%, -50%, 0); + } + + @include e(icon) { + display: inline-block; + position: absolute; + width: 100%; + top: 50%; + left: 50%; + transform: translate3d(-50%, -50%, 0); + color: $--color-white; + text-align: center; + font-size: 12px; + } + + @include e(panel) { + position: absolute; + z-index: 10; + padding: 6px; + box-sizing: content-box; + background-color: $--color-white; + border: 1px solid $--border-color-lighter; + border-radius: $--border-radius-base; + box-shadow: $--dropdown-menu-box-shadow; + } +} diff --git a/packages/theme-chalk/src/common/popup.scss b/packages/theme-chalk/src/common/popup.scss new file mode 100644 index 0000000..00030ba --- /dev/null +++ b/packages/theme-chalk/src/common/popup.scss @@ -0,0 +1,42 @@ +@import "./var.scss"; +@import "../mixins/mixins"; + +.v-modal-enter { + animation: v-modal-in .2s ease; +} + +.v-modal-leave { + animation: v-modal-out .2s ease forwards; +} + +@keyframes v-modal-in { + 0% { + opacity: 0; + } + 100% { + } +} + +@keyframes v-modal-out { + 0% { + } + 100% { + opacity: 0; + } +} + +.v-modal { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + opacity: $--popup-modal-opacity; + background: $--popup-modal-background-color; +} + +@include b(popup-parent) { + @include m(hidden) { + overflow: hidden; + } +} diff --git a/packages/theme-chalk/src/common/transition.scss b/packages/theme-chalk/src/common/transition.scss new file mode 100644 index 0000000..f8eb9e3 --- /dev/null +++ b/packages/theme-chalk/src/common/transition.scss @@ -0,0 +1,99 @@ +@import "var"; + +.fade-in-linear-enter-active, +.fade-in-linear-leave-active { + transition: $--fade-linear-transition; +} +.fade-in-linear-enter, +.fade-in-linear-leave, +.fade-in-linear-leave-active { + opacity: 0; +} + +.el-fade-in-linear-enter-active, +.el-fade-in-linear-leave-active { + transition: $--fade-linear-transition; +} +.el-fade-in-linear-enter, +.el-fade-in-linear-leave, +.el-fade-in-linear-leave-active { + opacity: 0; +} + +.el-fade-in-enter-active, +.el-fade-in-leave-active { + transition: all .3s cubic-bezier(.55,0,.1,1); +} +.el-fade-in-enter, +.el-fade-in-leave-active { + opacity: 0; +} + +.el-zoom-in-center-enter-active, +.el-zoom-in-center-leave-active { + transition: all .3s cubic-bezier(.55,0,.1,1); +} +.el-zoom-in-center-enter, +.el-zoom-in-center-leave-active { + opacity: 0; + transform: scaleX(0); +} + +.el-zoom-in-top-enter-active, +.el-zoom-in-top-leave-active { + opacity: 1; + transform: scaleY(1); + transition: $--md-fade-transition; + transform-origin: center top; +} +.el-zoom-in-top-enter, +.el-zoom-in-top-leave-active { + opacity: 0; + transform: scaleY(0); +} + +.el-zoom-in-bottom-enter-active, +.el-zoom-in-bottom-leave-active { + opacity: 1; + transform: scaleY(1); + transition: $--md-fade-transition; + transform-origin: center bottom; +} +.el-zoom-in-bottom-enter, +.el-zoom-in-bottom-leave-active { + opacity: 0; + transform: scaleY(0); +} + +.el-zoom-in-left-enter-active, +.el-zoom-in-left-leave-active { + opacity: 1; + transform: scale(1, 1); + transition: $--md-fade-transition; + transform-origin: top left; +} +.el-zoom-in-left-enter, +.el-zoom-in-left-leave-active { + opacity: 0; + transform: scale(.45, .45); +} + +.collapse-transition { + transition: 0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out; +} +.horizontal-collapse-transition { + transition: 0.3s width ease-in-out, 0.3s padding-left ease-in-out, 0.3s padding-right ease-in-out; +} + +.el-list-enter-active, +.el-list-leave-active { + transition: all 1s; +} +.el-list-enter, .el-list-leave-active { + opacity: 0; + transform: translateY(-30px); +} + +.el-opacity-transition { + transition: opacity .3s cubic-bezier(.55,0,.1,1); +} \ No newline at end of file diff --git a/packages/theme-chalk/src/common/var.scss b/packages/theme-chalk/src/common/var.scss new file mode 100644 index 0000000..551dbe6 --- /dev/null +++ b/packages/theme-chalk/src/common/var.scss @@ -0,0 +1,994 @@ +/* Element Chalk Variables */ + +// Special comment for theme configurator +// type|skipAutoTranslation|Category|Order +// skipAutoTranslation 1 + +/* Transition +-------------------------- */ +$--all-transition: all .3s cubic-bezier(.645,.045,.355,1) !default; +$--fade-transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !default; +$--fade-linear-transition: opacity 200ms linear !default; +$--md-fade-transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !default; +$--border-transition-base: border-color .2s cubic-bezier(.645,.045,.355,1) !default; +$--color-transition-base: color .2s cubic-bezier(.645,.045,.355,1) !default; + +/* Color +-------------------------- */ +/// color|1|Brand Color|0 +$--color-primary: #409EFF !default; +/// color|1|Background Color|4 +$--color-white: #FFFFFF !default; +/// color|1|Background Color|4 +$--color-black: #000000 !default; +$--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */ +$--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */ +$--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */ +$--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */ +$--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */ +$--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */ +$--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */ +$--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|1|Functional Color|1 +$--color-success: #67C23A !default; +/// color|1|Functional Color|1 +$--color-warning: #E6A23C !default; +/// color|1|Functional Color|1 +$--color-danger: #F56C6C !default; +/// color|1|Functional Color|1 +$--color-info: #909399 !default; + +$--color-success-light: mix($--color-white, $--color-success, 80%) !default; +$--color-warning-light: mix($--color-white, $--color-warning, 80%) !default; +$--color-danger-light: mix($--color-white, $--color-danger, 80%) !default; +$--color-info-light: mix($--color-white, $--color-info, 80%) !default; + +$--color-success-lighter: mix($--color-white, $--color-success, 90%) !default; +$--color-warning-lighter: mix($--color-white, $--color-warning, 90%) !default; +$--color-danger-lighter: mix($--color-white, $--color-danger, 90%) !default; +$--color-info-lighter: mix($--color-white, $--color-info, 90%) !default; +/// color|1|Font Color|2 +$--color-text-primary: #303133 !default; +/// color|1|Font Color|2 +$--color-text-regular: #606266 !default; +/// color|1|Font Color|2 +$--color-text-secondary: #909399 !default; +/// color|1|Font Color|2 +$--color-text-placeholder: #C0C4CC !default; +/// color|1|Border Color|3 +$--border-color-base: #DCDFE6 !default; +/// color|1|Border Color|3 +$--border-color-light: #E4E7ED !default; +/// color|1|Border Color|3 +$--border-color-lighter: #EBEEF5 !default; +/// color|1|Border Color|3 +$--border-color-extra-light: #F2F6FC !default; + +// Background +/// color|1|Background Color|4 +$--background-color-base: #F5F7FA !default; + +/* Link +-------------------------- */ +$--link-color: $--color-primary-light-2 !default; +$--link-hover-color: $--color-primary !default; + +/* Border +-------------------------- */ +$--border-width-base: 1px !default; +$--border-style-base: solid !default; +$--border-color-hover: $--color-text-placeholder !default; +$--border-base: $--border-width-base $--border-style-base $--border-color-base !default; +/// borderRadius|1|Radius|0 +$--border-radius-base: 4px !default; +/// borderRadius|1|Radius|0 +$--border-radius-small: 2px !default; +/// borderRadius|1|Radius|0 +$--border-radius-circle: 100% !default; +/// borderRadius|1|Radius|0 +$--border-radius-zero: 0 !default; + +// Box-shadow +/// boxShadow|1|Shadow|1 +$--box-shadow-base: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04) !default; +// boxShadow|1|Shadow|1 +$--box-shadow-dark: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .12) !default; +/// boxShadow|1|Shadow|1 +$--box-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !default; + +/* Fill +-------------------------- */ +$--fill-base: $--color-white !default; + +/* Typography +-------------------------- */ +$--font-path: 'fonts' !default; +$--font-display: 'auto' !default; +/// fontSize|1|Font Size|0 +$--font-size-extra-large: 20px !default; +/// fontSize|1|Font Size|0 +$--font-size-large: 18px !default; +/// fontSize|1|Font Size|0 +$--font-size-medium: 16px !default; +/// fontSize|1|Font Size|0 +$--font-size-base: 14px !default; +/// fontSize|1|Font Size|0 +$--font-size-small: 13px !default; +/// fontSize|1|Font Size|0 +$--font-size-extra-small: 12px !default; +/// fontWeight|1|Font Weight|1 +$--font-weight-primary: 500 !default; +/// fontWeight|1|Font Weight|1 +$--font-weight-secondary: 100 !default; +/// fontLineHeight|1|Line Height|2 +$--font-line-height-primary: 24px !default; +/// fontLineHeight|1|Line Height|2 +$--font-line-height-secondary: 16px !default; +$--font-color-disabled-base: #bbb !default; +/* Size +-------------------------- */ +$--size-base: 14px !default; + +/* z-index +-------------------------- */ +$--index-normal: 1 !default; +$--index-top: 1000 !default; +$--index-popper: 2000 !default; + +/* Disable base +-------------------------- */ +$--disabled-fill-base: $--background-color-base !default; +$--disabled-color-base: $--color-text-placeholder !default; +$--disabled-border-base: $--border-color-light !default; + +/* Icon +-------------------------- */ +$--icon-color: #666 !default; +$--icon-color-base: $--color-info !default; + +/* Checkbox +-------------------------- */ +/// fontSize||Font|1 +$--checkbox-font-size: 14px !default; +/// fontWeight||Font|1 +$--checkbox-font-weight: $--font-weight-primary !default; +/// color||Color|0 +$--checkbox-font-color: $--color-text-regular !default; +$--checkbox-input-height: 14px !default; +$--checkbox-input-width: 14px !default; +/// borderRadius||Border|2 +$--checkbox-border-radius: $--border-radius-small !default; +/// color||Color|0 +$--checkbox-background-color: $--color-white !default; +$--checkbox-input-border: $--border-base !default; + +/// color||Color|0 +$--checkbox-disabled-border-color: $--border-color-base !default; +$--checkbox-disabled-input-fill: #edf2fc !default; +$--checkbox-disabled-icon-color: $--color-text-placeholder !default; + +$--checkbox-disabled-checked-input-fill: $--border-color-extra-light !default; +$--checkbox-disabled-checked-input-border-color: $--border-color-base !default; +$--checkbox-disabled-checked-icon-color: $--color-text-placeholder !default; + +/// color||Color|0 +$--checkbox-checked-font-color: $--color-primary !default; +$--checkbox-checked-input-border-color: $--color-primary !default; +/// color||Color|0 +$--checkbox-checked-background-color: $--color-primary !default; +$--checkbox-checked-icon-color: $--fill-base !default; + +$--checkbox-input-border-color-hover: $--color-primary !default; +/// height||Other|4 +$--checkbox-bordered-height: 40px !default; +/// padding||Spacing|3 +$--checkbox-bordered-padding: 9px 20px 9px 10px !default; +/// padding||Spacing|3 +$--checkbox-bordered-medium-padding: 7px 20px 7px 10px !default; +/// padding||Spacing|3 +$--checkbox-bordered-small-padding: 5px 15px 5px 10px !default; +/// padding||Spacing|3 +$--checkbox-bordered-mini-padding: 3px 15px 3px 10px !default; +$--checkbox-bordered-medium-input-height: 14px !default; +$--checkbox-bordered-medium-input-width: 14px !default; +/// height||Other|4 +$--checkbox-bordered-medium-height: 36px !default; +$--checkbox-bordered-small-input-height: 12px !default; +$--checkbox-bordered-small-input-width: 12px !default; +/// height||Other|4 +$--checkbox-bordered-small-height: 32px !default; +$--checkbox-bordered-mini-input-height: 12px !default; +$--checkbox-bordered-mini-input-width: 12px !default; +/// height||Other|4 +$--checkbox-bordered-mini-height: 28px !default; + +/// color||Color|0 +$--checkbox-button-checked-background-color: $--color-primary !default; +/// color||Color|0 +$--checkbox-button-checked-font-color: $--color-white !default; +/// color||Color|0 +$--checkbox-button-checked-border-color: $--color-primary !default; + + + +/* Radio +-------------------------- */ +/// fontSize||Font|1 +$--radio-font-size: $--font-size-base !default; +/// fontWeight||Font|1 +$--radio-font-weight: $--font-weight-primary !default; +/// color||Color|0 +$--radio-font-color: $--color-text-regular !default; +$--radio-input-height: 14px !default; +$--radio-input-width: 14px !default; +/// borderRadius||Border|2 +$--radio-input-border-radius: $--border-radius-circle !default; +/// color||Color|0 +$--radio-input-background-color: $--color-white !default; +$--radio-input-border: $--border-base !default; +/// color||Color|0 +$--radio-input-border-color: $--border-color-base !default; +/// color||Color|0 +$--radio-icon-color: $--color-white !default; + +$--radio-disabled-input-border-color: $--disabled-border-base !default; +$--radio-disabled-input-fill: $--disabled-fill-base !default; +$--radio-disabled-icon-color: $--disabled-fill-base !default; + +$--radio-disabled-checked-input-border-color: $--disabled-border-base !default; +$--radio-disabled-checked-input-fill: $--disabled-fill-base !default; +$--radio-disabled-checked-icon-color: $--color-text-placeholder !default; + +/// color||Color|0 +$--radio-checked-font-color: $--color-primary !default; +/// color||Color|0 +$--radio-checked-input-border-color: $--color-primary !default; +/// color||Color|0 +$--radio-checked-input-background-color: $--color-white !default; +/// color||Color|0 +$--radio-checked-icon-color: $--color-primary !default; + +$--radio-input-border-color-hover: $--color-primary !default; + +$--radio-bordered-height: 40px !default; +$--radio-bordered-padding: 12px 20px 0 10px !default; +$--radio-bordered-medium-padding: 10px 20px 0 10px !default; +$--radio-bordered-small-padding: 8px 15px 0 10px !default; +$--radio-bordered-mini-padding: 6px 15px 0 10px !default; +$--radio-bordered-medium-input-height: 14px !default; +$--radio-bordered-medium-input-width: 14px !default; +$--radio-bordered-medium-height: 36px !default; +$--radio-bordered-small-input-height: 12px !default; +$--radio-bordered-small-input-width: 12px !default; +$--radio-bordered-small-height: 32px !default; +$--radio-bordered-mini-input-height: 12px !default; +$--radio-bordered-mini-input-width: 12px !default; +$--radio-bordered-mini-height: 28px !default; + +/// fontSize||Font|1 +$--radio-button-font-size: $--font-size-base !default; +/// color||Color|0 +$--radio-button-checked-background-color: $--color-primary !default; +/// color||Color|0 +$--radio-button-checked-font-color: $--color-white !default; +/// color||Color|0 +$--radio-button-checked-border-color: $--color-primary !default; +$--radio-button-disabled-checked-fill: $--border-color-extra-light !default; + +/* Select +-------------------------- */ +$--select-border-color-hover: $--border-color-hover !default; +$--select-disabled-border: $--disabled-border-base !default; +/// fontSize||Font|1 +$--select-font-size: $--font-size-base !default; +$--select-close-hover-color: $--color-text-secondary !default; + +$--select-input-color: $--color-text-placeholder !default; +$--select-multiple-input-color: #666 !default; +/// color||Color|0 +$--select-input-focus-border-color: $--color-primary !default; +/// fontSize||Font|1 +$--select-input-font-size: 14px !default; + +$--select-option-color: $--color-text-regular !default; +$--select-option-disabled-color: $--color-text-placeholder !default; +$--select-option-disabled-background: $--color-white !default; +/// height||Other|4 +$--select-option-height: 34px !default; +$--select-option-hover-background: $--background-color-base !default; +/// color||Color|0 +$--select-option-selected-font-color: $--color-primary !default; +$--select-option-selected-hover: $--background-color-base !default; + +$--select-group-color: $--color-info !default; +$--select-group-height: 30px !default; +$--select-group-font-size: 12px !default; + +$--select-dropdown-background: $--color-white !default; +$--select-dropdown-shadow: $--box-shadow-light !default; +$--select-dropdown-empty-color: #999 !default; +/// height||Other|4 +$--select-dropdown-max-height: 274px !default; +$--select-dropdown-padding: 6px 0 !default; +$--select-dropdown-empty-padding: 10px 0 !default; +$--select-dropdown-border: solid 1px $--border-color-light !default; + +/* Alert +-------------------------- */ +$--alert-padding: 8px 16px !default; +/// borderRadius||Border|2 +$--alert-border-radius: $--border-radius-base !default; +/// fontSize||Font|1 +$--alert-title-font-size: 13px !default; +/// fontSize||Font|1 +$--alert-description-font-size: 12px !default; +/// fontSize||Font|1 +$--alert-close-font-size: 12px !default; +/// fontSize||Font|1 +$--alert-close-customed-font-size: 13px !default; + +$--alert-success-color: $--color-success-lighter !default; +$--alert-info-color: $--color-info-lighter !default; +$--alert-warning-color: $--color-warning-lighter !default; +$--alert-danger-color: $--color-danger-lighter !default; + +/// height||Other|4 +$--alert-icon-size: 16px !default; +/// height||Other|4 +$--alert-icon-large-size: 28px !default; + +/* MessageBox +-------------------------- */ +/// color||Color|0 +$--messagebox-title-color: $--color-text-primary !default; +$--msgbox-width: 420px !default; +$--msgbox-border-radius: 4px !default; +/// fontSize||Font|1 +$--messagebox-font-size: $--font-size-large !default; +/// fontSize||Font|1 +$--messagebox-content-font-size: $--font-size-base !default; +/// color||Color|0 +$--messagebox-content-color: $--color-text-regular !default; +/// fontSize||Font|1 +$--messagebox-error-font-size: 12px !default; +$--msgbox-padding-primary: 15px !default; +/// color||Color|0 +$--messagebox-success-color: $--color-success !default; +/// color||Color|0 +$--messagebox-info-color: $--color-info !default; +/// color||Color|0 +$--messagebox-warning-color: $--color-warning !default; +/// color||Color|0 +$--messagebox-danger-color: $--color-danger !default; + +/* Message +-------------------------- */ +$--message-shadow: $--box-shadow-base !default; +$--message-min-width: 380px !default; +$--message-background-color: #edf2fc !default; +$--message-padding: 15px 15px 15px 20px !default; +/// color||Color|0 +$--message-close-icon-color: $--color-text-placeholder !default; +/// height||Other|4 +$--message-close-size: 16px !default; +/// color||Color|0 +$--message-close-hover-color: $--color-text-secondary !default; + +/// color||Color|0 +$--message-success-font-color: $--color-success !default; +/// color||Color|0 +$--message-info-font-color: $--color-info !default; +/// color||Color|0 +$--message-warning-font-color: $--color-warning !default; +/// color||Color|0 +$--message-danger-font-color: $--color-danger !default; + +/* Notification +-------------------------- */ +$--notification-width: 330px !default; +/// padding||Spacing|3 +$--notification-padding: 14px 26px 14px 13px !default; +$--notification-radius: 8px !default; +$--notification-shadow: $--box-shadow-light !default; +/// color||Color|0 +$--notification-border-color: $--border-color-lighter !default; +$--notification-icon-size: 24px !default; +$--notification-close-font-size: $--message-close-size !default; +$--notification-group-margin-left: 13px !default; +$--notification-group-margin-right: 8px !default; +/// fontSize||Font|1 +$--notification-content-font-size: $--font-size-base !default; +/// color||Color|0 +$--notification-content-color: $--color-text-regular !default; +/// fontSize||Font|1 +$--notification-title-font-size: 16px !default; +/// color||Color|0 +$--notification-title-color: $--color-text-primary !default; + +/// color||Color|0 +$--notification-close-color: $--color-text-secondary !default; +/// color||Color|0 +$--notification-close-hover-color: $--color-text-regular !default; + +/// color||Color|0 +$--notification-success-icon-color: $--color-success !default; +/// color||Color|0 +$--notification-info-icon-color: $--color-info !default; +/// color||Color|0 +$--notification-warning-icon-color: $--color-warning !default; +/// color||Color|0 +$--notification-danger-icon-color: $--color-danger !default; + +/* Input +-------------------------- */ +$--input-font-size: $--font-size-base !default; +/// color||Color|0 +$--input-font-color: $--color-text-regular !default; +/// height||Other|4 +$--input-width: 140px !default; +/// height||Other|4 +$--input-height: 40px !default; +$--input-border: $--border-base !default; +$--input-border-color: $--border-color-base !default; +/// borderRadius||Border|2 +$--input-border-radius: $--border-radius-base !default; +$--input-border-color-hover: $--border-color-hover !default; +/// color||Color|0 +$--input-background-color: $--color-white !default; +$--input-fill-disabled: $--disabled-fill-base !default; +$--input-color-disabled: $--font-color-disabled-base !default; +/// color||Color|0 +$--input-icon-color: $--color-text-placeholder !default; +/// color||Color|0 +$--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; + +$--input-disabled-fill: $--disabled-fill-base !default; +$--input-disabled-border: $--disabled-border-base !default; +$--input-disabled-color: $--disabled-color-base !default; +$--input-disabled-placeholder-color: $--color-text-placeholder !default; + +/// fontSize||Font|1 +$--input-medium-font-size: 14px !default; +/// height||Other|4 +$--input-medium-height: 36px !default; +/// fontSize||Font|1 +$--input-small-font-size: 13px !default; +/// height||Other|4 +$--input-small-height: 32px !default; +/// fontSize||Font|1 +$--input-mini-font-size: 12px !default; +/// height||Other|4 +$--input-mini-height: 28px !default; + +/* Cascader +-------------------------- */ +/// color||Color|0 +$--cascader-menu-font-color: $--color-text-regular !default; +/// color||Color|0 +$--cascader-menu-selected-font-color: $--color-primary !default; +$--cascader-menu-fill: $--fill-base !default; +$--cascader-menu-font-size: $--font-size-base !default; +$--cascader-menu-radius: $--border-radius-base !default; +$--cascader-menu-border: solid 1px $--border-color-light !default; +$--cascader-menu-shadow: $--box-shadow-light !default; +$--cascader-node-background-hover: $--background-color-base !default; +$--cascader-node-color-disabled:$--color-text-placeholder !default; +$--cascader-color-empty:$--color-text-placeholder !default; +$--cascader-tag-background: #f0f2f5; + +/* Group +-------------------------- */ +$--group-option-flex: 0 0 (1/5) * 100% !default; +$--group-option-offset-bottom: 12px !default; +$--group-option-fill-hover: rgba($--color-black, 0.06) !default; +$--group-title-color: $--color-black !default; +$--group-title-font-size: $--font-size-base !default; +$--group-title-width: 66px !default; + +/* Tab +-------------------------- */ +$--tab-font-size: $--font-size-base !default; +$--tab-border-line: 1px solid #e4e4e4 !default; +$--tab-header-color-active: $--color-text-secondary !default; +$--tab-header-color-hover: $--color-text-regular !default; +$--tab-header-color: $--color-text-regular !default; +$--tab-header-fill-active: rgba($--color-black, 0.06) !default; +$--tab-header-fill-hover: rgba($--color-black, 0.06) !default; +$--tab-vertical-header-width: 90px !default; +$--tab-vertical-header-count-color: $--color-white !default; +$--tab-vertical-header-count-fill: $--color-text-secondary !default; + +/* Button +-------------------------- */ +/// fontSize||Font|1 +$--button-font-size: $--font-size-base !default; +/// fontWeight||Font|1 +$--button-font-weight: $--font-weight-primary !default; +/// borderRadius||Border|2 +$--button-border-radius: $--border-radius-base !default; +/// padding||Spacing|3 +$--button-padding-vertical: 12px !default; +/// padding||Spacing|3 +$--button-padding-horizontal: 20px !default; + +/// fontSize||Font|1 +$--button-medium-font-size: $--font-size-base !default; +/// borderRadius||Border|2 +$--button-medium-border-radius: $--border-radius-base !default; +/// padding||Spacing|3 +$--button-medium-padding-vertical: 10px !default; +/// padding||Spacing|3 +$--button-medium-padding-horizontal: 20px !default; + +/// fontSize||Font|1 +$--button-small-font-size: 12px !default; +$--button-small-border-radius: #{$--border-radius-base - 1} !default; +/// padding||Spacing|3 +$--button-small-padding-vertical: 9px !default; +/// padding||Spacing|3 +$--button-small-padding-horizontal: 15px !default; +/// fontSize||Font|1 +$--button-mini-font-size: 12px !default; +$--button-mini-border-radius: #{$--border-radius-base - 1} !default; +/// padding||Spacing|3 +$--button-mini-padding-vertical: 7px !default; +/// padding||Spacing|3 +$--button-mini-padding-horizontal: 15px !default; + +/// color||Color|0 +$--button-default-font-color: $--color-text-regular !default; +/// color||Color|0 +$--button-default-background-color: $--color-white !default; +/// color||Color|0 +$--button-default-border-color: $--border-color-base !default; + +/// color||Color|0 +$--button-disabled-font-color: $--color-text-placeholder !default; +/// color||Color|0 +$--button-disabled-background-color: $--color-white !default; +/// color||Color|0 +$--button-disabled-border-color: $--border-color-lighter !default; + +/// color||Color|0 +$--button-primary-border-color: $--color-primary !default; +/// color||Color|0 +$--button-primary-font-color: $--color-white !default; +/// color||Color|0 +$--button-primary-background-color: $--color-primary !default; +/// color||Color|0 +$--button-success-border-color: $--color-success !default; +/// color||Color|0 +$--button-success-font-color: $--color-white !default; +/// color||Color|0 +$--button-success-background-color: $--color-success !default; +/// color||Color|0 +$--button-warning-border-color: $--color-warning !default; +/// color||Color|0 +$--button-warning-font-color: $--color-white !default; +/// color||Color|0 +$--button-warning-background-color: $--color-warning !default; +/// color||Color|0 +$--button-danger-border-color: $--color-danger !default; +/// color||Color|0 +$--button-danger-font-color: $--color-white !default; +/// color||Color|0 +$--button-danger-background-color: $--color-danger !default; +/// color||Color|0 +$--button-info-border-color: $--color-info !default; +/// color||Color|0 +$--button-info-font-color: $--color-white !default; +/// color||Color|0 +$--button-info-background-color: $--color-info !default; + +$--button-hover-tint-percent: 20% !default; +$--button-active-shade-percent: 10% !default; + + +/* cascader +-------------------------- */ +$--cascader-height: 200px !default; + +/* Switch +-------------------------- */ +/// color||Color|0 +$--switch-on-color: $--color-primary !default; +/// color||Color|0 +$--switch-off-color: $--border-color-base !default; +/// fontSize||Font|1 +$--switch-font-size: $--font-size-base !default; +$--switch-core-border-radius: 10px !default; +// height||Other|4 TODO: width 代码写死的40px 所以下面这三个属性都没意义 +$--switch-width: 40px !default; +// height||Other|4 +$--switch-height: 20px !default; +// height||Other|4 +$--switch-button-size: 16px !default; + +/* Dialog +-------------------------- */ +$--dialog-background-color: $--color-white !default; +$--dialog-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3) !default; +/// fontSize||Font|1 +$--dialog-title-font-size: $--font-size-large !default; +/// fontSize||Font|1 +$--dialog-content-font-size: 14px !default; +/// fontLineHeight||LineHeight|2 +$--dialog-font-line-height: $--font-line-height-primary !default; +/// padding||Spacing|3 +$--dialog-padding-primary: 20px !default; + +/* Table +-------------------------- */ +/// color||Color|0 +$--table-border-color: $--border-color-lighter !default; +$--table-border: 1px solid $--table-border-color !default; +/// color||Color|0 +$--table-font-color: $--color-text-regular !default; +/// color||Color|0 +$--table-header-font-color: $--color-text-secondary !default; +/// color||Color|0 +$--table-row-hover-background-color: $--background-color-base !default; +$--table-current-row-background-color: $--color-primary-light-9 !default; +/// color||Color|0 +$--table-header-background-color: $--color-white !default; +$--table-fixed-box-shadow: 0 0 10px rgba(0, 0, 0, .12) !default; + +/* Pagination +-------------------------- */ +/// fontSize||Font|1 +$--pagination-font-size: 13px !default; +/// color||Color|0 +$--pagination-background-color: $--color-white !default; +/// color||Color|0 +$--pagination-font-color: $--color-text-primary !default; +$--pagination-border-radius: 3px !default; +/// color||Color|0 +$--pagination-button-color: $--color-text-primary !default; +/// height||Other|4 +$--pagination-button-width: 35.5px !default; +/// height||Other|4 +$--pagination-button-height: 28px !default; +/// color||Color|0 +$--pagination-button-disabled-color: $--color-text-placeholder !default; +/// color||Color|0 +$--pagination-button-disabled-background-color: $--color-white !default; +/// color||Color|0 +$--pagination-hover-color: $--color-primary !default; + +/* Popup +-------------------------- */ +/// color||Color|0 +$--popup-modal-background-color: $--color-black !default; +/// opacity||Other|1 +$--popup-modal-opacity: 0.5 !default; + +/* Popover +-------------------------- */ +/// color||Color|0 +$--popover-background-color: $--color-white !default; +/// fontSize||Font|1 +$--popover-font-size: $--font-size-base !default; +/// color||Color|0 +$--popover-border-color: $--border-color-lighter !default; +$--popover-arrow-size: 6px !default; +/// padding||Spacing|3 +$--popover-padding: 12px !default; +$--popover-padding-large: 18px 20px !default; +/// fontSize||Font|1 +$--popover-title-font-size: 16px !default; +/// color||Color|0 +$--popover-title-font-color: $--color-text-primary !default; + +/* Tooltip +-------------------------- */ +/// color|1|Color|0 +$--tooltip-fill: $--color-text-primary !default; +/// color|1|Color|0 +$--tooltip-color: $--color-white !default; +/// fontSize||Font|1 +$--tooltip-font-size: 12px !default; +/// color||Color|0 +$--tooltip-border-color: $--color-text-primary !default; +$--tooltip-arrow-size: 6px !default; +/// padding||Spacing|3 +$--tooltip-padding: 10px !default; + +/* Tag +-------------------------- */ +/// color||Color|0 +$--tag-info-color: $--color-info !default; +/// color||Color|0 +$--tag-primary-color: $--color-primary !default; +/// color||Color|0 +$--tag-success-color: $--color-success !default; +/// color||Color|0 +$--tag-warning-color: $--color-warning !default; +/// color||Color|0 +$--tag-danger-color: $--color-danger !default; +/// fontSize||Font|1 +$--tag-font-size: 12px !default; +$--tag-border-radius: 4px !default; +$--tag-padding: 0 10px !default; + +/* Tree +-------------------------- */ +/// color||Color|0 +$--tree-node-hover-background-color: $--background-color-base !default; +/// color||Color|0 +$--tree-font-color: $--color-text-regular !default; +/// color||Color|0 +$--tree-expand-icon-color: $--color-text-placeholder !default; + +/* Dropdown +-------------------------- */ +$--dropdown-menu-box-shadow: $--box-shadow-light !default; +$--dropdown-menuItem-hover-fill: $--color-primary-light-9 !default; +$--dropdown-menuItem-hover-color: $--link-color !default; + +/* Badge +-------------------------- */ +/// color||Color|0 +$--badge-background-color: $--color-danger !default; +$--badge-radius: 10px !default; +/// fontSize||Font|1 +$--badge-font-size: 12px !default; +/// padding||Spacing|3 +$--badge-padding: 6px !default; +/// height||Other|4 +$--badge-size: 18px !default; + +/* Card +--------------------------*/ +/// color||Color|0 +$--card-border-color: $--border-color-lighter !default; +$--card-border-radius: 4px !default; +/// padding||Spacing|3 +$--card-padding: 20px !default; + +/* Slider +--------------------------*/ +/// color||Color|0 +$--slider-main-background-color: $--color-primary !default; +/// color||Color|0 +$--slider-runway-background-color: $--border-color-light !default; +$--slider-button-hover-color: mix($--color-primary, black, 97%) !default; +$--slider-stop-background-color: $--color-white !default; +$--slider-disable-color: $--color-text-placeholder !default; +$--slider-margin: 16px 0 !default; +$--slider-border-radius: 3px !default; +/// height|1|Other|4 +$--slider-height: 6px !default; +/// height||Other|4 +$--slider-button-size: 16px !default; +$--slider-button-wrapper-size: 36px !default; +$--slider-button-wrapper-offset: -15px !default; + +/* Steps +--------------------------*/ +$--steps-border-color: $--disabled-border-base !default; +$--steps-border-radius: 4px !default; +$--steps-padding: 20px !default; + +/* Menu +--------------------------*/ +/// fontSize||Font|1 +$--menu-item-font-size: $--font-size-base !default; +/// color||Color|0 +$--menu-item-font-color: $--color-text-primary !default; +/// color||Color|0 +$--menu-background-color: $--color-white !default; +$--menu-item-hover-fill: $--color-primary-light-9 !default; + +/* Rate +--------------------------*/ +$--rate-height: 20px !default; +/// fontSize||Font|1 +$--rate-font-size: $--font-size-base !default; +/// height||Other|3 +$--rate-icon-size: 18px !default; +/// margin||Spacing|2 +$--rate-icon-margin: 6px !default; +$--rate-icon-color: $--color-text-placeholder !default; + +/* DatePicker +--------------------------*/ +$--datepicker-font-color: $--color-text-regular !default; +/// color|1|Color|0 +$--datepicker-off-font-color: $--color-text-placeholder !default; +/// color||Color|0 +$--datepicker-header-font-color: $--color-text-regular !default; +$--datepicker-icon-color: $--color-text-primary !default; +$--datepicker-border-color: $--disabled-border-base !default; +$--datepicker-inner-border-color: #e4e4e4 !default; +/// color||Color|0 +$--datepicker-inrange-background-color: $--border-color-extra-light !default; +/// color||Color|0 +$--datepicker-inrange-hover-background-color: $--border-color-extra-light !default; +/// color||Color|0 +$--datepicker-active-color: $--color-primary !default; +/// color||Color|0 +$--datepicker-hover-font-color: $--color-primary !default; +$--datepicker-cell-hover-color: #fff !default; + +/* Loading +--------------------------*/ +/// height||Other|4 +$--loading-spinner-size: 42px !default; +/// height||Other|4 +$--loading-fullscreen-spinner-size: 50px !default; + +/* Scrollbar +--------------------------*/ +$--scrollbar-background-color: rgba($--color-text-secondary, .3) !default; +$--scrollbar-hover-background-color: rgba($--color-text-secondary, .5) !default; + +/* Carousel +--------------------------*/ +/// fontSize||Font|1 +$--carousel-arrow-font-size: 12px !default; +$--carousel-arrow-size: 36px !default; +$--carousel-arrow-background: rgba(31, 45, 61, 0.11) !default; +$--carousel-arrow-hover-background: rgba(31, 45, 61, 0.23) !default; +/// width||Other|4 +$--carousel-indicator-width: 30px !default; +/// height||Other|4 +$--carousel-indicator-height: 2px !default; +$--carousel-indicator-padding-horizontal: 4px !default; +$--carousel-indicator-padding-vertical: 12px !default; +$--carousel-indicator-out-color: $--border-color-hover !default; + +/* Collapse +--------------------------*/ +/// color||Color|0 +$--collapse-border-color: $--border-color-lighter !default; +/// height||Other|4 +$--collapse-header-height: 48px !default; +/// color||Color|0 +$--collapse-header-background-color: $--color-white !default; +/// color||Color|0 +$--collapse-header-font-color: $--color-text-primary !default; +/// fontSize||Font|1 +$--collapse-header-font-size: 13px !default; +/// color||Color|0 +$--collapse-content-background-color: $--color-white !default; +/// fontSize||Font|1 +$--collapse-content-font-size: 13px !default; +/// color||Color|0 +$--collapse-content-font-color: $--color-text-primary !default; + +/* Transfer +--------------------------*/ +$--transfer-border-color: $--border-color-lighter !default; +$--transfer-border-radius: $--border-radius-base !default; +/// height||Other|4 +$--transfer-panel-width: 200px !default; +/// height||Other|4 +$--transfer-panel-header-height: 40px !default; +/// color||Color|0 +$--transfer-panel-header-background-color: $--background-color-base !default; +/// height||Other|4 +$--transfer-panel-footer-height: 40px !default; +/// height||Other|4 +$--transfer-panel-body-height: 246px !default; +/// height||Other|4 +$--transfer-item-height: 30px !default; +/// height||Other|4 +$--transfer-filter-height: 32px !default; + +/* Header + --------------------------*/ +$--header-padding: 0 20px !default; + +/* Footer +--------------------------*/ +$--footer-padding: 0 20px !default; + +/* Main +--------------------------*/ +$--main-padding: 20px !default; + +/* Timeline +--------------------------*/ +$--timeline-node-size-normal: 12px !default; +$--timeline-node-size-large: 14px !default; +$--timeline-node-color: $--border-color-light !default; + +/* Backtop +--------------------------*/ +/// color||Color|0 +$--backtop-background-color: $--color-white !default; +/// color||Color|0 +$--backtop-font-color: $--color-primary !default; +/// color||Color|0 +$--backtop-hover-background-color: $--border-color-extra-light !default; + +/* Link +--------------------------*/ +/// fontSize||Font|1 +$--link-font-size: $--font-size-base !default; +/// fontWeight||Font|1 +$--link-font-weight: $--font-weight-primary !default; +/// color||Color|0 +$--link-default-font-color: $--color-text-regular !default; +/// color||Color|0 +$--link-default-active-color: $--color-primary !default; +/// color||Color|0 +$--link-disabled-font-color: $--color-text-placeholder !default; +/// color||Color|0 +$--link-primary-font-color: $--color-primary !default; +/// color||Color|0 +$--link-success-font-color: $--color-success !default; +/// color||Color|0 +$--link-warning-font-color: $--color-warning !default; +/// color||Color|0 +$--link-danger-font-color: $--color-danger !default; +/// color||Color|0 +$--link-info-font-color: $--color-info !default; +/* Calendar +--------------------------*/ +/// border||Other|4 +$--calendar-border: $--table-border !default; +/// color||Other|4 +$--calendar-selected-background-color: #F2F8FE !default; +$--calendar-cell-width: 85px !default; + +/* Form +-------------------------- */ +/// fontSize||Font|1 +$--form-label-font-size: $--font-size-base !default; + +/* Avatar +--------------------------*/ +/// color||Color|0 +$--avatar-font-color: #fff !default; +/// color||Color|0 +$--avatar-background-color: #C0C4CC !default; +/// fontSize||Font Size|1 +$--avatar-text-font-size: 14px !default; +/// fontSize||Font Size|1 +$--avatar-icon-font-size: 18px !default; +/// borderRadius||Border|2 +$--avatar-border-radius: $--border-radius-base !default; +/// size|1|Avatar Size|3 +$--avatar-large-size: 40px !default; +/// size|1|Avatar Size|3 +$--avatar-medium-size: 36px !default; +/// size|1|Avatar Size|3 +$--avatar-small-size: 28px !default; + +/* Break-point +--------------------------*/ +$--sm: 768px !default; +$--md: 992px !default; +$--lg: 1200px !default; +$--xl: 1920px !default; + +$--breakpoints: ( + 'xs' : (max-width: $--sm - 1), + 'sm' : (min-width: $--sm), + 'md' : (min-width: $--md), + 'lg' : (min-width: $--lg), + 'xl' : (min-width: $--xl) +); + +$--breakpoints-spec: ( + 'xs-only' : (max-width: $--sm - 1), + 'sm-and-up' : (min-width: $--sm), + 'sm-only': "(min-width: #{$--sm}) and (max-width: #{$--md - 1})", + 'sm-and-down': (max-width: $--md - 1), + 'md-and-up' : (min-width: $--md), + 'md-only': "(min-width: #{$--md}) and (max-width: #{$--lg - 1})", + 'md-and-down': (max-width: $--lg - 1), + 'lg-and-up' : (min-width: $--lg), + 'lg-only': "(min-width: #{$--lg}) and (max-width: #{$--xl - 1})", + 'lg-and-down': (max-width: $--xl - 1), + 'xl-only' : (min-width: $--xl), +); diff --git a/packages/theme-chalk/src/container.scss b/packages/theme-chalk/src/container.scss new file mode 100644 index 0000000..df7b2af --- /dev/null +++ b/packages/theme-chalk/src/container.scss @@ -0,0 +1,14 @@ +@import "mixins/mixins"; + +@include b(container) { + display: flex; + flex-direction: row; + flex: 1; + flex-basis: auto; + box-sizing: border-box; + min-width: 0; + + @include when(vertical) { + flex-direction: column; + } +} diff --git a/packages/theme-chalk/src/date-picker.scss b/packages/theme-chalk/src/date-picker.scss new file mode 100644 index 0000000..516f056 --- /dev/null +++ b/packages/theme-chalk/src/date-picker.scss @@ -0,0 +1,12 @@ +@import "./date-picker/date-table.scss"; +@import "./date-picker/month-table.scss"; +@import "./date-picker/year-table.scss"; +@import "./date-picker/time-spinner.scss"; +@import "./date-picker/picker.scss"; +@import "./date-picker/date-picker.scss"; +@import "./date-picker/date-range-picker.scss"; +@import "./date-picker/time-range-picker.scss"; +@import "./date-picker/time-picker.scss"; +@import "./input.scss"; +@import "./scrollbar.scss"; +@import "./popper"; \ No newline at end of file diff --git a/packages/theme-chalk/src/date-picker/date-picker.scss b/packages/theme-chalk/src/date-picker/date-picker.scss new file mode 100644 index 0000000..7ac85ab --- /dev/null +++ b/packages/theme-chalk/src/date-picker/date-picker.scss @@ -0,0 +1,97 @@ +@import "../common/var"; +@import "../mixins/mixins"; +@import "./picker-panel.scss"; + +@include b(date-picker) { + width: 322px; + + &.has-sidebar.has-time { + width: 434px; + } + + &.has-sidebar { + width: 438px; + } + + &.has-time .el-picker-panel__body-wrapper { + position: relative; + } + + .el-picker-panel__content { + width: 292px; + } + + table { + table-layout: fixed; + width: 100%; + } + + @include e(editor-wrap) { + position: relative; + display: table-cell; + padding: 0 5px; + } + + @include e(time-header) { + position: relative; + border-bottom: 1px solid $--datepicker-inner-border-color; + font-size: 12px; + padding: 8px 5px 5px 5px; + display: table; + width: 100%; + box-sizing: border-box; + } + + @include e(header) { + margin: 12px; + text-align: center; + + @include m(bordered) { + margin-bottom: 0; + padding-bottom: 12px; + border-bottom: solid 1px $--border-color-lighter; + + & + .el-picker-panel__content { + margin-top: 0; + } + } + } + + @include e(header-label) { + font-size: 16px; + font-weight: 500; + padding: 0 5px; + line-height: 22px; + text-align: center; + cursor: pointer; + color: $--color-text-regular; + + &:hover { + color: $--datepicker-hover-font-color; + } + + &.active { + color: $--datepicker-active-color; + } + } + + @include e(prev-btn) { + float: left; + } + + @include e(next-btn) { + float: right; + } + + @include e(time-wrap) { + padding: 10px; + text-align: center; + } + + @include e(time-label) { + float: left; + cursor: pointer; + line-height: 30px; + margin-left: 10px; + } +} diff --git a/packages/theme-chalk/src/date-picker/date-range-picker.scss b/packages/theme-chalk/src/date-picker/date-range-picker.scss new file mode 100644 index 0000000..cff12a1 --- /dev/null +++ b/packages/theme-chalk/src/date-picker/date-range-picker.scss @@ -0,0 +1,101 @@ +@import "../common/var"; + +@include b(date-range-picker) { + width: 646px; + + &.has-sidebar { + width: 756px; + } + + table { + table-layout: fixed; + width: 100%; + } + + .el-picker-panel__body { + min-width: 513px; + } + + .el-picker-panel__content { + margin: 0; + } + + @include e(header) { + position: relative; + text-align: center; + height: 28px; + + [class*=arrow-left] { + float: left; + } + + [class*=arrow-right] { + float: right; + } + + div { + font-size: 16px; + font-weight: 500; + margin-right: 50px; + } + } + + @include e(content) { + float: left; + width: 50%; + box-sizing: border-box; + margin: 0; + padding: 16px; + + @include when(left) { + border-right: 1px solid $--datepicker-inner-border-color; + } + .el-date-range-picker__header { + + div { + margin-left: 50px; + margin-right: 50px; + } + } + } + + @include e(editors-wrap) { + box-sizing: border-box; + display: table-cell; + + @include when(right) { + text-align: right; + } + } + + @include e(time-header) { + position: relative; + border-bottom: 1px solid $--datepicker-inner-border-color; + font-size: 12px; + padding: 8px 5px 5px 5px; + display: table; + width: 100%; + box-sizing: border-box; + + > .el-icon-arrow-right { + font-size: 20px; + vertical-align: middle; + display: table-cell; + color: $--datepicker-icon-color; + } + } + + @include e(time-picker-wrap) { + position: relative; + display: table-cell; + padding: 0 5px; + + .el-picker-panel { + position: absolute; + top: 13px; + right: 0; + z-index: 1; + background: $--color-white; + } + } +} diff --git a/packages/theme-chalk/src/date-picker/date-table.scss b/packages/theme-chalk/src/date-picker/date-table.scss new file mode 100644 index 0000000..5fed1bb --- /dev/null +++ b/packages/theme-chalk/src/date-picker/date-table.scss @@ -0,0 +1,151 @@ +@import "../common/var"; +@import "../mixins/mixins"; + +@include b(date-table) { + font-size: 12px; + user-select: none; + + @include when(week-mode) { + .el-date-table__row { + &:hover { + div { + background-color: $--datepicker-inrange-background-color; + } + td.available:hover { + color: $--datepicker-font-color; + } + td:first-child div { + margin-left: 5px; + border-top-left-radius: 15px; + border-bottom-left-radius: 15px; + } + td:last-child div { + margin-right: 5px; + border-top-right-radius: 15px; + border-bottom-right-radius: 15px; + } + } + + &.current div { + background-color: $--datepicker-inrange-background-color; + } + } + } + + td { + width: 32px; + height: 30px; + padding: 4px 0; + box-sizing: border-box; + text-align: center; + cursor: pointer; + position: relative; + + & div { + height: 30px; + padding: 3px 0; + box-sizing: border-box; + } + + & span { + width: 24px; + height: 24px; + display: block; + margin: 0 auto; + line-height: 24px; + position: absolute; + left: 50%; + transform: translateX(-50%); + border-radius: 50%; + } + + &.next-month, + &.prev-month { + color: $--datepicker-off-font-color; + } + + &.today { + position: relative; + span { + color: $--color-primary; + font-weight: bold; + } + &.start-date span, + &.end-date span { + color: $--color-white; + } + } + + &.available:hover { + color: $--datepicker-hover-font-color; + } + + &.in-range div { + background-color: $--datepicker-inrange-background-color; + &:hover { + background-color: $--datepicker-inrange-hover-background-color; + } + } + + &.current:not(.disabled) span { + color: $--color-white; + background-color: $--datepicker-active-color; + } + &.start-date div, + &.end-date div { + color: $--color-white; + } + + &.start-date span, + &.end-date span { + background-color: $--datepicker-active-color; + } + + &.start-date div { + margin-left: 5px; + border-top-left-radius: 15px; + border-bottom-left-radius: 15px; + } + + &.end-date div { + margin-right: 5px; + border-top-right-radius: 15px; + border-bottom-right-radius: 15px; + } + + &.disabled div { + background-color: $--background-color-base; + opacity: 1; + cursor: not-allowed; + color: $--color-text-placeholder; + } + + &.selected div { + margin-left: 5px; + margin-right: 5px; + background-color: $--datepicker-inrange-background-color; + border-radius: 15px; + &:hover { + background-color: $--datepicker-inrange-hover-background-color; + } + } + + &.selected span { + background-color: $--datepicker-active-color; + color: $--color-white; + border-radius: 15px; + } + + &.week { + font-size: 80%; + color: $--datepicker-header-font-color; + } + } + + th { + padding: 5px; + color: $--datepicker-header-font-color; + font-weight: 400; + border-bottom: solid 1px $--border-color-lighter; + } +} diff --git a/packages/theme-chalk/src/date-picker/month-table.scss b/packages/theme-chalk/src/date-picker/month-table.scss new file mode 100644 index 0000000..1164f70 --- /dev/null +++ b/packages/theme-chalk/src/date-picker/month-table.scss @@ -0,0 +1,82 @@ +@import "../common/var"; + +@include b(month-table) { + font-size: 12px; + margin: -1px; + border-collapse: collapse; + + td { + text-align: center; + padding: 8px 0px; + cursor: pointer; + & div { + height: 48px; + padding: 6px 0; + box-sizing: border-box; + } + &.today { + .cell { + color: $--color-primary; + font-weight: bold; + } + &.start-date .cell, + &.end-date .cell { + color: $--color-white; + } + } + + &.disabled .cell { + background-color: $--background-color-base; + cursor: not-allowed; + color: $--color-text-placeholder; + + &:hover { + color: $--color-text-placeholder; + } + } + + .cell { + width: 60px; + height: 36px; + display: block; + line-height: 36px; + color: $--datepicker-font-color; + margin: 0 auto; + border-radius: 18px; + &:hover { + color: $--datepicker-hover-font-color; + } + } + + &.in-range div { + background-color: $--datepicker-inrange-background-color; + &:hover { + background-color: $--datepicker-inrange-hover-background-color; + } + } + &.start-date div, + &.end-date div { + color: $--color-white; + } + + &.start-date .cell, + &.end-date .cell { + color: $--color-white; + background-color: $--datepicker-active-color; + } + + &.start-date div { + border-top-left-radius: 24px; + border-bottom-left-radius: 24px; + } + + &.end-date div { + border-top-right-radius: 24px; + border-bottom-right-radius: 24px; + } + + &.current:not(.disabled) .cell { + color: $--datepicker-active-color; + } + } +} diff --git a/packages/theme-chalk/src/date-picker/picker-panel.scss b/packages/theme-chalk/src/date-picker/picker-panel.scss new file mode 100644 index 0000000..70fed3b --- /dev/null +++ b/packages/theme-chalk/src/date-picker/picker-panel.scss @@ -0,0 +1,117 @@ +@import "../common/var"; + +@include b(picker-panel) { + color: $--color-text-regular; + border: 1px solid $--datepicker-border-color; + box-shadow: $--box-shadow-light; + background: $--color-white; + border-radius: $--border-radius-base; + line-height: 30px; + margin: 5px 0; + + @include e((body, body-wrapper)) { + &::after { + content: ""; + display: table; + clear: both; + } + } + + @include e(content) { + position: relative; + margin: 15px; + } + + @include e(footer) { + border-top: 1px solid $--datepicker-inner-border-color; + padding: 4px; + text-align: right; + background-color: $--color-white; + position: relative; + font-size: 0; + } + + @include e(shortcut) { + display: block; + width: 100%; + border: 0; + background-color: transparent; + line-height: 28px; + font-size: 14px; + color: $--datepicker-font-color; + padding-left: 12px; + text-align: left; + outline: none; + cursor: pointer; + + &:hover { + color: $--datepicker-hover-font-color; + } + + &.active { + background-color: #e6f1fe; + color: $--datepicker-active-color; + } + } + + @include e(btn) { + border: 1px solid #dcdcdc; + color: #333; + line-height: 24px; + border-radius: 2px; + padding: 0 20px; + cursor: pointer; + background-color: transparent; + outline: none; + font-size: 12px; + + &[disabled] { + color: #cccccc; + cursor: not-allowed; + } + } + + @include e(icon-btn) { + font-size: 12px; + color: $--datepicker-icon-color; + border: 0; + background: transparent; + cursor: pointer; + outline: none; + margin-top: 8px; + + &:hover { + color: $--datepicker-hover-font-color; + } + + @include when(disabled) { + color: $--font-color-disabled-base; + + &:hover { + cursor: not-allowed; + } + } + } + + @include e(link-btn) { + vertical-align: middle; + } +} + +.el-picker-panel *[slot=sidebar], +.el-picker-panel__sidebar { + position: absolute; + top: 0; + bottom: 0; + width: 110px; + border-right: 1px solid $--datepicker-inner-border-color; + box-sizing: border-box; + padding-top: 6px; + background-color: $--color-white; + overflow: auto; +} + +.el-picker-panel *[slot=sidebar] + .el-picker-panel__body, +.el-picker-panel__sidebar + .el-picker-panel__body { + margin-left: 110px; +} diff --git a/packages/theme-chalk/src/date-picker/picker.scss b/packages/theme-chalk/src/date-picker/picker.scss new file mode 100644 index 0000000..8110c2a --- /dev/null +++ b/packages/theme-chalk/src/date-picker/picker.scss @@ -0,0 +1,197 @@ +@import "../mixins/mixins"; +@import "../common/var"; +@import "../common/transition"; + +@include b(date-editor) { + position: relative; + display: inline-block; + text-align: left; + + &.el-input, + &.el-input__inner { + width: 220px; + } + + @include m((monthrange)) { + &.el-input, + &.el-input__inner { + width: 300px; + } + } + + @include m((daterange, timerange)) { + &.el-input, + &.el-input__inner { + width: 350px; + } + } + + @include m(datetimerange) { + &.el-input, + &.el-input__inner { + width: 400px; + } + } + + @include m(dates) { + .el-input__inner { + text-overflow: ellipsis; + white-space: nowrap; + } + } + + .el-icon-circle-close { + cursor: pointer; + } + + .el-range__icon { + font-size: 14px; + margin-left: -5px; + color: $--color-text-placeholder; + float: left; + line-height: 32px; + } + + .el-range-input { + appearance: none; + border: none; + outline: none; + display: inline-block; + height: 100%; + margin: 0; + padding: 0; + width: 39%; + text-align: center; + font-size: $--font-size-base; + color: $--color-text-regular; + + &::placeholder { + color: $--color-text-placeholder; + } + } + + .el-range-separator { + display: inline-block; + height: 100%; + padding: 0 5px; + margin: 0; + text-align: center; + line-height: 32px; + font-size: 14px; + width: 5%; + color: $--color-text-primary; + } + + .el-range__close-icon { + font-size: 14px; + color: $--color-text-placeholder; + width: 25px; + display: inline-block; + float: right; + line-height: 32px; + } +} + +@include b(range-editor) { + &.el-input__inner { + display: inline-flex; + align-items: center; + padding: 3px 10px; + } + + .el-range-input { + line-height: 1; + } + + @include when(active) { + border-color: $--color-primary; + + &:hover { + border-color: $--color-primary; + } + } + + @include m(medium) { + &.el-input__inner { + height: $--input-medium-height; + } + + .el-range-separator { + line-height: 28px; + font-size: $--input-medium-font-size; + } + + .el-range-input { + font-size: $--input-medium-font-size; + } + + .el-range__icon, + .el-range__close-icon { + line-height: 28px; + } + } + + @include m(small) { + &.el-input__inner { + height: $--input-small-height; + } + + .el-range-separator { + line-height: 24px; + font-size: $--input-small-font-size; + } + + .el-range-input { + font-size: $--input-small-font-size; + } + + .el-range__icon, + .el-range__close-icon { + line-height: 24px; + } + } + + @include m(mini) { + &.el-input__inner { + height: $--input-mini-height; + } + + .el-range-separator { + line-height: 20px; + font-size: $--input-mini-font-size; + } + + .el-range-input { + font-size: $--input-mini-font-size; + } + + .el-range__icon, + .el-range__close-icon { + line-height: 20px; + } + } + + @include when(disabled) { + background-color: $--input-disabled-fill; + border-color: $--input-disabled-border; + color: $--input-disabled-color; + cursor: not-allowed; + + &:hover, &:focus { + border-color: $--input-disabled-border; + } + + input { + background-color: $--input-disabled-fill; + color: $--input-disabled-color; + cursor: not-allowed; + &::placeholder { + color: $--input-disabled-placeholder-color; + } + } + + .el-range-separator { + color: $--input-disabled-color; + } + } +} diff --git a/packages/theme-chalk/src/date-picker/time-picker.scss b/packages/theme-chalk/src/date-picker/time-picker.scss new file mode 100644 index 0000000..eaaf8f0 --- /dev/null +++ b/packages/theme-chalk/src/date-picker/time-picker.scss @@ -0,0 +1,85 @@ +@import "../common/var"; + +@include b(time-panel) { + margin: 5px 0; + border: solid 1px $--datepicker-border-color; + background-color: $--color-white; + box-shadow: $--box-shadow-light; + border-radius: 2px; + position: absolute; + width: 180px; + left: 0; + z-index: $--index-top; + user-select: none; + box-sizing: content-box; + + @include e(content) { + font-size: 0; + position: relative; + overflow: hidden; + + &::after, &::before { + content: ""; + top: 50%; + position: absolute; + margin-top: -15px; + height: 32px; + z-index: -1; + left: 0; + right: 0; + box-sizing: border-box; + padding-top: 6px; + text-align: left; + border-top: 1px solid $--border-color-light; + border-bottom: 1px solid $--border-color-light; + } + + &::after { + left: 50%; + margin-left: 12%; + margin-right: 12%; + } + + &::before { + padding-left: 50%; + margin-right: 12%; + margin-left: 12%; + } + + &.has-seconds { + &::after { + left: calc(100% / 3 * 2); + } + + &::before { + padding-left: calc(100% / 3); + } + } + } + + @include e(footer) { + border-top: 1px solid $--datepicker-inner-border-color; + padding: 4px; + height: 36px; + line-height: 25px; + text-align: right; + box-sizing: border-box; + } + + @include e(btn) { + border: none; + line-height: 28px; + padding: 0 5px; + margin: 0 5px; + cursor: pointer; + background-color: transparent; + outline: none; + font-size: 12px; + color: $--color-text-primary; + + &.confirm { + font-weight: 800; + color: $--datepicker-active-color; + } + } +} diff --git a/packages/theme-chalk/src/date-picker/time-range-picker.scss b/packages/theme-chalk/src/date-picker/time-range-picker.scss new file mode 100644 index 0000000..a2bf629 --- /dev/null +++ b/packages/theme-chalk/src/date-picker/time-range-picker.scss @@ -0,0 +1,31 @@ +@import "../common/var"; + +@include b(time-range-picker) { + width: 354px; + overflow: visible; + + @include e(content) { + position: relative; + text-align: center; + padding: 10px; + } + + @include e(cell) { + box-sizing: border-box; + margin: 0; + padding: 4px 7px 7px; + width: 50%; + display: inline-block; + } + + @include e(header) { + margin-bottom: 5px; + text-align: center; + font-size: 14px; + } + + @include e(body) { + border-radius:2px; + border: 1px solid $--datepicker-border-color; + } +} diff --git a/packages/theme-chalk/src/date-picker/time-spinner.scss b/packages/theme-chalk/src/date-picker/time-spinner.scss new file mode 100644 index 0000000..c70260a --- /dev/null +++ b/packages/theme-chalk/src/date-picker/time-spinner.scss @@ -0,0 +1,110 @@ +@import "../common/var"; + +@include b(time-spinner) { + &.has-seconds { + .el-time-spinner__wrapper { + width: 33.3%; + } + } + + @include e(wrapper) { + max-height: 190px; + overflow: auto; + display: inline-block; + width: 50%; + vertical-align: top; + position: relative; + + & .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) { + padding-bottom: 15px; + } + + @include when(arrow) { + box-sizing: border-box; + text-align: center; + overflow: hidden; + + .el-time-spinner__list { + transform: translateY(-32px); + } + + .el-time-spinner__item:hover:not(.disabled):not(.active) { + background: $--color-white; + cursor: default; + } + } + } + + @include e(arrow) { + font-size: 12px; + color: $--color-text-secondary; + position: absolute; + left: 0; + width: 100%; + z-index: $--index-normal; + text-align: center; + height: 30px; + line-height: 30px; + cursor: pointer; + + &:hover { + color: $--color-primary; + } + + &.el-icon-arrow-up { + top: 10px; + } + + &.el-icon-arrow-down { + bottom: 10px; + } + } + + @include e(input) { + &.el-input { + width: 70%; + + .el-input__inner { + padding: 0; + text-align: center; + } + } + } + + @include e(list) { + padding: 0; + margin: 0; + list-style: none; + text-align: center; + + &::after, + &::before { + content: ''; + display: block; + width: 100%; + height: 80px; + } + } + + @include e(item) { + height: 32px; + line-height: 32px; + font-size: 12px; + color: $--color-text-regular; + + &:hover:not(.disabled):not(.active) { + background: $--background-color-base; + cursor: pointer; + } + + &.active:not(.disabled) { + color: $--color-text-primary; + font-weight: bold; + } + + &.disabled { + color: $--color-text-placeholder; + cursor: not-allowed; + } + } +} diff --git a/packages/theme-chalk/src/date-picker/year-table.scss b/packages/theme-chalk/src/date-picker/year-table.scss new file mode 100644 index 0000000..18fbed9 --- /dev/null +++ b/packages/theme-chalk/src/date-picker/year-table.scss @@ -0,0 +1,51 @@ +@import "../common/var"; + +@include b(year-table) { + font-size: 12px; + margin: -1px; + border-collapse: collapse; + + .el-icon { + color: $--datepicker-icon-color; + } + + td { + text-align: center; + padding: 20px 3px; + cursor: pointer; + + &.today { + .cell { + color: $--color-primary; + font-weight: bold; + } + } + + &.disabled .cell { + background-color: $--background-color-base; + cursor: not-allowed; + color: $--color-text-placeholder; + + &:hover { + color: $--color-text-placeholder; + } + } + + .cell { + width: 48px; + height: 32px; + display: block; + line-height: 32px; + color: $--datepicker-font-color; + margin: 0 auto; + + &:hover { + color: $--datepicker-hover-font-color; + } + } + + &.current:not(.disabled) .cell { + color: $--datepicker-active-color; + } + } +} diff --git a/packages/theme-chalk/src/dialog.scss b/packages/theme-chalk/src/dialog.scss new file mode 100644 index 0000000..2cc7014 --- /dev/null +++ b/packages/theme-chalk/src/dialog.scss @@ -0,0 +1,157 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "common/var"; +@import "common/popup"; + +@include b(dialog) { + position: relative; + margin: 0 auto 50px; + background: $--dialog-background-color; + border-radius: $--border-radius-small; + box-shadow: $--dialog-box-shadow; + box-sizing: border-box; + width: 50%; + display: flex; + flex-flow: column; + transition: all 50ms; + + @include when(fullscreen) { + width: 100%; + margin-top: 0; + margin-bottom: 0; + height: 100%; + overflow: auto; + } + + @include e(wrapper) { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + overflow: auto; + margin: 0; + } + + @include e(header) { + padding: $--dialog-padding-primary; + padding-bottom: 10px; + flex: none; + } + + @include e(headerbtn) { + position: absolute; + top: $--dialog-padding-primary; + right: $--dialog-padding-primary; + padding: 0; + background: transparent; + border: none; + outline: none; + cursor: pointer; + font-size: $--message-close-size; + + &.size { + right: 50px; + } + + .el-dialog__close { + color: $--color-info; + } + + .el-dialog__maximize { + height: 1em; + width: 1em; + display: inline-block; + background: center / contain transparent + url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiM5MDkzOTk7fS5jbHMtMntmaWxsOm5vbmU7fTwvc3R5bGU+PC9kZWZzPjx0aXRsZT7mnIDlpKfljJbpnZnmgIE8L3RpdGxlPjxnIGlkPSLlm77lsYJfMiIgZGF0YS1uYW1lPSLlm77lsYIgMiI+PGcgaWQ9IuWbvuWxgl8xLTIiIGRhdGEtbmFtZT0i5Zu+5bGCIDEiPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTAsMVYxNUgxNlYxWk0xNSwxNEgxVjRIMTVaIi8+PHJlY3QgY2xhc3M9ImNscy0yIiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiLz48L2c+PC9nPjwvc3ZnPg=="); + } + + .el-dialog__minimize { + height: 1em; + width: 1em; + display: inline-block; + background: center / contain transparent + url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7fS5jbHMtMntmaWxsOiM5MDkzOTk7fTwvc3R5bGU+PC9kZWZzPjx0aXRsZT7mnIDlsI/ljJbpnZnmgIE8L3RpdGxlPjxnIGlkPSLlm77lsYJfMiIgZGF0YS1uYW1lPSLlm77lsYIgMiI+PGcgaWQ9IuWbvuWxgl8xLTIiIGRhdGEtbmFtZT0i5Zu+5bGCIDEiPjxyZWN0IGNsYXNzPSJjbHMtMSIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ii8+PHBhdGggY2xhc3M9ImNscy0yIiBkPSJNMSwxVjE1SDE1VjFaTTIuNTcsMTQuMDYsNi40NCwxMC4ydjIuNTJoLjlWOC42NkgzLjI4di45SDUuOEwxLjk0LDEzLjQzVjEuOTRIMTMuNDNMOS41Niw1LjhWMy4yOGgtLjlWNy4zNGg0LjA2di0uOUgxMC4ybDMuODYtMy44N1YxNC4wNloiLz48L2c+PC9nPjwvc3ZnPg=="); + } + + &:focus, + &:hover { + .el-dialog__close { + color: $--color-primary; + } + .el-dialog__minimize { + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7fS5jbHMtMntmaWxsOiMxNjc3ZmY7fTwvc3R5bGU+PC9kZWZzPjx0aXRsZT7mnIDlsI/ljJY8L3RpdGxlPjxnIGlkPSLlm77lsYJfMiIgZGF0YS1uYW1lPSLlm77lsYIgMiI+PGcgaWQ9IuWbvuWxgl8xLTIiIGRhdGEtbmFtZT0i5Zu+5bGCIDEiPjxyZWN0IGNsYXNzPSJjbHMtMSIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ii8+PHBhdGggY2xhc3M9ImNscy0yIiBkPSJNMSwxVjE1SDE1VjFaTTIuNTcsMTQuMDYsNi40NCwxMC4ydjIuNTJoLjlWOC42NkgzLjI4di45SDUuOEwxLjk0LDEzLjQzVjEuOTRIMTMuNDNMOS41Niw1LjhWMy4yOGgtLjlWNy4zNGg0LjA2di0uOUgxMC4ybDMuODYtMy44N1YxNC4wNloiLz48L2c+PC9nPjwvc3ZnPg=="); + } + .el-dialog__maximize { + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiMxNjc3ZmY7fS5jbHMtMntmaWxsOm5vbmU7fTwvc3R5bGU+PC9kZWZzPjx0aXRsZT7mnIDlpKfljJY8L3RpdGxlPjxnIGlkPSLlm77lsYJfMiIgZGF0YS1uYW1lPSLlm77lsYIgMiI+PGcgaWQ9IuWbvuWxgl8xLTIiIGRhdGEtbmFtZT0i5Zu+5bGCIDEiPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTAsMVYxNUgxNlYxWk0xNSwxNEgxVjRIMTVaIi8+PHJlY3QgY2xhc3M9ImNscy0yIiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiLz48L2c+PC9nPjwvc3ZnPg=="); + } + } + } + + @include e(title) { + line-height: $--dialog-font-line-height; + font-size: $--dialog-title-font-size; + color: $--color-text-primary; + } + + @include e(body) { + padding: ($--dialog-padding-primary + 10px) $--dialog-padding-primary; + color: $--color-text-regular; + font-size: $--dialog-content-font-size; + word-break: break-all; + flex: auto; + overflow: hidden; + } + + @include e(footer) { + padding: $--dialog-padding-primary; + padding-top: 10px; + text-align: right; + box-sizing: border-box; + flex: none; + } + + // 内容居中布局 + @include m(center) { + text-align: center; + + @include e(body) { + text-align: initial; + padding: 25px ($--dialog-padding-primary + 5px) 30px; + } + + @include e(footer) { + text-align: inherit; + } + } +} + +.dialog-fade-enter-active { + animation: dialog-fade-in 0.3s; +} + +.dialog-fade-leave-active { + animation: dialog-fade-out 0.3s; +} + +@keyframes dialog-fade-in { + 0% { + transform: translate3d(0, -20px, 0); + opacity: 0; + } + 100% { + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes dialog-fade-out { + 0% { + transform: translate3d(0, 0, 0); + opacity: 1; + } + 100% { + transform: translate3d(0, -20px, 0); + opacity: 0; + } +} diff --git a/packages/theme-chalk/src/display.scss b/packages/theme-chalk/src/display.scss new file mode 100644 index 0000000..fac8b49 --- /dev/null +++ b/packages/theme-chalk/src/display.scss @@ -0,0 +1,12 @@ +@import "common/var"; +@import "mixins/mixins"; + +.hidden { + @each $break-point-name, $value in $--breakpoints-spec { + &-#{$break-point-name} { + @include res($break-point-name, $--breakpoints-spec) { + display: none !important; + } + } + } +} diff --git a/packages/theme-chalk/src/divider.scss b/packages/theme-chalk/src/divider.scss new file mode 100644 index 0000000..4ed94ee --- /dev/null +++ b/packages/theme-chalk/src/divider.scss @@ -0,0 +1,47 @@ +@import "common/var"; +@import "mixins/mixins"; + +@include b(divider) { + background-color: $--border-color-base; + position: relative; + + @include m(horizontal) { + display: block; + height: 1px; + width: 100%; + margin: 24px 0; + } + + @include m(vertical) { + display: inline-block; + width: 1px; + height: 1em; + margin: 0 8px; + vertical-align: middle; + position: relative; + } + + @include e(text) { + position: absolute; + background-color: $--color-white; + padding: 0 20px; + font-weight: 500; + color: $--color-text-primary; + font-size: 14px; + + @include when(left) { + left: 20px; + transform: translateY(-50%); + } + + @include when(center) { + left: 50%; + transform: translateX(-50%) translateY(-50%); + } + + @include when(right) { + right: 20px; + transform: translateY(-50%); + } + } +} \ No newline at end of file diff --git a/packages/theme-chalk/src/drawer.scss b/packages/theme-chalk/src/drawer.scss new file mode 100644 index 0000000..8e13f35 --- /dev/null +++ b/packages/theme-chalk/src/drawer.scss @@ -0,0 +1,218 @@ +@import "mixins/mixins"; +@import "common/var"; + +@keyframes el-drawer-fade-in { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@mixin drawer-animation($direction) { + + @keyframes #{$direction}-drawer-in { + 0% { + + @if $direction == ltr { + transform: translate(-100%, 0px); + } + + @if $direction == rtl { + transform: translate(100%, 0px); + } + + @if $direction == ttb { + transform: translate(0px, -100%); + } + + @if $direction == btt { + transform: translate(0px, 100%); + } + } + + 100% { + @if $direction == ltr { + transform: translate(0px, 0px); + } + + @if $direction == rtl { + transform: translate(0px, 0px); + } + + @if $direction == ttb { + transform: translate(0px, 0px); + } + + @if $direction == btt { + transform: translate(0px, 0px); + } + } + } + + @keyframes #{$direction}-drawer-out { + 0% { + @if $direction == ltr { + transform: translate(0px, 0px); + } + + @if $direction == rtl { + transform: translate(0px, 0px);; + } + + @if $direction == ttb { + transform: translate(0px, 0px); + } + + @if $direction == btt { + transform: translate(0px, 0); + } + } + + 100% { + @if $direction == ltr { + transform: translate(-100%, 0px); + } + + @if $direction == rtl { + transform: translate(100%, 0px); + } + + @if $direction == ttb { + transform: translate(0px, -100%); + } + + @if $direction == btt { + transform: translate(0px, 100%); + } + } + } +} + +@mixin animation-in($direction) { + .el-drawer__open &.#{$direction} { + animation: #{$direction}-drawer-in .3s 1ms; + } +} + +@mixin animation-out($direction) { + &.#{$direction} { + animation: #{$direction}-drawer-out .3s; + } +} + +@include drawer-animation(rtl); +@include drawer-animation(ltr); +@include drawer-animation(ttb); +@include drawer-animation(btt); + +$directions: rtl, ltr, ttb, btt; + +@include b(drawer) { + position: absolute; + box-sizing: border-box; + background-color: $--dialog-background-color; + display: flex; + flex-direction: column; + box-shadow: 0 8px 10px -5px rgba(0, 0, 0, 0.2), + 0 16px 24px 2px rgba(0, 0, 0, 0.14), + 0 6px 30px 5px rgba(0, 0, 0, 0.12); + overflow: hidden; + outline: 0; + + @each $direction in $directions { + @include animation-out($direction); + @include animation-in($direction); + } + + &__wrapper { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + overflow: hidden; + margin: 0; + } + + &__header { + align-items: center; + color: rgb(114, 118, 123); + display: flex; + margin-bottom: 32px; + padding: $--dialog-padding-primary; + padding-bottom: 0; + & > :first-child { + flex: 1; + } + } + + &__title { + margin: 0; + flex: 1; + line-height: inherit; + font-size: 1rem; + } + + &__close-btn { + border: none; + cursor: pointer; + font-size: $--font-size-extra-large; + color: inherit; + background-color: transparent; + } + + &__body { + flex: 1; + & > * { + box-sizing: border-box; + } + } + + &.ltr, &.rtl { + height: 100%; + top: 0; + bottom: 0; + } + + &.ttb, &.btt { + width: 100%; + left: 0; + right: 0; + } + + &.ltr { + left: 0; + } + + &.rtl { + right: 0; + } + + &.ttb { + top: 0; + } + + &.btt { + bottom: 0; + } +} + +.el-drawer__container { + position: relative; + left: 0; + right: 0; + top: 0; + bottom: 0; + height: 100%; + width: 100%; +} + +.el-drawer-fade-enter-active { + animation: el-drawer-fade-in .3s; +} + +.el-drawer-fade-leave-active { + animation: el-drawer-fade-in .3s reverse; +} diff --git a/packages/theme-chalk/src/dropdown-item.scss b/packages/theme-chalk/src/dropdown-item.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/dropdown-menu.scss b/packages/theme-chalk/src/dropdown-menu.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/dropdown.scss b/packages/theme-chalk/src/dropdown.scss new file mode 100644 index 0000000..8471859 --- /dev/null +++ b/packages/theme-chalk/src/dropdown.scss @@ -0,0 +1,177 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "button"; +@import "./popper"; + +@include b(dropdown) { + display: inline-block; + position: relative; + color: $--color-text-regular; + font-size: $--font-size-base; + + .el-button-group { + display: block; + .el-button { + float: none; + } + } + + & .el-dropdown__caret-button { + padding-left: 5px; + padding-right: 5px; + position: relative; + border-left: none; + + &::before { + $gap: 5px; + + content: ''; + position: absolute; + display: block; + width: 1px; + top: $gap; + bottom: $gap; + left: 0; + background: mix(white, transparent, 50%); + } + + &.el-button--default::before { + background: mix($--button-default-border-color, transparent, 50%); + } + + &:hover { + &::before { + top: 0; + bottom: 0; + } + } + + & .el-dropdown__icon { + padding-left: 0; + } + } + @include e(icon) { + font-size: 12px; + margin: 0 3px; + } + + .el-dropdown-selfdefine { // 自定义 + &:focus:active, &:focus:not(.focusing) { + outline-width: 0; + } + } +} + +@include b(dropdown-menu) { + position: absolute; + top: 0; + left: 0; + z-index: 10; + padding: 10px 0; + margin: 5px 0; + background-color: $--color-white; + border: 1px solid $--border-color-lighter; + border-radius: $--border-radius-base; + box-shadow: $--dropdown-menu-box-shadow; + + @include e(item) { + list-style: none; + line-height: 36px; + padding: 0 20px; + margin: 0; + font-size: $--font-size-base; + color: $--color-text-regular; + cursor: pointer; + outline: none; + &:not(.is-disabled):hover, &:focus { + background-color: $--dropdown-menuItem-hover-fill; + color: $--dropdown-menuItem-hover-color; + } + + i { + margin-right: 5px; + } + + @include m(divided) { + $divided-offset: 6px; + + position: relative; + margin-top: $divided-offset; + border-top: 1px solid $--border-color-lighter; + + &:before { + content: ''; + height: $divided-offset; + display: block; + margin: 0 -20px; + background-color: $--color-white; + } + } + + @include when(disabled) { + cursor: default; + color: $--font-color-disabled-base; + pointer-events: none; + } + } + + @include m(medium) { + padding: 6px 0; + + @include e(item) { + line-height: 30px; + padding: 0 17px; + font-size: 14px; + + &.el-dropdown-menu__item--divided { + $divided-offset: 6px; + margin-top: $divided-offset; + + &:before { + height: $divided-offset; + margin: 0 -17px; + } + } + } + } + + @include m(small) { + padding: 6px 0; + + @include e(item) { + line-height: 27px; + padding: 0 15px; + font-size: 13px; + + &.el-dropdown-menu__item--divided { + $divided-offset: 4px; + margin-top: $divided-offset; + + &:before { + height: $divided-offset; + margin: 0 -15px; + } + } + } + } + + @include m(mini) { + padding: 3px 0; + + @include e(item) { + line-height: 24px; + padding: 0 10px; + font-size: 12px; + + &.el-dropdown-menu__item--divided { + $divided-offset: 3px; + margin-top: $divided-offset; + + &:before { + height: $divided-offset; + margin: 0 -10px; + } + } + } + } +} diff --git a/packages/theme-chalk/src/fonts/element-icons.ttf b/packages/theme-chalk/src/fonts/element-icons.ttf new file mode 100644 index 0000000..91b74de Binary files /dev/null and b/packages/theme-chalk/src/fonts/element-icons.ttf differ diff --git a/packages/theme-chalk/src/fonts/element-icons.woff b/packages/theme-chalk/src/fonts/element-icons.woff new file mode 100644 index 0000000..02b9a25 Binary files /dev/null and b/packages/theme-chalk/src/fonts/element-icons.woff differ diff --git a/packages/theme-chalk/src/footer.scss b/packages/theme-chalk/src/footer.scss new file mode 100644 index 0000000..71a67b0 --- /dev/null +++ b/packages/theme-chalk/src/footer.scss @@ -0,0 +1,8 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(footer) { + padding: $--footer-padding; + box-sizing: border-box; + flex-shrink: 0; +} diff --git a/packages/theme-chalk/src/form-item.scss b/packages/theme-chalk/src/form-item.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/form.scss b/packages/theme-chalk/src/form.scss new file mode 100644 index 0000000..2494ca0 --- /dev/null +++ b/packages/theme-chalk/src/form.scss @@ -0,0 +1,167 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "common/var"; + +@include b(form) { + @include m(label-left) { + & .el-form-item__label { + text-align: left; + } + } + @include m(label-top) { + & .el-form-item__label { + float: none; + display: inline-block; + text-align: left; + padding: 0 0 10px 0; + } + } + @include m(inline) { + & .el-form-item { + display: inline-block; + margin-right: 10px; + vertical-align: top; + } + & .el-form-item__label { + float: none; + display: inline-block; + } + & .el-form-item__content { + display: inline-block; + vertical-align: top; + } + &.el-form--label-top .el-form-item__content { + display: block; + } + } +} +@include b(form-item) { + margin-bottom: 22px; + @include utils-clearfix; + + & .el-form-item { + margin-bottom: 0; + } + + & .el-input__validateIcon { + display: none; + } + + @include m(medium) { + .el-form-item__label { + line-height: 36px; + } + .el-form-item__content { + line-height: 36px; + } + } + @include m(small) { + .el-form-item__label { + line-height: 32px; + } + .el-form-item__content { + line-height: 32px; + } + &.el-form-item { + margin-bottom: 18px; + } + .el-form-item__error { + padding-top: 2px; + } + } + @include m(mini) { + .el-form-item__label { + line-height: 28px; + } + .el-form-item__content { + line-height: 28px; + } + &.el-form-item { + margin-bottom: 18px; + } + .el-form-item__error { + padding-top: 1px; + } + } + + @include e(label-wrap) { + float: left; + .el-form-item__label { + display: inline-block; + float: none; + } + } + + @include e(label) { + text-align: right; + vertical-align: middle; + float: left; + font-size: $--form-label-font-size; + color: $--color-text-regular; + line-height: 40px; + padding: 0 12px 0 0; + box-sizing: border-box; + } + @include e(content) { + line-height: 40px; + position: relative; + font-size: 14px; + @include utils-clearfix; + + .el-input-group { + vertical-align: top; + } + } + @include e(error) { + color: $--color-danger; + font-size: 12px; + line-height: 1; + padding-top: 4px; + position: absolute; + top: 100%; + left: 0; + + @include m(inline) { + position: relative; + top: auto; + left: auto; + display: inline-block; + margin-left: 10px; + } + } + + @include when(required) { + @include pseudo('not(.is-no-asterisk)') { + & > .el-form-item__label:before, + & .el-form-item__label-wrap > .el-form-item__label:before { + content: '*'; + color: $--color-danger; + margin-right: 4px; + } + } + } + + @include when(error) { + & .el-input__inner, + & .el-textarea__inner { + &, &:focus { + border-color: $--color-danger; + } + } + & .el-input-group__append, + & .el-input-group__prepend { + & .el-input__inner { + border-color: transparent; + } + } + .el-input__validateIcon { + color: $--color-danger; + } + } + + @include m(feedback) { + .el-input__validateIcon { + display: inline-block; + } + } +} diff --git a/packages/theme-chalk/src/header.scss b/packages/theme-chalk/src/header.scss new file mode 100644 index 0000000..9e8a1d8 --- /dev/null +++ b/packages/theme-chalk/src/header.scss @@ -0,0 +1,8 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(header) { + padding: $--header-padding; + box-sizing: border-box; + flex-shrink: 0; +} diff --git a/packages/theme-chalk/src/icon.scss b/packages/theme-chalk/src/icon.scss new file mode 100644 index 0000000..25a4487 --- /dev/null +++ b/packages/theme-chalk/src/icon.scss @@ -0,0 +1,1167 @@ +@import "common/var"; + +@font-face { + font-family: 'element-icons'; + src: url('#{$--font-path}/element-icons.woff') format('woff'), /* chrome, firefox */ + url('#{$--font-path}/element-icons.ttf') format('truetype'); /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ + font-weight: normal; + font-display: $--font-display; + font-style: normal; +} + +[class^="el-icon-"], [class*=" el-icon-"] { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'element-icons' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: baseline; + display: inline-block; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.el-icon-ice-cream-round:before { + content: "\e6a0"; +} + +.el-icon-ice-cream-square:before { + content: "\e6a3"; +} + +.el-icon-lollipop:before { + content: "\e6a4"; +} + +.el-icon-potato-strips:before { + content: "\e6a5"; +} + +.el-icon-milk-tea:before { + content: "\e6a6"; +} + +.el-icon-ice-drink:before { + content: "\e6a7"; +} + +.el-icon-ice-tea:before { + content: "\e6a9"; +} + +.el-icon-coffee:before { + content: "\e6aa"; +} + +.el-icon-orange:before { + content: "\e6ab"; +} + +.el-icon-pear:before { + content: "\e6ac"; +} + +.el-icon-apple:before { + content: "\e6ad"; +} + +.el-icon-cherry:before { + content: "\e6ae"; +} + +.el-icon-watermelon:before { + content: "\e6af"; +} + +.el-icon-grape:before { + content: "\e6b0"; +} + +.el-icon-refrigerator:before { + content: "\e6b1"; +} + +.el-icon-goblet-square-full:before { + content: "\e6b2"; +} + +.el-icon-goblet-square:before { + content: "\e6b3"; +} + +.el-icon-goblet-full:before { + content: "\e6b4"; +} + +.el-icon-goblet:before { + content: "\e6b5"; +} + +.el-icon-cold-drink:before { + content: "\e6b6"; +} + +.el-icon-coffee-cup:before { + content: "\e6b8"; +} + +.el-icon-water-cup:before { + content: "\e6b9"; +} + +.el-icon-hot-water:before { + content: "\e6ba"; +} + +.el-icon-ice-cream:before { + content: "\e6bb"; +} + +.el-icon-dessert:before { + content: "\e6bc"; +} + +.el-icon-sugar:before { + content: "\e6bd"; +} + +.el-icon-tableware:before { + content: "\e6be"; +} + +.el-icon-burger:before { + content: "\e6bf"; +} + +.el-icon-knife-fork:before { + content: "\e6c1"; +} + +.el-icon-fork-spoon:before { + content: "\e6c2"; +} + +.el-icon-chicken:before { + content: "\e6c3"; +} + +.el-icon-food:before { + content: "\e6c4"; +} + +.el-icon-dish-1:before { + content: "\e6c5"; +} + +.el-icon-dish:before { + content: "\e6c6"; +} + +.el-icon-moon-night:before { + content: "\e6ee"; +} + +.el-icon-moon:before { + content: "\e6f0"; +} + +.el-icon-cloudy-and-sunny:before { + content: "\e6f1"; +} + +.el-icon-partly-cloudy:before { + content: "\e6f2"; +} + +.el-icon-cloudy:before { + content: "\e6f3"; +} + +.el-icon-sunny:before { + content: "\e6f6"; +} + +.el-icon-sunset:before { + content: "\e6f7"; +} + +.el-icon-sunrise-1:before { + content: "\e6f8"; +} + +.el-icon-sunrise:before { + content: "\e6f9"; +} + +.el-icon-heavy-rain:before { + content: "\e6fa"; +} + +.el-icon-lightning:before { + content: "\e6fb"; +} + +.el-icon-light-rain:before { + content: "\e6fc"; +} + +.el-icon-wind-power:before { + content: "\e6fd"; +} + +.el-icon-baseball:before { + content: "\e712"; +} + +.el-icon-soccer:before { + content: "\e713"; +} + +.el-icon-football:before { + content: "\e715"; +} + +.el-icon-basketball:before { + content: "\e716"; +} + +.el-icon-ship:before { + content: "\e73f"; +} + +.el-icon-truck:before { + content: "\e740"; +} + +.el-icon-bicycle:before { + content: "\e741"; +} + +.el-icon-mobile-phone:before { + content: "\e6d3"; +} + +.el-icon-service:before { + content: "\e6d4"; +} + +.el-icon-key:before { + content: "\e6e2"; +} + +.el-icon-unlock:before { + content: "\e6e4"; +} + +.el-icon-lock:before { + content: "\e6e5"; +} + +.el-icon-watch:before { + content: "\e6fe"; +} + +.el-icon-watch-1:before { + content: "\e6ff"; +} + +.el-icon-timer:before { + content: "\e702"; +} + +.el-icon-alarm-clock:before { + content: "\e703"; +} + +.el-icon-map-location:before { + content: "\e704"; +} + +.el-icon-delete-location:before { + content: "\e705"; +} + +.el-icon-add-location:before { + content: "\e706"; +} + +.el-icon-location-information:before { + content: "\e707"; +} + +.el-icon-location-outline:before { + content: "\e708"; +} + +.el-icon-location:before { + content: "\e79e"; +} + +.el-icon-place:before { + content: "\e709"; +} + +.el-icon-discover:before { + content: "\e70a"; +} + +.el-icon-first-aid-kit:before { + content: "\e70b"; +} + +.el-icon-trophy-1:before { + content: "\e70c"; +} + +.el-icon-trophy:before { + content: "\e70d"; +} + +.el-icon-medal:before { + content: "\e70e"; +} + +.el-icon-medal-1:before { + content: "\e70f"; +} + +.el-icon-stopwatch:before { + content: "\e710"; +} + +.el-icon-mic:before { + content: "\e711"; +} + +.el-icon-copy-document:before { + content: "\e718"; +} + +.el-icon-full-screen:before { + content: "\e719"; +} + +.el-icon-switch-button:before { + content: "\e71b"; +} + +.el-icon-aim:before { + content: "\e71c"; +} + +.el-icon-crop:before { + content: "\e71d"; +} + +.el-icon-odometer:before { + content: "\e71e"; +} + +.el-icon-time:before { + content: "\e71f"; +} + +.el-icon-bangzhu:before { + content: "\e724"; +} + +.el-icon-close-notification:before { + content: "\e726"; +} + +.el-icon-microphone:before { + content: "\e727"; +} + +.el-icon-turn-off-microphone:before { + content: "\e728"; +} + +.el-icon-position:before { + content: "\e729"; +} + +.el-icon-postcard:before { + content: "\e72a"; +} + +.el-icon-message:before { + content: "\e72b"; +} + +.el-icon-chat-line-square:before { + content: "\e72d"; +} + +.el-icon-chat-dot-square:before { + content: "\e72e"; +} + +.el-icon-chat-dot-round:before { + content: "\e72f"; +} + +.el-icon-chat-square:before { + content: "\e730"; +} + +.el-icon-chat-line-round:before { + content: "\e731"; +} + +.el-icon-chat-round:before { + content: "\e732"; +} + +.el-icon-set-up:before { + content: "\e733"; +} + +.el-icon-turn-off:before { + content: "\e734"; +} + +.el-icon-open:before { + content: "\e735"; +} + +.el-icon-connection:before { + content: "\e736"; +} + +.el-icon-link:before { + content: "\e737"; +} + +.el-icon-cpu:before { + content: "\e738"; +} + +.el-icon-thumb:before { + content: "\e739"; +} + +.el-icon-female:before { + content: "\e73a"; +} + +.el-icon-male:before { + content: "\e73b"; +} + +.el-icon-guide:before { + content: "\e73c"; +} + +.el-icon-news:before { + content: "\e73e"; +} + +.el-icon-price-tag:before { + content: "\e744"; +} + +.el-icon-discount:before { + content: "\e745"; +} + +.el-icon-wallet:before { + content: "\e747"; +} + +.el-icon-coin:before { + content: "\e748"; +} + +.el-icon-money:before { + content: "\e749"; +} + +.el-icon-bank-card:before { + content: "\e74a"; +} + +.el-icon-box:before { + content: "\e74b"; +} + +.el-icon-present:before { + content: "\e74c"; +} + +.el-icon-sell:before { + content: "\e6d5"; +} + +.el-icon-sold-out:before { + content: "\e6d6"; +} + +.el-icon-shopping-bag-2:before { + content: "\e74d"; +} + +.el-icon-shopping-bag-1:before { + content: "\e74e"; +} + +.el-icon-shopping-cart-2:before { + content: "\e74f"; +} + +.el-icon-shopping-cart-1:before { + content: "\e750"; +} + +.el-icon-shopping-cart-full:before { + content: "\e751"; +} + +.el-icon-smoking:before { + content: "\e752"; +} + +.el-icon-no-smoking:before { + content: "\e753"; +} + +.el-icon-house:before { + content: "\e754"; +} + +.el-icon-table-lamp:before { + content: "\e755"; +} + +.el-icon-school:before { + content: "\e756"; +} + +.el-icon-office-building:before { + content: "\e757"; +} + +.el-icon-toilet-paper:before { + content: "\e758"; +} + +.el-icon-notebook-2:before { + content: "\e759"; +} + +.el-icon-notebook-1:before { + content: "\e75a"; +} + +.el-icon-files:before { + content: "\e75b"; +} + +.el-icon-collection:before { + content: "\e75c"; +} + +.el-icon-receiving:before { + content: "\e75d"; +} + +.el-icon-suitcase-1:before { + content: "\e760"; +} + +.el-icon-suitcase:before { + content: "\e761"; +} + +.el-icon-film:before { + content: "\e763"; +} + +.el-icon-collection-tag:before { + content: "\e765"; +} + +.el-icon-data-analysis:before { + content: "\e766"; +} + +.el-icon-pie-chart:before { + content: "\e767"; +} + +.el-icon-data-board:before { + content: "\e768"; +} + +.el-icon-data-line:before { + content: "\e76d"; +} + +.el-icon-reading:before { + content: "\e769"; +} + +.el-icon-magic-stick:before { + content: "\e76a"; +} + +.el-icon-coordinate:before { + content: "\e76b"; +} + +.el-icon-mouse:before { + content: "\e76c"; +} + +.el-icon-brush:before { + content: "\e76e"; +} + +.el-icon-headset:before { + content: "\e76f"; +} + +.el-icon-umbrella:before { + content: "\e770"; +} + +.el-icon-scissors:before { + content: "\e771"; +} + +.el-icon-mobile:before { + content: "\e773"; +} + +.el-icon-attract:before { + content: "\e774"; +} + +.el-icon-monitor:before { + content: "\e775"; +} + +.el-icon-search:before { + content: "\e778"; +} + +.el-icon-takeaway-box:before { + content: "\e77a"; +} + +.el-icon-paperclip:before { + content: "\e77d"; +} + +.el-icon-printer:before { + content: "\e77e"; +} + +.el-icon-document-add:before { + content: "\e782"; +} + +.el-icon-document:before { + content: "\e785"; +} + +.el-icon-document-checked:before { + content: "\e786"; +} + +.el-icon-document-copy:before { + content: "\e787"; +} + +.el-icon-document-delete:before { + content: "\e788"; +} + +.el-icon-document-remove:before { + content: "\e789"; +} + +.el-icon-tickets:before { + content: "\e78b"; +} + +.el-icon-folder-checked:before { + content: "\e77f"; +} + +.el-icon-folder-delete:before { + content: "\e780"; +} + +.el-icon-folder-remove:before { + content: "\e781"; +} + +.el-icon-folder-add:before { + content: "\e783"; +} + +.el-icon-folder-opened:before { + content: "\e784"; +} + +.el-icon-folder:before { + content: "\e78a"; +} + +.el-icon-edit-outline:before { + content: "\e764"; +} + +.el-icon-edit:before { + content: "\e78c"; +} + +.el-icon-date:before { + content: "\e78e"; +} + +.el-icon-c-scale-to-original:before { + content: "\e7c6"; +} + +.el-icon-view:before { + content: "\e6ce"; +} + +.el-icon-loading:before { + content: "\e6cf"; +} + +.el-icon-rank:before { + content: "\e6d1"; +} + +.el-icon-sort-down:before { + content: "\e7c4"; +} + +.el-icon-sort-up:before { + content: "\e7c5"; +} + +.el-icon-sort:before { + content: "\e6d2"; +} + +.el-icon-finished:before { + content: "\e6cd"; +} + +.el-icon-refresh-left:before { + content: "\e6c7"; +} + +.el-icon-refresh-right:before { + content: "\e6c8"; +} + +.el-icon-refresh:before { + content: "\e6d0"; +} + +.el-icon-video-play:before { + content: "\e7c0"; +} + +.el-icon-video-pause:before { + content: "\e7c1"; +} + +.el-icon-d-arrow-right:before { + content: "\e6dc"; +} + +.el-icon-d-arrow-left:before { + content: "\e6dd"; +} + +.el-icon-arrow-up:before { + content: "\e6e1"; +} + +.el-icon-arrow-down:before { + content: "\e6df"; +} + +.el-icon-arrow-right:before { + content: "\e6e0"; +} + +.el-icon-arrow-left:before { + content: "\e6de"; +} + +.el-icon-top-right:before { + content: "\e6e7"; +} + +.el-icon-top-left:before { + content: "\e6e8"; +} + +.el-icon-top:before { + content: "\e6e6"; +} + +.el-icon-bottom:before { + content: "\e6eb"; +} + +.el-icon-right:before { + content: "\e6e9"; +} + +.el-icon-back:before { + content: "\e6ea"; +} + +.el-icon-bottom-right:before { + content: "\e6ec"; +} + +.el-icon-bottom-left:before { + content: "\e6ed"; +} + +.el-icon-caret-top:before { + content: "\e78f"; +} + +.el-icon-caret-bottom:before { + content: "\e790"; +} + +.el-icon-caret-right:before { + content: "\e791"; +} + +.el-icon-caret-left:before { + content: "\e792"; +} + +.el-icon-d-caret:before { + content: "\e79a"; +} + +.el-icon-share:before { + content: "\e793"; +} + +.el-icon-menu:before { + content: "\e798"; +} + +.el-icon-s-grid:before { + content: "\e7a6"; +} + +.el-icon-s-check:before { + content: "\e7a7"; +} + +.el-icon-s-data:before { + content: "\e7a8"; +} + +.el-icon-s-opportunity:before { + content: "\e7aa"; +} + +.el-icon-s-custom:before { + content: "\e7ab"; +} + +.el-icon-s-claim:before { + content: "\e7ad"; +} + +.el-icon-s-finance:before { + content: "\e7ae"; +} + +.el-icon-s-comment:before { + content: "\e7af"; +} + +.el-icon-s-flag:before { + content: "\e7b0"; +} + +.el-icon-s-marketing:before { + content: "\e7b1"; +} + +.el-icon-s-shop:before { + content: "\e7b4"; +} + +.el-icon-s-open:before { + content: "\e7b5"; +} + +.el-icon-s-management:before { + content: "\e7b6"; +} + +.el-icon-s-ticket:before { + content: "\e7b7"; +} + +.el-icon-s-release:before { + content: "\e7b8"; +} + +.el-icon-s-home:before { + content: "\e7b9"; +} + +.el-icon-s-promotion:before { + content: "\e7ba"; +} + +.el-icon-s-operation:before { + content: "\e7bb"; +} + +.el-icon-s-unfold:before { + content: "\e7bc"; +} + +.el-icon-s-fold:before { + content: "\e7a9"; +} + +.el-icon-s-platform:before { + content: "\e7bd"; +} + +.el-icon-s-order:before { + content: "\e7be"; +} + +.el-icon-s-cooperation:before { + content: "\e7bf"; +} + +.el-icon-bell:before { + content: "\e725"; +} + +.el-icon-message-solid:before { + content: "\e799"; +} + +.el-icon-video-camera:before { + content: "\e772"; +} + +.el-icon-video-camera-solid:before { + content: "\e796"; +} + +.el-icon-camera:before { + content: "\e779"; +} + +.el-icon-camera-solid:before { + content: "\e79b"; +} + +.el-icon-download:before { + content: "\e77c"; +} + +.el-icon-upload2:before { + content: "\e77b"; +} + +.el-icon-upload:before { + content: "\e7c3"; +} + +.el-icon-picture-outline-round:before { + content: "\e75f"; +} + +.el-icon-picture-outline:before { + content: "\e75e"; +} + +.el-icon-picture:before { + content: "\e79f"; +} + +.el-icon-close:before { + content: "\e6db"; +} + +.el-icon-check:before { + content: "\e6da"; +} + +.el-icon-plus:before { + content: "\e6d9"; +} + +.el-icon-minus:before { + content: "\e6d8"; +} + +.el-icon-help:before { + content: "\e73d"; +} + +.el-icon-s-help:before { + content: "\e7b3"; +} + +.el-icon-circle-close:before { + content: "\e78d"; +} + +.el-icon-circle-check:before { + content: "\e720"; +} + +.el-icon-circle-plus-outline:before { + content: "\e723"; +} + +.el-icon-remove-outline:before { + content: "\e722"; +} + +.el-icon-zoom-out:before { + content: "\e776"; +} + +.el-icon-zoom-in:before { + content: "\e777"; +} + +.el-icon-error:before { + content: "\e79d"; +} + +.el-icon-success:before { + content: "\e79c"; +} + +.el-icon-circle-plus:before { + content: "\e7a0"; +} + +.el-icon-remove:before { + content: "\e7a2"; +} + +.el-icon-info:before { + content: "\e7a1"; +} + +.el-icon-question:before { + content: "\e7a4"; +} + +.el-icon-warning-outline:before { + content: "\e6c9"; +} + +.el-icon-warning:before { + content: "\e7a3"; +} + +.el-icon-goods:before { + content: "\e7c2"; +} + +.el-icon-s-goods:before { + content: "\e7b2"; +} + +.el-icon-star-off:before { + content: "\e717"; +} + +.el-icon-star-on:before { + content: "\e797"; +} + +.el-icon-more-outline:before { + content: "\e6cc"; +} + +.el-icon-more:before { + content: "\e794"; +} + +.el-icon-phone-outline:before { + content: "\e6cb"; +} + +.el-icon-phone:before { + content: "\e795"; +} + +.el-icon-user:before { + content: "\e6e3"; +} + +.el-icon-user-solid:before { + content: "\e7a5"; +} + +.el-icon-setting:before { + content: "\e6ca"; +} + +.el-icon-s-tools:before { + content: "\e7ac"; +} + +.el-icon-delete:before { + content: "\e6d7"; +} + +.el-icon-delete-solid:before { + content: "\e7c9"; +} + +.el-icon-eleme:before { + content: "\e7c7"; +} + +.el-icon-platform-eleme:before { + content: "\e7ca"; +} + +.el-icon-loading { + animation: rotating 2s linear infinite; +} + +.el-icon--right { + margin-left: 5px; +} +.el-icon--left { + margin-right: 5px; +} + +@keyframes rotating { + 0% { + transform: rotateZ(0deg); + } + 100% { + transform: rotateZ(360deg); + } +} diff --git a/packages/theme-chalk/src/image.scss b/packages/theme-chalk/src/image.scss new file mode 100644 index 0000000..39358e6 --- /dev/null +++ b/packages/theme-chalk/src/image.scss @@ -0,0 +1,179 @@ +@import "mixins/mixins"; +@import "common/var"; + +%size { + width: 100%; + height: 100%; +} + +@include b(image) { + position: relative; + display: inline-block; + overflow: hidden; + + @include e(inner) { + @extend %size; + vertical-align: top; + + @include m(center) { + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: block; + } + } + + @include e(placeholder) { + @extend %size; + background: $--background-color-base; + } + + @include e(error) { + @extend %size; + display: flex; + justify-content: center; + align-items: center; + font-size: 14px; + background: $--background-color-base; + color: $--color-text-placeholder; + vertical-align: middle; + } + + @include e(preview) { + cursor: pointer; + } +} + + +@include b(image-viewer) { + + + @include e(wrapper) { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + @include e(btn) { + position: absolute; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + opacity: .8; + cursor: pointer; + box-sizing: border-box; + user-select: none; + } + + @include e(close) { + top: 40px; + right: 40px; + width: 40px; + height: 40px; + font-size: 24px; + color: #fff; + background-color: #606266; + } + + @include e(canvas) { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + @include e(actions) { + left: 50%; + bottom: 30px; + transform: translateX(-50%); + width: 282px; + height: 44px; + padding: 0 23px; + background-color: #606266; + border-color: #fff; + border-radius: 22px; + + @include e(actions__inner) { + width: 100%; + height: 100%; + text-align: justify; + cursor: default; + font-size: 23px; + color: #fff; + display: flex; + align-items: center; + justify-content: space-around; + } + } + + @include e(prev){ + top: 50%; + transform: translateY(-50%); + width: 44px; + height: 44px; + font-size: 24px; + color: #fff; + background-color: #606266; + border-color: #fff; + left: 40px; + } + + @include e(next){ + top: 50%; + transform: translateY(-50%); + width: 44px; + height: 44px; + font-size: 24px; + color: #fff; + background-color: #606266; + border-color: #fff; + right: 40px; + text-indent: 2px; + } + + @include e(mask) { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + opacity: .5; + background: #000; + } +} + +.viewer-fade-enter-active { + animation: viewer-fade-in .3s; +} + +.viewer-fade-leave-active { + animation: viewer-fade-out .3s; +} + +@keyframes viewer-fade-in { + 0% { + transform: translate3d(0, -20px, 0); + opacity: 0; + } + 100% { + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes viewer-fade-out { + 0% { + transform: translate3d(0, 0, 0); + opacity: 1; + } + 100% { + transform: translate3d(0, -20px, 0); + opacity: 0; + } +} diff --git a/packages/theme-chalk/src/index.scss b/packages/theme-chalk/src/index.scss new file mode 100644 index 0000000..3572c99 --- /dev/null +++ b/packages/theme-chalk/src/index.scss @@ -0,0 +1,80 @@ +@import "./base.scss"; +@import "./pagination.scss"; +@import "./dialog.scss"; +@import "./autocomplete.scss"; +@import "./dropdown.scss"; +@import "./dropdown-menu.scss"; +@import "./dropdown-item.scss"; +@import "./menu.scss"; +@import "./submenu.scss"; +@import "./menu-item.scss"; +@import "./menu-item-group.scss"; +@import "./input.scss"; +@import "./input-number.scss"; +@import "./radio.scss"; +@import "./radio-group.scss"; +@import "./radio-button.scss"; +@import "./checkbox.scss"; +@import "./checkbox-button.scss"; +@import "./checkbox-group.scss"; +@import "./switch.scss"; +@import "./select.scss"; +@import "./button.scss"; +@import "./button-group.scss"; +@import "./table.scss"; +@import "./table-column.scss"; +@import "./date-picker.scss"; +@import "./time-select.scss"; +@import "./time-picker.scss"; +@import "./popover.scss"; +@import "./tooltip.scss"; +@import "./message-box.scss"; +@import "./breadcrumb.scss"; +@import "./breadcrumb-item.scss"; +@import "./form.scss"; +@import "./form-item.scss"; +@import "./tabs.scss"; +@import "./tab-pane.scss"; +@import "./tag.scss"; +@import "./tree.scss"; +@import "./alert.scss"; +@import "./notification.scss"; +@import "./slider.scss"; +@import "./loading.scss"; +@import "./row.scss"; +@import "./col.scss"; +@import "./upload.scss"; +@import "./progress.scss"; +@import "./spinner.scss"; +@import "./message.scss"; +@import "./badge.scss"; +@import "./card.scss"; +@import "./rate.scss"; +@import "./steps.scss"; +@import "./step.scss"; +@import "./carousel.scss"; +@import "./scrollbar.scss"; +@import "./carousel-item.scss"; +@import "./collapse.scss"; +@import "./collapse-item.scss"; +@import "./cascader.scss"; +@import "./color-picker.scss"; +@import "./transfer.scss"; +@import "./container.scss"; +@import "./header.scss"; +@import "./aside.scss"; +@import "./main.scss"; +@import "./footer.scss"; +@import "./timeline.scss"; +@import "./timeline-item.scss"; +@import "./link.scss"; +@import "./divider.scss"; +@import "./image.scss"; +@import "./calendar.scss"; +@import "./backtop.scss"; +@import "./infinite-scroll.scss"; +@import "./page-header.scss"; +@import "./cascader-panel.scss"; +@import "./avatar.scss"; +@import "./drawer.scss"; +@import "./popconfirm.scss"; diff --git a/packages/theme-chalk/src/infinite-scroll.scss b/packages/theme-chalk/src/infinite-scroll.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/infiniteScroll.scss b/packages/theme-chalk/src/infiniteScroll.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/input-number.scss b/packages/theme-chalk/src/input-number.scss new file mode 100644 index 0000000..4e5109c --- /dev/null +++ b/packages/theme-chalk/src/input-number.scss @@ -0,0 +1,180 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "input"; + +@include b(input-number) { + position: relative; + display: inline-block; + width: 180px; + line-height: #{$--input-height - 2}; + + .el-input { + display: block; + + &__inner { + -webkit-appearance: none; + padding-left: #{$--input-height + 10}; + padding-right: #{$--input-height + 10}; + text-align: center; + } + } + + @include e((increase, decrease)) { + position: absolute; + z-index: 1; + top: 1px; + width: $--input-height; + height: auto; + text-align: center; + background: $--background-color-base; + color: $--color-text-regular; + cursor: pointer; + font-size: 13px; + + &:hover { + color: $--color-primary; + + &:not(.is-disabled) ~ .el-input .el-input__inner:not(.is-disabled) { + border-color: $--input-focus-border; + } + } + + &.is-disabled { + color: $--disabled-color-base; + cursor: not-allowed; + } + } + + @include e(increase) { + right: 1px; + border-radius: 0 $--border-radius-base $--border-radius-base 0; + border-left: $--border-base; + } + + @include e(decrease) { + left: 1px; + border-radius: $--border-radius-base 0 0 $--border-radius-base; + border-right: $--border-base; + } + + @include when(disabled) { + @include e((increase, decrease)) { + border-color: $--disabled-border-base; + color: $--disabled-border-base; + + &:hover { + color: $--disabled-border-base; + cursor: not-allowed; + } + } + } + + @include m(medium) { + width: 200px; + line-height: #{$--input-medium-height - 2}; + + @include e((increase, decrease)) { + width: $--input-medium-height; + font-size: $--input-medium-font-size; + } + + .el-input__inner { + padding-left: #{$--input-medium-height + 7}; + padding-right: #{$--input-medium-height + 7}; + } + } + + @include m(small) { + width: 130px; + line-height: #{$--input-small-height - 2}; + + @include e((increase, decrease)) { + width: $--input-small-height; + font-size: $--input-small-font-size; + + [class*=el-icon] { + transform: scale(.9); + } + } + + .el-input__inner { + padding-left: #{$--input-small-height + 7}; + padding-right: #{$--input-small-height + 7}; + } + } + + @include m(mini) { + width: 130px; + line-height: #{$--input-mini-height - 2}; + + @include e((increase, decrease)) { + width: $--input-mini-height; + font-size: $--input-mini-font-size; + + [class*=el-icon] { + transform: scale(.8); + } + } + + .el-input__inner { + padding-left: #{$--input-mini-height + 7}; + padding-right: #{$--input-mini-height + 7}; + } + } + + @include when(without-controls) { + .el-input__inner { + padding-left: 15px; + padding-right: 15px; + } + } + + @include when(controls-right) { + .el-input__inner { + padding-left: 15px; + padding-right: #{$--input-height + 10}; + } + + @include e((increase, decrease)) { + height: auto; + line-height: #{($--input-height - 2) / 2}; + + [class*=el-icon] { + transform: scale(.8); + } + } + + @include e(increase) { + border-radius: 0 $--border-radius-base 0 0; + border-bottom: $--border-base; + } + + @include e(decrease) { + right: 1px; + bottom: 1px; + top: auto; + left: auto; + border-right: none; + border-left: $--border-base; + border-radius: 0 0 $--border-radius-base 0; + } + + &[class*=medium] { + [class*=increase], [class*=decrease] { + line-height: #{($--input-medium-height - 2) / 2}; + } + } + + &[class*=small] { + [class*=increase], [class*=decrease] { + line-height: #{($--input-small-height - 2) / 2}; + } + } + + &[class*=mini] { + [class*=increase], [class*=decrease] { + line-height: #{($--input-mini-height - 2) / 2}; + } + } + } +} diff --git a/packages/theme-chalk/src/input.scss b/packages/theme-chalk/src/input.scss new file mode 100644 index 0000000..80df982 --- /dev/null +++ b/packages/theme-chalk/src/input.scss @@ -0,0 +1,356 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(textarea) { + position: relative; + display: inline-block; + width: 100%; + vertical-align: bottom; + font-size: $--font-size-base; + + @include e(inner) { + display: block; + resize: vertical; + padding: 5px 15px; + line-height: 1.5; + box-sizing: border-box; + width: 100%; + font-size: inherit; + color: $--input-font-color; + background-color: $--input-background-color; + background-image: none; + border: $--input-border; + border-radius: $--input-border-radius; + transition: $--border-transition-base; + + &::placeholder { + color: $--input-placeholder-color; + } + + &:hover { + border-color: $--input-hover-border; + } + + &:focus { + outline: none; + border-color: $--input-focus-border; + } + } + + & .el-input__count { + color: $--color-info; + background: $--color-white; + position: absolute; + font-size: 12px; + bottom: 5px; + right: 10px; + } + + @include when(disabled) { + .el-textarea__inner { + background-color: $--input-disabled-fill; + border-color: $--input-disabled-border; + color: $--input-disabled-color; + cursor: not-allowed; + + &::placeholder { + color: $--input-disabled-placeholder-color; + } + } + } + + @include when(exceed) { + .el-textarea__inner { + border-color: $--color-danger; + } + + .el-input__count { + color: $--color-danger; + } + } +} + +@include b(input) { + position: relative; + font-size: $--font-size-base; + display: inline-block; + width: 100%; + @include scroll-bar; + + & .el-input__clear { + color: $--input-icon-color; + font-size: $--input-font-size; + cursor: pointer; + transition: $--color-transition-base; + + &:hover { + color: $--input-clear-hover-color; + } + } + + & .el-input__count { + height: 100%; + display: inline-flex; + align-items: center; + color: $--color-info; + font-size: 12px; + + .el-input__count-inner { + background: $--color-white; + line-height: initial; + display: inline-block; + padding: 0 5px; + } + } + + @include e(inner) { + -webkit-appearance: none; + background-color: $--input-background-color; + background-image: none; + border-radius: $--input-border-radius; + border: $--input-border; + box-sizing: border-box; + color: $--input-font-color; + display: inline-block; + font-size: inherit; + height: $--input-height; + line-height: $--input-height; + outline: none; + padding: 0 15px; + transition: $--border-transition-base; + width: 100%; + + &::placeholder { + color: $--input-placeholder-color; + } + + &:hover { + border-color: $--input-hover-border; + } + + &:focus { + outline: none; + border-color: $--input-focus-border; + } + } + + @include e(suffix) { + position: absolute; + height: 100%; + right: 5px; + top: 0; + text-align: center; + color: $--input-icon-color; + transition: all .3s; + pointer-events: none; + } + + @include e(suffix-inner) { + pointer-events: all; + } + + @include e(prefix) { + position: absolute; + height: 100%; + left: 5px; + top: 0; + text-align: center; + color: $--input-icon-color; + transition: all .3s; + } + + @include e(icon) { + height: 100%; + width: 25px; + text-align: center; + transition: all .3s; + line-height: $--input-height; + + &:after { + content: ''; + height: 100%; + width: 0; + display: inline-block; + vertical-align: middle; + } + } + + @include e(validateIcon) { + pointer-events: none; + } + + @include when(active) { + .el-input__inner { + outline: none; + border-color: $--input-focus-border; + } + } + + @include when(disabled) { + .el-input__inner { + background-color: $--input-disabled-fill; + border-color: $--input-disabled-border; + color: $--input-disabled-color; + cursor: not-allowed; + + &::placeholder { + color: $--input-disabled-placeholder-color; + } + } + + .el-input__icon { + cursor: not-allowed; + } + } + + @include when(exceed) { + .el-input__inner { + border-color: $--color-danger; + } + + .el-input__suffix { + .el-input__count { + color: $--color-danger; + } + } + } + + @include m(suffix) { + .el-input__inner { + padding-right: 30px; + } + } + + @include m(prefix) { + .el-input__inner { + padding-left: 30px; + } + } + + @include m(medium) { + font-size: $--input-medium-font-size; + + @include e(inner) { + height: $--input-medium-height; + line-height: $--input-medium-height; + } + + .el-input__icon { + line-height: $--input-medium-height; + } + } + @include m(small) { + font-size: $--input-small-font-size; + + @include e(inner) { + height: $--input-small-height; + line-height: $--input-small-height; + } + + .el-input__icon { + line-height: $--input-small-height; + } + } + @include m(mini) { + font-size: $--input-mini-font-size; + + @include e(inner) { + height: $--input-mini-height; + line-height: $--input-mini-height; + } + + .el-input__icon { + line-height: $--input-mini-height; + } + } +} + +@include b(input-group) { + line-height: normal; + display: inline-table; + width: 100%; + border-collapse: separate; + border-spacing:0; + + > .el-input__inner { + vertical-align: middle; + display: table-cell; + } + + @include e((append, prepend)) { + background-color: $--background-color-base; + color: $--color-info; + vertical-align: middle; + display: table-cell; + position: relative; + border: $--border-base; + border-radius: $--input-border-radius; + padding: 0 20px; + width: 1px; + white-space: nowrap; + + &:focus { + outline: none; + } + + .el-select, + .el-button { + display: inline-block; + margin: -10px -20px; + } + + button.el-button, + div.el-select .el-input__inner, + div.el-select:hover .el-input__inner { + border-color: transparent; + background-color: transparent; + color: inherit; + border-top: 0; + border-bottom: 0; + } + + .el-button, + .el-input { + font-size: inherit; + } + } + + @include e(prepend) { + border-right: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + @include e(append) { + border-left: 0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + @include m(prepend) { + .el-input__inner { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .el-select .el-input.is-focus .el-input__inner { + border-color: transparent; + } + } + + @include m(append) { + .el-input__inner { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .el-select .el-input.is-focus .el-input__inner { + border-color: transparent; + } + } +} + +/** disalbe default clear on IE */ +.el-input__inner::-ms-clear { + display: none; + width: 0; + height: 0; +} diff --git a/packages/theme-chalk/src/link.scss b/packages/theme-chalk/src/link.scss new file mode 100644 index 0000000..704379f --- /dev/null +++ b/packages/theme-chalk/src/link.scss @@ -0,0 +1,81 @@ +@import "mixins/mixins"; +@import "common/var"; + +$typeMap: ( + primary: $--link-primary-font-color, + danger: $--link-danger-font-color, + success: $--link-success-font-color, + warning: $--link-warning-font-color, + info: $--link-info-font-color); + +@include b(link) { + display: inline-flex; + flex-direction: row; + align-items: center; + justify-content: center; + vertical-align: middle; + position: relative; + text-decoration: none; + outline: none; + cursor: pointer; + padding: 0; + font-size: $--link-font-size; + font-weight: $--link-font-weight; + + @include when(underline) { + &:hover:after { + content: ""; + position: absolute; + left: 0; + right: 0; + height: 0; + bottom: 0; + border-bottom: 1px solid $--link-default-active-color + } + } + + @include when(disabled) { + cursor: not-allowed; + } + + & [class*="el-icon-"] { + & + span { + margin-left: 5px; + } + } + + + &.el-link--default { + color: $--link-default-font-color; + &:hover { + color: $--link-default-active-color + } + &:after { + border-color: $--link-default-active-color + } + @include when(disabled) { + color: $--link-disabled-font-color + } + } + + @each $type, $primaryColor in $typeMap { + &.el-link--#{$type} { + color: $primaryColor; + &:hover { + color: mix($primaryColor, $--color-white, 80%) + } + &:after { + border-color: $primaryColor + } + @include when(disabled) { + color: mix($primaryColor, $--color-white, 50%) + } + @include when(underline) { + &:hover:after { + border-color: $primaryColor + } + } + } + } + +} diff --git a/packages/theme-chalk/src/loading.scss b/packages/theme-chalk/src/loading.scss new file mode 100644 index 0000000..d63e512 --- /dev/null +++ b/packages/theme-chalk/src/loading.scss @@ -0,0 +1,96 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(loading-parent) { + @include m(relative) { + position: relative !important; + } + + @include m(hidden) { + overflow: hidden !important; + } +} + +@include b(loading-mask) { + position: absolute; + z-index: 2000; + background-color: rgba(255, 255, 255, .9); + margin: 0; + top: 0; + right: 0; + bottom: 0; + left: 0; + transition: opacity 0.3s; + + @include when(fullscreen) { + position: fixed; + + .el-loading-spinner { + margin-top: #{- $--loading-fullscreen-spinner-size / 2}; + + .circular { + height: $--loading-fullscreen-spinner-size; + width: $--loading-fullscreen-spinner-size; + } + } + } +} + +@include b(loading-spinner) { + top: 50%; + margin-top: #{- $--loading-spinner-size / 2}; + width: 100%; + text-align: center; + position: absolute; + + .el-loading-text { + color: $--color-primary; + margin: 3px 0; + font-size: 14px; + } + + .circular { + height: $--loading-spinner-size; + width: $--loading-spinner-size; + animation: loading-rotate 2s linear infinite; + } + + .path { + animation: loading-dash 1.5s ease-in-out infinite; + stroke-dasharray: 90, 150; + stroke-dashoffset: 0; + stroke-width: 2; + stroke: $--color-primary; + stroke-linecap: round; + } + + i { + color: $--color-primary; + } +} + +.el-loading-fade-enter, +.el-loading-fade-leave-active { + opacity: 0; +} + +@keyframes loading-rotate { + 100% { + transform: rotate(360deg); + } +} + +@keyframes loading-dash { + 0% { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -40px; + } + 100% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -120px; + } +} diff --git a/packages/theme-chalk/src/main.scss b/packages/theme-chalk/src/main.scss new file mode 100644 index 0000000..3765af5 --- /dev/null +++ b/packages/theme-chalk/src/main.scss @@ -0,0 +1,12 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(main) { + // IE11 supports the
element partially https://caniuse.com/#search=main + display: block; + flex: 1; + flex-basis: auto; + overflow: auto; + box-sizing: border-box; + padding: $--main-padding; +} diff --git a/packages/theme-chalk/src/menu-item-group.scss b/packages/theme-chalk/src/menu-item-group.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/menu-item.scss b/packages/theme-chalk/src/menu-item.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/menu.scss b/packages/theme-chalk/src/menu.scss new file mode 100644 index 0000000..5b8c38e --- /dev/null +++ b/packages/theme-chalk/src/menu.scss @@ -0,0 +1,289 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "common/var"; +@import "common/transition"; + +@mixin menu-item { + height: 56px; + line-height: 56px; + font-size: $--menu-item-font-size; + color: $--menu-item-font-color; + padding: 0 20px; + list-style: none; + cursor: pointer; + position: relative; + transition: border-color .3s, background-color .3s, color .3s; + box-sizing: border-box; + white-space: nowrap; + + * { + vertical-align: middle; + } + + i { + color: $--color-text-secondary; + } + + &:hover, + &:focus { + outline: none; + background-color: $--menu-item-hover-fill; + } + + @include when(disabled) { + opacity: 0.25; + cursor: not-allowed; + background: none !important; + } +} + +@include b(menu) { + border-right: solid 1px #e6e6e6; + list-style: none; + position: relative; + margin: 0; + padding-left: 0; + background-color: $--menu-background-color; + @include utils-clearfix; + &.el-menu--horizontal { + border-bottom: solid 1px #e6e6e6; + } + + @include m(horizontal) { + border-right: none; + & > .el-menu-item { + float: left; + height: 60px; + line-height: 60px; + margin: 0; + border-bottom: 2px solid transparent; + color: $--color-text-secondary; + + a, + a:hover { + color: inherit; + } + + &:not(.is-disabled):hover, + &:not(.is-disabled):focus{ + background-color: #fff; + } + } + & > .el-submenu { + float: left; + + &:focus, + &:hover { + outline: none; + .el-submenu__title { + color: $--color-text-primary; + } + } + + &.is-active { + .el-submenu__title { + border-bottom: 2px solid $--color-primary; + color: $--color-text-primary; + } + } + + & .el-submenu__title { + height: 60px; + line-height: 60px; + border-bottom: 2px solid transparent; + color: $--color-text-secondary; + + &:hover { + background-color: #fff; + } + } + & .el-submenu__icon-arrow { + position: static; + vertical-align: middle; + margin-left: 8px; + margin-top: -3px; + } + } + & .el-menu { + & .el-menu-item, + & .el-submenu__title { + background-color: $--color-white; + float: none; + height: 36px; + line-height: 36px; + padding: 0 10px; + color: $--color-text-secondary; + } + & .el-menu-item.is-active, + & .el-submenu.is-active > .el-submenu__title { + color: $--color-text-primary; + } + } + & .el-menu-item:not(.is-disabled):hover, + & .el-menu-item:not(.is-disabled):focus { + outline: none; + color: $--color-text-primary; + } + & > .el-menu-item.is-active { + border-bottom: 2px solid $--color-primary; + color: $--color-text-primary; + } + } + @include m(collapse) { + width: 64px; + + > .el-menu-item, + > .el-submenu > .el-submenu__title { + [class^="el-icon-"] { + margin: 0; + vertical-align: middle; + width: 24px; + text-align: center; + } + .el-submenu__icon-arrow { + display: none; + } + span { + height: 0; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + } + + > .el-menu-item.is-active i { + color: inherit; + } + + .el-menu .el-submenu { + min-width: 200px; + } + + .el-submenu { + position: relative; + & .el-menu { + position: absolute; + margin-left: 5px; + top: 0; + left: 100%; + z-index: 10; + border: 1px solid $--border-color-light; + border-radius: $--border-radius-small; + box-shadow: $--box-shadow-light; + } + + &.is-opened { + > .el-submenu__title .el-submenu__icon-arrow { + transform: none; + } + } + } + } + @include m(popup) { + z-index: 100; + min-width: 200px; + border: none; + padding: 5px 0; + border-radius: $--border-radius-small; + box-shadow: $--box-shadow-light; + + &-bottom-start { + margin-top: 5px; + } + &-right-start { + margin-left: 5px; + margin-right: 5px; + } + } +} +@include b(menu-item) { + @include menu-item; + + & [class^="el-icon-"] { + margin-right: 5px; + width: 24px; + text-align: center; + font-size: 18px; + vertical-align: middle; + } + @include when(active) { + color: $--color-primary; + i { + color: inherit; + } + } +} + +@include b(submenu) { + list-style: none; + margin: 0; + padding-left: 0; + + @include e(title) { + @include menu-item; + + &:hover { + background-color: $--menu-item-hover-fill; + } + } + & .el-menu { + border: none; + } + & .el-menu-item { + height: 50px; + line-height: 50px; + padding: 0 45px; + min-width: 200px; + } + @include e(icon-arrow) { + position: absolute; + top: 50%; + right: 20px; + margin-top: -7px; + transition: transform .3s; + font-size: 12px; + } + @include when(active) { + .el-submenu__title { + border-bottom-color: $--color-primary; + } + } + @include when(opened) { + > .el-submenu__title .el-submenu__icon-arrow { + transform: rotateZ(180deg); + } + } + @include when(disabled) { + .el-submenu__title, + .el-menu-item { + opacity: 0.25; + cursor: not-allowed; + background: none !important; + } + } + [class^="el-icon-"] { + vertical-align: middle; + margin-right: 5px; + width: 24px; + text-align: center; + font-size: 18px; + } +} + +@include b(menu-item-group) { + > ul { + padding: 0; + } + @include e(title) { + padding: 7px 0 7px 20px; + line-height: normal; + font-size: 12px; + color: $--color-text-secondary; + } +} + +.horizontal-collapse-transition .el-submenu__title .el-submenu__icon-arrow { + transition: .2s; + opacity: 0; +} diff --git a/packages/theme-chalk/src/message-box.scss b/packages/theme-chalk/src/message-box.scss new file mode 100644 index 0000000..283ac7c --- /dev/null +++ b/packages/theme-chalk/src/message-box.scss @@ -0,0 +1,226 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "common/popup"; +@import "button"; +@import "input"; + +@include b(message-box) { + display: inline-block; + width: $--msgbox-width; + padding-bottom: 10px; + vertical-align: middle; + background-color: $--color-white; + border-radius: $--msgbox-border-radius; + border: 1px solid $--border-color-lighter; + font-size: $--messagebox-font-size; + box-shadow: $--box-shadow-light; + text-align: left; + overflow: hidden; + backface-visibility: hidden; + + @include e(wrapper) { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + text-align: center; + + &::after { + content: ""; + display: inline-block; + height: 100%; + width: 0; + vertical-align: middle; + } + } + + @include e(header) { + position: relative; + padding: $--msgbox-padding-primary; + padding-bottom: 10px; + } + + @include e(title) { + padding-left: 0; + margin-bottom: 0; + font-size: $--messagebox-font-size; + line-height: 1.3; + color: $--messagebox-title-color; + } + + @include e(headerbtn) { + position: absolute; + top: $--msgbox-padding-primary; + right: $--msgbox-padding-primary; + padding: 0; + border: none; + outline: none; + background: transparent; + font-size: $--message-close-size; + cursor: pointer; + + .el-message-box__close { + color: $--color-info; + } + + &:focus, &:hover { + .el-message-box__close { + color: $--color-primary; + } + } + + } + + @include e(content) { + padding: 10px $--msgbox-padding-primary; + color: $--messagebox-content-color; + font-size: $--messagebox-content-font-size; + } + + @include e(container) { + position: relative; + } + + @include e(input) { + padding-top: 15px; + + & input.invalid { + border-color: $--color-danger; + &:focus { + border-color: $--color-danger; + } + } + } + + @include e(status) { + position: absolute; + top: 14px; + font-size: 18px !important; + + &::before { + // 防止图标切割 + padding-left: 1px; + vertical-align: middle; + } + + + .el-message-box__message { + padding-left: 36px; + padding-right: 12px; + } + + &.el-icon-success { + color: $--messagebox-success-color; + } + + &.el-icon-info { + color: $--messagebox-info-color; + } + + &.el-icon-warning { + color: $--messagebox-warning-color; + } + + &.el-icon-error { + color: $--messagebox-danger-color; + } + } + + @include e(message) { + margin: 0; + + & p { + margin: 0; + line-height: 24px; + } + } + + @include e(errormsg) { + color: $--color-danger; + font-size: $--messagebox-error-font-size; + min-height: 18px; + margin-top: 2px; + } + + @include e(btns) { + padding: 5px 15px 0; + text-align: right; + + & button:nth-child(2) { + margin-left: 10px; + } + } + + @include e(btns-reverse) { + flex-direction: row-reverse; + } + + // centerAlign 布局 + @include m(center) { + padding-bottom: 30px; + + @include e(header) { + padding-top: 30px; + } + + @include e(title) { + position: relative; + display: flex; + align-items: center; + justify-content: center; + } + + @include e(status) { + position: relative; + top: auto; + padding-right: 5px; + text-align: center; + transform: translateY(-1px); + } + + @include e(message) { + margin-left: 0; + } + + @include e((btns, content)) { + text-align: center; + } + + @include e(content) { + $padding-horizontal: $--msgbox-padding-primary + 12px; + + padding-left: $padding-horizontal; + padding-right: $padding-horizontal; + } + } +} + +.msgbox-fade-enter-active { + animation: msgbox-fade-in .3s; +} + +.msgbox-fade-leave-active { + animation: msgbox-fade-out .3s; +} + +@keyframes msgbox-fade-in { + 0% { + transform: translate3d(0, -20px, 0); + opacity: 0; + } + 100% { + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes msgbox-fade-out { + 0% { + transform: translate3d(0, 0, 0); + opacity: 1; + } + 100% { + transform: translate3d(0, -20px, 0); + opacity: 0; + } +} diff --git a/packages/theme-chalk/src/message.scss b/packages/theme-chalk/src/message.scss new file mode 100644 index 0000000..58de084 --- /dev/null +++ b/packages/theme-chalk/src/message.scss @@ -0,0 +1,120 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(message) { + min-width: $--message-min-width; + box-sizing: border-box; + border-radius: $--border-radius-base; + border-width: $--border-width-base; + border-style: $--border-style-base; + border-color: $--border-color-lighter; + position: fixed; + left: 50%; + top: 20px; + transform: translateX(-50%); + background-color: $--message-background-color; + transition: opacity 0.3s, transform .4s, top 0.4s; + overflow: hidden; + padding: $--message-padding; + display: flex; + align-items: center; + + @include when(center) { + justify-content: center; + } + + @include when(closable) { + .el-message__content { + padding-right: 16px; + } + } + + p { + margin: 0; + } + + @include m(info) { + .el-message__content { + color: $--message-info-font-color; + } + } + + @include m(success) { + background-color: $--color-success-lighter; + border-color: $--color-success-light; + + .el-message__content { + color: $--message-success-font-color; + } + } + + @include m(warning) { + background-color: $--color-warning-lighter; + border-color: $--color-warning-light; + + .el-message__content { + color: $--message-warning-font-color; + } + } + + @include m(error) { + background-color: $--color-danger-lighter; + border-color: $--color-danger-light; + + .el-message__content { + color: $--message-danger-font-color; + } + } + + @include e(icon) { + margin-right: 10px; + } + + @include e(content) { + padding: 0; + font-size: 14px; + line-height: 1; + &:focus { + outline-width: 0; + } + } + + @include e(closeBtn) { + position: absolute; + top: 50%; + right: 15px; + transform: translateY(-50%); + cursor: pointer; + color: $--message-close-icon-color; + font-size: $--message-close-size; + + &:focus { + outline-width: 0; + } + &:hover { + color: $--message-close-hover-color; + } + } + + & .el-icon-success { + color: $--message-success-font-color; + } + + & .el-icon-error { + color: $--message-danger-font-color; + } + + & .el-icon-info { + color: $--message-info-font-color; + } + + & .el-icon-warning { + color: $--message-warning-font-color; + } +} + +.el-message-fade-enter, +.el-message-fade-leave-active { + opacity: 0; + transform: translate(-50%, -100%); +} diff --git a/packages/theme-chalk/src/mixins/_button.scss b/packages/theme-chalk/src/mixins/_button.scss new file mode 100644 index 0000000..03c86e5 --- /dev/null +++ b/packages/theme-chalk/src/mixins/_button.scss @@ -0,0 +1,81 @@ +@import "../common/var"; +@mixin button-plain($color) { + color: $color; + background: mix($--color-white, $color, 90%); + border-color: mix($--color-white, $color, 60%); + + &:hover, + &:focus { + background: $color; + border-color: $color; + color: $--color-white; + } + + &:active { + background: mix($--color-black, $color, $--button-active-shade-percent); + border-color: mix($--color-black, $color, $--button-active-shade-percent); + color: $--color-white; + outline: none; + } + + &.is-disabled { + &, + &:hover, + &:focus, + &:active { + color: mix($--color-white, $color, 40%); + background-color: mix($--color-white, $color, 90%); + border-color: mix($--color-white, $color, 80%); + } + } +} + +@mixin button-variant($color, $background-color, $border-color) { + color: $color; + background-color: $background-color; + border-color: $border-color; + + &:hover, + &:focus { + background: mix($--color-white, $background-color, $--button-hover-tint-percent); + border-color: mix($--color-white, $border-color, $--button-hover-tint-percent); + color: $color; + } + + &:active { + background: mix($--color-black, $background-color, $--button-active-shade-percent); + border-color: mix($--color-black, $border-color, $--button-active-shade-percent); + color: $color; + outline: none; + } + + &.is-active { + background: mix($--color-black, $background-color, $--button-active-shade-percent); + border-color: mix($--color-black, $border-color, $--button-active-shade-percent); + color: $color; + } + + &.is-disabled { + &, + &:hover, + &:focus, + &:active { + color: $--color-white; + background-color: mix($background-color, $--color-white); + border-color: mix($border-color, $--color-white); + } + } + + &.is-plain { + @include button-plain($background-color); + } +} + +@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $border-radius) { + padding: $padding-vertical $padding-horizontal; + font-size: $font-size; + border-radius: $border-radius; + &.is-round { + padding: $padding-vertical $padding-horizontal; + } +} diff --git a/packages/theme-chalk/src/mixins/config.scss b/packages/theme-chalk/src/mixins/config.scss new file mode 100644 index 0000000..87e29b4 --- /dev/null +++ b/packages/theme-chalk/src/mixins/config.scss @@ -0,0 +1,4 @@ +$namespace: 'el'; +$element-separator: '__'; +$modifier-separator: '--'; +$state-prefix: 'is-'; diff --git a/packages/theme-chalk/src/mixins/function.scss b/packages/theme-chalk/src/mixins/function.scss new file mode 100644 index 0000000..f348cb6 --- /dev/null +++ b/packages/theme-chalk/src/mixins/function.scss @@ -0,0 +1,44 @@ +@import "config"; + +/* BEM support Func + -------------------------- */ +@function selectorToString($selector) { + $selector: inspect($selector); + $selector: str-slice($selector, 2, -2); + @return $selector; +} + +@function containsModifier($selector) { + $selector: selectorToString($selector); + + @if str-index($selector, $modifier-separator) { + @return true; + } @else { + @return false; + } +} + +@function containWhenFlag($selector) { + $selector: selectorToString($selector); + + @if str-index($selector, '.' + $state-prefix) { + @return true + } @else { + @return false + } +} + +@function containPseudoClass($selector) { + $selector: selectorToString($selector); + + @if str-index($selector, ':') { + @return true + } @else { + @return false + } +} + +@function hitAllSpecialNestRule($selector) { + + @return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector); +} diff --git a/packages/theme-chalk/src/mixins/mixins.scss b/packages/theme-chalk/src/mixins/mixins.scss new file mode 100644 index 0000000..0805b07 --- /dev/null +++ b/packages/theme-chalk/src/mixins/mixins.scss @@ -0,0 +1,190 @@ +@import "function"; +@import "../common/var"; + +/* Break-points + -------------------------- */ +@mixin res($key, $map: $--breakpoints) { + // 循环断点Map,如果存在则返回 + @if map-has-key($map, $key) { + @media only screen and #{inspect(map-get($map, $key))} { + @content; + } + } @else { + @warn "Undefeined points: `#{$map}`"; + } +} + +/* Scrollbar + -------------------------- */ +@mixin scroll-bar { + $--scrollbar-thumb-background: #b4bccc; + $--scrollbar-track-background: #fff; + + &::-webkit-scrollbar { + z-index: 11; + width: 6px; + + &:horizontal { + height: 6px; + } + + &-thumb { + border-radius: 5px; + width: 6px; + background: $--scrollbar-thumb-background; + } + + &-corner { + background: $--scrollbar-track-background; + } + + &-track { + background: $--scrollbar-track-background; + + &-piece { + background: $--scrollbar-track-background; + width: 6px; + } + } + } +} + +/* Placeholder + -------------------------- */ +@mixin placeholder { + &::-webkit-input-placeholder { + @content + } + + &::-moz-placeholder { + @content + } + + &:-ms-input-placeholder { + @content + } +} + +/* BEM + -------------------------- */ +@mixin b($block) { + $B: $namespace+'-'+$block !global; + + .#{$B} { + @content; + } +} + +@mixin e($element) { + $E: $element !global; + $selector: &; + $currentSelector: ""; + @each $unit in $element { + $currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","}; + } + + @if hitAllSpecialNestRule($selector) { + @at-root { + #{$selector} { + #{$currentSelector} { + @content; + } + } + } + } @else { + @at-root { + #{$currentSelector} { + @content; + } + } + } +} + +@mixin m($modifier) { + $selector: &; + $currentSelector: ""; + @each $unit in $modifier { + $currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","}; + } + + @at-root { + #{$currentSelector} { + @content; + } + } +} + +@mixin configurable-m($modifier, $E-flag: false) { + $selector: &; + $interpolation: ''; + + @if $E-flag { + $interpolation: $element-separator + $E-flag; + } + + @at-root { + #{$selector} { + .#{$B+$interpolation+$modifier-separator+$modifier} { + @content; + } + } + } +} + +@mixin spec-selector($specSelector: '', $element: $E, $modifier: false, $block: $B) { + $modifierCombo: ''; + + @if $modifier { + $modifierCombo: $modifier-separator + $modifier; + } + + @at-root { + #{&}#{$specSelector}.#{$block+$element-separator+$element+$modifierCombo} { + @content + } + } +} + +@mixin meb($modifier: false, $element: $E, $block: $B) { + $selector: &; + $modifierCombo: ''; + + @if $modifier { + $modifierCombo: $modifier-separator + $modifier; + } + + @at-root { + #{$selector} { + .#{$block+$element-separator+$element+$modifierCombo} { + @content + } + } + } +} + +@mixin when($state) { + @at-root { + &.#{$state-prefix + $state} { + @content; + } + } +} + +@mixin extend-rule($name) { + @extend #{'%shared-'+$name}; +} + +@mixin share-rule($name) { + $rule-name: '%shared-'+$name; + + @at-root #{$rule-name} { + @content + } +} + +@mixin pseudo($pseudo) { + @at-root #{&}#{':#{$pseudo}'} { + @content + } +} + diff --git a/packages/theme-chalk/src/mixins/utils.scss b/packages/theme-chalk/src/mixins/utils.scss new file mode 100644 index 0000000..a642326 --- /dev/null +++ b/packages/theme-chalk/src/mixins/utils.scss @@ -0,0 +1,39 @@ +@mixin utils-user-select($value) { + -moz-user-select: $value; + -webkit-user-select: $value; + -ms-user-select: $value; +} + +@mixin utils-clearfix { + $selector: &; + + @at-root { + #{$selector}::before, + #{$selector}::after { + display: table; + content: ""; + } + #{$selector}::after { + clear: both + } + } +} + +@mixin utils-vertical-center { + $selector: &; + + @at-root { + #{$selector}::after { + display: inline-block; + content: ""; + height: 100%; + vertical-align: middle + } + } +} + +@mixin utils-ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} \ No newline at end of file diff --git a/packages/theme-chalk/src/notification.scss b/packages/theme-chalk/src/notification.scss new file mode 100644 index 0000000..1105e23 --- /dev/null +++ b/packages/theme-chalk/src/notification.scss @@ -0,0 +1,99 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(notification) { + display: flex; + width: $--notification-width; + padding: $--notification-padding; + border-radius: $--notification-radius; + box-sizing: border-box; + border: 1px solid $--notification-border-color; + position: fixed; + background-color: $--color-white; + box-shadow: $--notification-shadow; + transition: opacity .3s, transform .3s, left .3s, right .3s, top 0.4s, bottom .3s; + overflow: hidden; + + &.right { + right: 16px; + } + + &.left { + left: 16px; + } + + @include e(group) { + margin-left: $--notification-group-margin-left; + margin-right: $--notification-group-margin-right; + } + + @include e(title) { + font-weight: bold; + font-size: $--notification-title-font-size; + color: $--notification-title-color; + margin: 0; + } + + @include e(content) { + font-size: $--notification-content-font-size; + line-height: 21px; + margin: 6px 0 0 0; + color: $--notification-content-color; + text-align: justify; + + p { + margin: 0; + } + } + + @include e(icon) { + height: $--notification-icon-size; + width: $--notification-icon-size; + font-size: $--notification-icon-size; + } + + @include e(closeBtn) { + position: absolute; + top: 18px; + right: 15px; + cursor: pointer; + color: $--notification-close-color; + font-size: $--notification-close-font-size; + + &:hover { + color: $--notification-close-hover-color; + } + } + + .el-icon-success { + color: $--notification-success-icon-color; + } + + .el-icon-error { + color: $--notification-danger-icon-color; + } + + .el-icon-info { + color: $--notification-info-icon-color; + } + + .el-icon-warning { + color: $--notification-warning-icon-color; + } +} + +.el-notification-fade-enter { + &.right { + right: 0; + transform: translateX(100%); + } + + &.left { + left: 0; + transform: translateX(-100%); + } +} + +.el-notification-fade-leave-active { + opacity: 0; +} diff --git a/packages/theme-chalk/src/option-group.scss b/packages/theme-chalk/src/option-group.scss new file mode 100644 index 0000000..c68addb --- /dev/null +++ b/packages/theme-chalk/src/option-group.scss @@ -0,0 +1,42 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(select-group) { + $gap: 20px; + + margin: 0; + padding: 0; + + @include e(wrap) { + position: relative; + list-style: none; + margin: 0; + padding: 0; + + &:not(:last-of-type) { + padding-bottom: 24px; + + &::after { + content: ''; + position: absolute; + display: block; + left: $gap; + right: $gap; + bottom: 12px; + height: 1px; + background: $--border-color-light; + } + } + } + + @include e(title) { + padding-left: $gap; + font-size: $--select-group-font-size; + color: $--select-group-color; + line-height: $--select-group-height; + } + + & .el-select-dropdown__item { + padding-left: $gap; + } +} diff --git a/packages/theme-chalk/src/option.scss b/packages/theme-chalk/src/option.scss new file mode 100644 index 0000000..ee5a383 --- /dev/null +++ b/packages/theme-chalk/src/option.scss @@ -0,0 +1,36 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(select-dropdown) { + @include e(item) { + font-size: $--select-font-size; + padding: 0 20px; + position: relative; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + color: $--select-option-color; + height: $--select-option-height; + line-height: $--select-option-height; + box-sizing: border-box; + cursor: pointer; + + @include when(disabled) { + color: $--select-option-disabled-color; + cursor: not-allowed; + + &:hover { + background-color: $--color-white; + } + } + + &.hover, &:hover { + background-color: $--select-option-hover-background; + } + + &.selected { + color: $--select-option-selected-font-color; + font-weight: bold; + } + } +} diff --git a/packages/theme-chalk/src/page-header.scss b/packages/theme-chalk/src/page-header.scss new file mode 100644 index 0000000..14c19fa --- /dev/null +++ b/packages/theme-chalk/src/page-header.scss @@ -0,0 +1,41 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(page-header) { + display: flex; + line-height: 24px; + + @include e(left) { + display: flex; + cursor: pointer; + margin-right: 40px; + position: relative; + + &::after { + content: ""; + position: absolute; + width: 1px; + height: 16px; + right: -20px; + top: 50%; + transform: translateY(-50%); + background-color: $--border-color-base; + } + + .el-icon-back { + font-size: 18px; + margin-right: 6px; + align-self: center; + } + + @include e(title) { + font-size: 14px; + font-weight: 500; + } + } + + @include e(content) { + font-size: 18px; + color: $--color-text-primary; + } +} diff --git a/packages/theme-chalk/src/pagination.scss b/packages/theme-chalk/src/pagination.scss new file mode 100644 index 0000000..02384e6 --- /dev/null +++ b/packages/theme-chalk/src/pagination.scss @@ -0,0 +1,295 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "common/var"; +@import "select"; + +@include b(pagination) { + white-space: nowrap; + padding: 2px 5px; + color: $--pagination-font-color; + font-weight: bold; + @include utils-clearfix; + + span:not([class*=suffix]), + button { + display: inline-block; + font-size: $--pagination-font-size; + min-width: $--pagination-button-width; + height: $--pagination-button-height; + line-height: $--pagination-button-height; + vertical-align: top; + box-sizing: border-box; + } + + .el-input__inner { + text-align: center; + -moz-appearance: textfield; + line-height: normal; + } + + // pagesize 的下拉 icon + .el-input__suffix { + right: 0; + transform: scale(.8); + } + + .el-select .el-input { + width: 100px; + margin: 0 5px; + + .el-input__inner { + padding-right: 25px; + border-radius: $--pagination-border-radius; + } + } + + button { + border: none; + padding: 0 6px; + background: transparent; + + &:focus { + outline: none; + } + + &:hover { + color: $--pagination-hover-color; + } + + &:disabled { + color: $--pagination-button-disabled-color; + background-color: $--pagination-button-disabled-background-color; + cursor: not-allowed; + } + } + + .btn-prev, + .btn-next { + background: center center no-repeat; + background-size: 16px; + background-color: $--pagination-background-color; + cursor: pointer; + margin: 0; + color: $--pagination-button-color; + + .el-icon { + display: block; + font-size: 12px; + font-weight: bold; + } + } + + .btn-prev { + padding-right: 12px; + } + + .btn-next { + padding-left: 12px; + } + + .el-pager li.disabled { + color: $--color-text-placeholder; + cursor: not-allowed; + } + + @include m(small) { + .btn-prev, + .btn-next, + .el-pager li, + .el-pager li.btn-quicknext, + .el-pager li.btn-quickprev, + .el-pager li:last-child { + border-color: transparent; + font-size: 12px; + line-height: 22px; + height: 22px; + min-width: 22px; + } + + .arrow.disabled { + visibility: hidden; + } + + .more::before, + li.more::before { + line-height: 24px; + } + + span:not([class*=suffix]), + button { + height: 22px; + line-height: 22px; + } + + @include e(editor) { + height: 22px; + &.el-input .el-input__inner { + height: 22px; + } + } + } + + @include e(sizes) { + margin: 0 10px 0 0; + font-weight: normal; + color: $--color-text-regular; + + .el-input .el-input__inner { + font-size: $--pagination-font-size; + padding-left: 8px; + + &:hover { + border-color: $--pagination-hover-color; + } + } + } + + @include e(total) { + margin-right: 10px; + font-weight: normal; + color: $--color-text-regular; + } + + @include e(jump) { + margin-left: 24px; + font-weight: normal; + color: $--color-text-regular; + + .el-input__inner { + padding: 0 3px; + } + } + + @include e(rightwrapper) { + float: right; + } + + @include e(editor) { + line-height: 18px; + padding: 0 2px; + height: $--pagination-button-height; + + text-align: center; + margin: 0 2px; + box-sizing: border-box; + border-radius: $--pagination-border-radius; + + &.el-input { + width: 50px; + } + + &.el-input .el-input__inner { + height: $--pagination-button-height; + } + + .el-input__inner::-webkit-inner-spin-button, + .el-input__inner::-webkit-outer-spin-button { + -webkit-appearance: none; + 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; + + &.disabled { + color: $--color-text-placeholder; + } + } + + .btn-prev, .btn-next { + padding: 0; + + &:disabled { + color: $--color-text-placeholder; + } + } + + .el-pager li:not(.disabled) { + &:hover { + color: $--pagination-hover-color; + } + + &.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) { + user-select: none; + list-style: none; + display: inline-block; + vertical-align: top; + font-size: 0; + padding: 0; + margin: 0; + + .more::before { + line-height: 30px; + } + + li { + padding: 0 4px; + background: $--pagination-background-color; + vertical-align: top; + display: inline-block; + font-size: $--pagination-font-size; + min-width: $--pagination-button-width; + height: $--pagination-button-height; + line-height: $--pagination-button-height; + cursor: pointer; + box-sizing: border-box; + text-align: center; + margin: 0; + + &.btn-quicknext, + &.btn-quickprev { + line-height: 28px; + color: $--pagination-button-color; + + &.disabled { + color: $--color-text-placeholder; + } + } + + &.btn-quickprev:hover { + cursor: pointer; + } + + &.btn-quicknext:hover { + cursor: pointer; + } + + &.active + li { + border-left: 0; + } + + &:hover { + color: $--pagination-hover-color; + } + + &.active { + color: $--pagination-hover-color; + cursor: default; + } + } +} diff --git a/packages/theme-chalk/src/popconfirm.scss b/packages/theme-chalk/src/popconfirm.scss new file mode 100644 index 0000000..bc4bb52 --- /dev/null +++ b/packages/theme-chalk/src/popconfirm.scss @@ -0,0 +1,16 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(popconfirm) { + @include e(main) { + display: flex; + align-items: center; + } + @include e(icon) { + margin-right: 5px; + } + @include e(action) { + text-align: right; + margin: 0 + } +} diff --git a/packages/theme-chalk/src/popover.scss b/packages/theme-chalk/src/popover.scss new file mode 100644 index 0000000..896712a --- /dev/null +++ b/packages/theme-chalk/src/popover.scss @@ -0,0 +1,40 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "./popper"; + +@include b(popover) { + position: absolute; + background: $--popover-background-color; + min-width: 150px; + border-radius: 4px; + border: 1px solid $--popover-border-color; + padding: $--popover-padding; + z-index: $--index-popper; + color: $--color-text-regular; + line-height: 1.4; + text-align: justify; + font-size: $--popover-font-size; + box-shadow: $--box-shadow-light; + word-break: break-all; + + @include m(plain) { + padding: $--popover-padding-large; + } + + @include e(title) { + color: $--popover-title-font-color; + font-size: $--popover-title-font-size; + line-height: 1; + margin-bottom: 12px; + } + + @include e(reference) { + &:focus:not(.focusing), &:focus:hover { + outline-width: 0; + } + } + + &:focus:active, &:focus { + outline-width: 0; + } +} diff --git a/packages/theme-chalk/src/popper.scss b/packages/theme-chalk/src/popper.scss new file mode 100644 index 0000000..2104f59 --- /dev/null +++ b/packages/theme-chalk/src/popper.scss @@ -0,0 +1,101 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(popper) { + .popper__arrow, + .popper__arrow::after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + } + + .popper__arrow { + border-width: $--popover-arrow-size; + filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03)) + } + + .popper__arrow::after { + content: " "; + border-width: $--popover-arrow-size; + } + + &[x-placement^="top"] { + margin-bottom: #{$--popover-arrow-size + 6}; + } + + &[x-placement^="top"] .popper__arrow { + bottom: -$--popover-arrow-size; + left: 50%; + margin-right: #{$--tooltip-arrow-size / 2}; + border-top-color: $--popover-border-color; + border-bottom-width: 0; + + &::after { + bottom: 1px; + margin-left: -$--popover-arrow-size; + border-top-color: $--popover-background-color; + border-bottom-width: 0; + } + } + + &[x-placement^="bottom"] { + margin-top: #{$--popover-arrow-size + 6}; + } + + &[x-placement^="bottom"] .popper__arrow { + top: -$--popover-arrow-size; + left: 50%; + margin-right: #{$--tooltip-arrow-size / 2}; + border-top-width: 0; + border-bottom-color: $--popover-border-color; + + &::after { + top: 1px; + margin-left: -$--popover-arrow-size; + border-top-width: 0; + border-bottom-color: $--popover-background-color; + } + } + + &[x-placement^="right"] { + margin-left: #{$--popover-arrow-size + 6}; + } + + &[x-placement^="right"] .popper__arrow { + top: 50%; + left: -$--popover-arrow-size; + margin-bottom: #{$--tooltip-arrow-size / 2}; + border-right-color: $--popover-border-color; + border-left-width: 0; + + &::after { + bottom: -$--popover-arrow-size; + left: 1px; + border-right-color: $--popover-background-color; + border-left-width: 0; + } + } + + &[x-placement^="left"] { + margin-right: #{$--popover-arrow-size + 6}; + } + + &[x-placement^="left"] .popper__arrow { + top: 50%; + right: -$--popover-arrow-size; + margin-bottom: #{$--tooltip-arrow-size / 2}; + border-right-width: 0; + border-left-color: $--popover-border-color; + + &::after { + right: 1px; + bottom: -$--popover-arrow-size; + margin-left: -$--popover-arrow-size; + border-right-width: 0; + border-left-color: $--popover-background-color; + } + } +} \ No newline at end of file diff --git a/packages/theme-chalk/src/progress.scss b/packages/theme-chalk/src/progress.scss new file mode 100644 index 0000000..e6139f5 --- /dev/null +++ b/packages/theme-chalk/src/progress.scss @@ -0,0 +1,141 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "common/var"; + +@include b(progress) { + position: relative; + line-height: 1; + + @include e(text) { + font-size:14px; + color: $--color-text-regular; + display: inline-block; + vertical-align: middle; + margin-left: 10px; + line-height: 1; + + i { + vertical-align: middle; + display: block; + } + } + + @include m((circle,dashboard)) { + display: inline-block; + + .el-progress__text { + position: absolute; + top: 50%; + left: 0; + width: 100%; + text-align: center; + margin: 0; + transform: translate(0, -50%); + + i { + vertical-align: middle; + display: inline-block; + } + } + } + + + @include m(without-text) { + .el-progress__text { + display: none; + } + + .el-progress-bar { + padding-right: 0; + margin-right: 0; + display: block; + } + } + + @include m(text-inside) { + .el-progress-bar { + padding-right: 0; + margin-right: 0; + } + } + + @include when(success) { + .el-progress-bar__inner { + background-color: $--color-success; + } + + .el-progress__text { + color: $--color-success; + } + } + + @include when(warning) { + .el-progress-bar__inner { + background-color: $--color-warning; + } + + .el-progress__text { + color: $--color-warning; + } + } + + @include when(exception) { + .el-progress-bar__inner { + background-color: $--color-danger; + } + + .el-progress__text { + color: $--color-danger; + } + } +} + +@include b(progress-bar) { + padding-right: 50px; + display: inline-block; + vertical-align: middle; + width: 100%; + margin-right: -55px; + box-sizing: border-box; + + @include e(outer) { + height: 6px; + border-radius: 100px; + background-color: $--border-color-lighter; + overflow: hidden; + position: relative; + vertical-align: middle; + } + @include e(inner) { + position: absolute; + left: 0; + top: 0; + height: 100%; + background-color: $--color-primary; + text-align: right; + border-radius: 100px; + line-height: 1; + white-space: nowrap; + transition: width 0.6s ease; + + @include utils-vertical-center; + } + + @include e(innerText) { + display: inline-block; + vertical-align: middle; + color: $--color-white; + font-size: 12px; + margin: 0 5px; + } +} + +@keyframes progress { + 0% { + background-position: 0 0; + } + + 100% { + background-position: 32px 0; + } +} diff --git a/packages/theme-chalk/src/radio-button.scss b/packages/theme-chalk/src/radio-button.scss new file mode 100644 index 0000000..bd4215e --- /dev/null +++ b/packages/theme-chalk/src/radio-button.scss @@ -0,0 +1,113 @@ +@import "mixins/mixins"; +@import "mixins/_button"; +@import "common/var"; + +@include b(radio-button) { + position: relative; + display: inline-block; + outline: none; + + @include e(inner) { + display: inline-block; + line-height: 1; + white-space: nowrap; + vertical-align: middle; + background: $--button-default-background-color; + border: $--border-base; + font-weight: $--button-font-weight; + border-left: 0; + color: $--button-default-font-color; + -webkit-appearance: none; + text-align: center; + box-sizing: border-box; + outline: none; + margin: 0; + position: relative; + cursor: pointer; + transition: $--all-transition; + + @include button-size($--button-padding-vertical, $--button-padding-horizontal, $--button-font-size, 0); + + &:hover { + color: $--color-primary; + } + + & [class*="el-icon-"] { + line-height: 0.9; + + & + span { + margin-left: 5px; + } + } + } + + &:first-child { + .el-radio-button__inner { + border-left: $--border-base; + border-radius: $--border-radius-base 0 0 $--border-radius-base; + box-shadow: none !important; + } + } + + @include e(orig-radio) { + opacity: 0; + outline: none; + position: absolute; + z-index: -1; + + &:checked { + & + .el-radio-button__inner { + color: $--radio-button-checked-font-color; + background-color: $--radio-button-checked-background-color; + border-color: $--radio-button-checked-border-color; + box-shadow: -1px 0 0 0 $--radio-button-checked-border-color; + } + } + + &:disabled { + & + .el-radio-button__inner { + color: $--button-disabled-font-color; + cursor: not-allowed; + background-image: none; + background-color: $--button-disabled-background-color; + border-color: $--button-disabled-border-color; + box-shadow: none; + } + &:checked + .el-radio-button__inner { + background-color: $--radio-button-disabled-checked-fill; + } + } + } + + &:last-child { + .el-radio-button__inner { + border-radius: 0 $--border-radius-base $--border-radius-base 0; + } + } + + &:first-child:last-child { + .el-radio-button__inner { + border-radius: $--border-radius-base; + } + } + + @include m(medium) { + & .el-radio-button__inner { + @include button-size($--button-medium-padding-vertical, $--button-medium-padding-horizontal, $--button-medium-font-size, 0); + } + } + @include m(small) { + & .el-radio-button__inner { + @include button-size($--button-small-padding-vertical, $--button-small-padding-horizontal, $--button-small-font-size, 0); + } + } + @include m(mini) { + & .el-radio-button__inner { + @include button-size($--button-mini-padding-vertical, $--button-mini-padding-horizontal, $--button-mini-font-size, 0); + } + } + + &:focus:not(.is-focus):not(:active):not(.is-disabled){ /*获得焦点时 样式提醒*/ + box-shadow: 0 0 2px 2px $--radio-button-checked-border-color; + } +} diff --git a/packages/theme-chalk/src/radio-group.scss b/packages/theme-chalk/src/radio-group.scss new file mode 100644 index 0000000..2ee95a7 --- /dev/null +++ b/packages/theme-chalk/src/radio-group.scss @@ -0,0 +1,9 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(radio-group) { + display: inline-block; + line-height: 1; + vertical-align: middle; + font-size: 0; +} diff --git a/packages/theme-chalk/src/radio.scss b/packages/theme-chalk/src/radio.scss new file mode 100644 index 0000000..4d8faf1 --- /dev/null +++ b/packages/theme-chalk/src/radio.scss @@ -0,0 +1,199 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import 'mixins/button'; +@import "common/var"; + +@include b(radio) { + color: $--radio-font-color; + font-weight: $--radio-font-weight; + line-height: 1; + position: relative; + cursor: pointer; + display: inline-block; + white-space: nowrap; + outline: none; + font-size: $--font-size-base; + margin-right: 30px; + @include utils-user-select(none); + + @include when(bordered) { + padding: $--radio-bordered-padding; + border-radius: $--border-radius-base; + border: $--border-base; + box-sizing: border-box; + height: $--radio-bordered-height; + + &.is-checked { + border-color: $--color-primary; + } + + &.is-disabled { + cursor: not-allowed; + border-color: $--border-color-lighter; + } + + & + .el-radio.is-bordered { + margin-left: 10px; + } + } + + @include m(medium) { + &.is-bordered { + padding: $--radio-bordered-medium-padding; + border-radius: $--button-medium-border-radius; + height: $--radio-bordered-medium-height; + .el-radio__label { + font-size: $--button-medium-font-size; + } + .el-radio__inner { + height: $--radio-bordered-medium-input-height; + width: $--radio-bordered-medium-input-width; + } + } + } + @include m(small) { + &.is-bordered { + padding: $--radio-bordered-small-padding; + border-radius: $--button-small-border-radius; + height: $--radio-bordered-small-height; + .el-radio__label { + font-size: $--button-small-font-size; + } + .el-radio__inner { + height: $--radio-bordered-small-input-height; + width: $--radio-bordered-small-input-width; + } + } + } + @include m(mini) { + &.is-bordered { + padding: $--radio-bordered-mini-padding; + border-radius: $--button-mini-border-radius; + height: $--radio-bordered-mini-height; + .el-radio__label { + font-size: $--button-mini-font-size; + } + .el-radio__inner { + height: $--radio-bordered-mini-input-height; + width: $--radio-bordered-mini-input-width; + } + } + } + + &:last-child { + margin-right: 0; + } + + @include e(input) { + white-space: nowrap; + cursor: pointer; + outline: none; + display: inline-block; + line-height: 1; + position: relative; + vertical-align: middle; + + @include when(disabled) { + .el-radio__inner { + background-color: $--radio-disabled-input-fill; + border-color: $--radio-disabled-input-border-color; + cursor: not-allowed; + + &::after { + cursor: not-allowed; + background-color: $--radio-disabled-icon-color; + } + + & + .el-radio__label { + cursor: not-allowed; + } + } + &.is-checked { + .el-radio__inner { + background-color: $--radio-disabled-checked-input-fill; + border-color: $--radio-disabled-checked-input-border-color; + + &::after { + background-color: $--radio-disabled-checked-icon-color; + } + } + } + & + span.el-radio__label { + color: $--color-text-placeholder; + cursor: not-allowed; + } + } + + @include when(checked) { + .el-radio__inner { + border-color: $--radio-checked-input-border-color; + background: $--radio-checked-icon-color; + + &::after { + transform: translate(-50%, -50%) scale(1); + } + } + + & + .el-radio__label { + color: $--radio-checked-font-color; + } + } + + @include when(focus) { + .el-radio__inner { + border-color: $--radio-input-border-color-hover; + } + } + } + @include e(inner) { + border: $--radio-input-border; + border-radius: $--radio-input-border-radius; + width: $--radio-input-width; + height: $--radio-input-height; + background-color: $--radio-input-background-color; + position: relative; + cursor: pointer; + display: inline-block; + box-sizing: border-box; + + &:hover { + border-color: $--radio-input-border-color-hover; + } + + &::after { + width: 4px; + height: 4px; + border-radius: $--radio-input-border-radius; + background-color: $--color-white; + content: ""; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%) scale(0); + transition: transform .15s ease-in; + } + } + + @include e(original) { + opacity: 0; + outline: none; + position: absolute; + z-index: -1; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0; + } + + &:focus:not(.is-focus):not(:active):not(.is-disabled) { /*获得焦点时 样式提醒*/ + .el-radio__inner { + box-shadow: 0 0 2px 2px $--radio-input-border-color-hover; + } + } + + @include e(label) { + font-size: $--radio-font-size; + padding-left: 10px; + } +} diff --git a/packages/theme-chalk/src/rate.scss b/packages/theme-chalk/src/rate.scss new file mode 100644 index 0000000..99d7d04 --- /dev/null +++ b/packages/theme-chalk/src/rate.scss @@ -0,0 +1,49 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(rate) { + height: $--rate-height; + line-height: 1; + + &:focus, &:active { + outline-width: 0; + } + + @include e(item) { + display: inline-block; + position: relative; + font-size: 0; + vertical-align: middle; + } + + @include e(icon) { + position: relative; + display: inline-block; + font-size: $--rate-icon-size; + margin-right: $--rate-icon-margin; + color: $--rate-icon-color; + transition: .3s; + &.hover { + transform: scale(1.15); + } + + .path2 { + position: absolute; + left: 0; + top: 0; + } + } + + @include e(decimal) { + position: absolute; + top: 0; + left: 0; + display: inline-block; + overflow: hidden; + } + + @include e(text) { + font-size: $--rate-font-size; + vertical-align: middle; + } +} diff --git a/packages/theme-chalk/src/reset.scss b/packages/theme-chalk/src/reset.scss new file mode 100644 index 0000000..a13e0de --- /dev/null +++ b/packages/theme-chalk/src/reset.scss @@ -0,0 +1,79 @@ +@import 'common/var'; + +body { + font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; + font-weight: 400; + font-size: $--font-size-base; + color: $--color-black; + -webkit-font-smoothing: antialiased; +} + +a { + color: $--color-primary; + text-decoration: none; + + &:hover, + &:focus { + color: mix($--color-white, $--color-primary, $--button-hover-tint-percent); + } + + &:active { + color: mix($--color-black, $--color-primary, $--button-active-shade-percent); + } +} + +h1, h2, h3, h4, h5, h6 { + color: $--color-text-regular; + font-weight: inherit; + + &:first-child { + margin-top: 0; + } + + &:last-child { + margin-bottom: 0; + } +} + +h1 { + font-size: #{$--font-size-base + 6px}; +} + +h2 { + font-size: #{$--font-size-base + 4px}; +} + +h3 { + font-size: #{$--font-size-base + 2px}; +} + +h4, h5, h6, p { + font-size: inherit; +} + +p { + line-height: 1.8; + + &:first-child { + margin-top: 0; + } + + &:last-child { + margin-bottom: 0; + } +} + +sup, sub { + font-size: #{$--font-size-base - 1px}; +} + +small { + font-size: #{$--font-size-base - 2px}; +} + +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eeeeee; +} diff --git a/packages/theme-chalk/src/row.scss b/packages/theme-chalk/src/row.scss new file mode 100644 index 0000000..cec45c8 --- /dev/null +++ b/packages/theme-chalk/src/row.scss @@ -0,0 +1,39 @@ +@import "common/var"; +@import "mixins/mixins"; +@import "mixins/utils"; + +@include b(row) { + position: relative; + box-sizing: border-box; + @include utils-clearfix; + + @include m(flex) { + display: flex; + &:before, + &:after { + display: none; + } + + @include when(justify-center) { + justify-content: center; + } + @include when(justify-end) { + justify-content: flex-end; + } + @include when(justify-space-between) { + justify-content: space-between; + } + @include when(justify-space-around) { + justify-content: space-around; + } + + @include when(align-middle) { + align-items: center; + } + @include when(align-bottom) { + align-items: flex-end; + } + } + +} + diff --git a/packages/theme-chalk/src/scrollbar.scss b/packages/theme-chalk/src/scrollbar.scss new file mode 100644 index 0000000..56e5f29 --- /dev/null +++ b/packages/theme-chalk/src/scrollbar.scss @@ -0,0 +1,72 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(scrollbar) { + overflow: hidden; + position: relative; + + &:hover, + &:active, + &:focus { + > .el-scrollbar__bar { + opacity: 1; + transition: opacity 340ms ease-out; + } + } + + @include e(wrap) { + overflow: scroll; + height: 100%; + + @include m(hidden-default) { + scrollbar-width: none; + &::-webkit-scrollbar { + width: 0; + height: 0; + } + } + } + + @include e(thumb) { + position: relative; + display: block; + width: 0; + height: 0; + cursor: pointer; + border-radius: inherit; + background-color: $--scrollbar-background-color; + transition: .3s background-color; + + &:hover { + background-color: $--scrollbar-hover-background-color; + } + } + + @include e(bar) { + position: absolute; + right: 2px; + bottom: 2px; + z-index: 1; + border-radius: 4px; + opacity: 0; + transition: opacity 120ms ease-out; + + @include when(vertical) { + width: 6px; + top: 2px; + + > div { + width: 100%; + } + } + + @include when(horizontal) { + height: 6px; + left: 2px; + + > div { + height: 100%; + } + } + } +} diff --git a/packages/theme-chalk/src/select-dropdown.scss b/packages/theme-chalk/src/select-dropdown.scss new file mode 100644 index 0000000..f9b3b4f --- /dev/null +++ b/packages/theme-chalk/src/select-dropdown.scss @@ -0,0 +1,59 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "./popper"; + +@include b(select-dropdown) { + position: absolute; + z-index: #{$--index-top + 1}; + border: $--select-dropdown-border; + border-radius: $--border-radius-base; + background-color: $--select-dropdown-background; + box-shadow: $--select-dropdown-shadow; + box-sizing: border-box; + margin: 5px 0; + + @include when(multiple) { + & .el-select-dropdown__item.selected { + color: $--select-option-selected-font-color; + background-color: $--select-dropdown-background; + + &.hover { + background-color: $--select-option-hover-background; + } + + &::after { + position: absolute; + right: 20px; + font-family: 'element-icons'; + content: "\e6da"; + font-size: 12px; + font-weight: bold; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + } + } + + .el-scrollbar.is-empty .el-select-dropdown__list{ + padding: 0; + } +} + +@include b(select-dropdown__empty) { + padding: $--select-dropdown-empty-padding; + margin: 0; + text-align: center; + color: $--select-dropdown-empty-color; + font-size: $--select-font-size; +} + +@include b(select-dropdown__wrap) { + max-height: $--select-dropdown-max-height; +} + +@include b(select-dropdown__list) { + list-style: none; + padding: $--select-dropdown-padding; + margin: 0; + box-sizing: border-box; +} diff --git a/packages/theme-chalk/src/select.scss b/packages/theme-chalk/src/select.scss new file mode 100644 index 0000000..d5f6a30 --- /dev/null +++ b/packages/theme-chalk/src/select.scss @@ -0,0 +1,148 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "common/var"; +@import "select-dropdown"; +@import "input"; +@import "tag"; +@import "option"; +@import "option-group"; +@import "scrollbar"; + +@include b(select) { + display: inline-block; + position: relative; + + .el-select__tags + >span { + display: contents; + } + + &:hover { + .el-input__inner { + border-color: $--select-border-color-hover; + } + } + + .el-input__inner { + cursor: pointer; + padding-right: 35px; + + &:focus { + border-color: $--select-input-focus-border-color; + } + } + + .el-input { + & .el-select__caret { + color: $--select-input-color; + font-size: $--select-input-font-size; + transition: transform .3s; + transform: rotateZ(180deg); + cursor: pointer; + + @include when(reverse) { + transform: rotateZ(0deg); + } + + @include when(show-close) { + font-size: $--select-font-size; + text-align: center; + transform: rotateZ(180deg); + border-radius: $--border-radius-circle; + color: $--select-input-color; + transition: $--color-transition-base; + + &:hover { + color: $--select-close-hover-color; + } + } + } + + &.is-disabled { + & .el-input__inner { + cursor: not-allowed; + + &:hover { + border-color: $--select-disabled-border; + } + } + } + + &.is-focus .el-input__inner { + border-color: $--select-input-focus-border-color; + } + } + + > .el-input { + display: block; + } + + @include e(input) { + border: none; + outline: none; + padding: 0; + margin-left: 15px; + color: $--select-multiple-input-color; + font-size: $--select-font-size; + appearance: none; + height: 28px; + background-color: transparent; + @include when(mini) { + height: 14px; + } + } + + @include e(close) { + cursor: pointer; + position: absolute; + top: 8px; + z-index: $--index-top; + right: 25px; + color: $--select-input-color; + line-height: 18px; + font-size: $--select-input-font-size; + + &:hover { + color: $--select-close-hover-color; + } + } + + @include e(tags) { + position: absolute; + line-height: normal; + white-space: normal; + z-index: $--index-normal; + top: 50%; + transform: translateY(-50%); + display: flex; + align-items: center; + flex-wrap: wrap; + } + + .el-tag__close { + margin-top: -2px; + } + + .el-tag { + box-sizing: border-box; + border-color: transparent; + margin: 2px 0 2px 6px; + background-color: #f0f2f5; + + &__close.el-icon-close { + background-color: $--color-text-placeholder; + right: -7px; + top: 0; + color: $--color-white; + + &:hover { + background-color: $--color-text-secondary; + } + + &::before { + display: block; + transform: translate(0, .5px); + } + } + } +} diff --git a/packages/theme-chalk/src/slider.scss b/packages/theme-chalk/src/slider.scss new file mode 100644 index 0000000..666c52d --- /dev/null +++ b/packages/theme-chalk/src/slider.scss @@ -0,0 +1,250 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "input-number"; +@import "tooltip"; +@import "common/var"; + +@include b(slider) { + + @include utils-clearfix; + + @include e(runway) { + width: 100%; + height: $--slider-height; + margin: $--slider-margin; + background-color: $--slider-runway-background-color; + border-radius: $--slider-border-radius; + position: relative; + cursor: pointer; + vertical-align: middle; + + &.show-input { + margin-right: 160px; + width: auto; + } + + &.disabled { + cursor: default; + + .el-slider__bar { + background-color: $--slider-disable-color; + } + + .el-slider__button { + border-color: $--slider-disable-color; + } + + .el-slider__button-wrapper { + &:hover, + &.hover { + cursor: not-allowed; + } + + &.dragging { + cursor: not-allowed; + } + } + + .el-slider__button { + &:hover, + &.hover, + &.dragging { + transform: scale(1); + } + + &:hover, + &.hover { + cursor: not-allowed; + } + + &.dragging { + cursor: not-allowed; + } + } + } + } + + @include e(input) { + float: right; + margin-top: 3px; + width: 130px; + + &.el-input-number--mini { + margin-top: 5px; + } + + &.el-input-number--medium { + margin-top: 0; + } + + &.el-input-number--large { + margin-top: -2px; + } + } + + @include e(bar) { + height: $--slider-height; + background-color: $--slider-main-background-color; + border-top-left-radius: $--slider-border-radius; + border-bottom-left-radius: $--slider-border-radius; + position: absolute; + } + + @include e(button-wrapper) { + height: $--slider-button-wrapper-size; + width: $--slider-button-wrapper-size; + position: absolute; + z-index: 1001; + top: $--slider-button-wrapper-offset; + transform: translateX(-50%); + background-color: transparent; + text-align: center; + user-select: none; + line-height: normal; + @include utils-vertical-center; + + .el-tooltip { + vertical-align: middle; + display: inline-block; + } + + &:hover, + &.hover { + cursor: grab; + } + + &.dragging { + cursor: grabbing; + } + } + + @include e(button) { + width: $--slider-button-size; + height: $--slider-button-size; + border: solid 2px $--slider-main-background-color; + background-color: $--color-white; + border-radius: 50%; + transition: .2s; + user-select: none; + + &:hover, + &.hover, + &.dragging { + transform: scale(1.2); + } + + &:hover, + &.hover { + cursor: grab; + } + + &.dragging { + cursor: grabbing; + } + } + + @include e(stop) { + position: absolute; + height: $--slider-height; + width: $--slider-height; + border-radius: $--border-radius-circle; + background-color: $--slider-stop-background-color; + transform: translateX(-50%); + } + + @include e(marks) { + top: 0; + left: 12px; + width: 18px; + height: 100%; + + @include e(marks-text) { + position: absolute; + transform: translateX(-50%); + font-size: 14px; + color: $--color-info; + margin-top: 15px; + } + } + + @include when(vertical) { + position: relative; + .el-slider__runway { + width: $--slider-height; + height: 100%; + margin: 0 16px; + } + .el-slider__bar { + width: $--slider-height; + height: auto; + border-radius: 0 0 3px 3px; + } + .el-slider__button-wrapper { + top: auto; + left: $--slider-button-wrapper-offset; + transform: translateY(50%); + } + .el-slider__stop { + transform: translateY(50%); + } + &.el-slider--with-input { + padding-bottom: #{$--input-medium-height + 22px}; + .el-slider__input { + overflow: visible; + float: none; + position: absolute; + bottom: 22px; + width: 36px; + margin-top: 15px; + .el-input__inner { + text-align: center; + padding-left: 5px; + padding-right: 5px; + } + .el-input-number__decrease, + .el-input-number__increase + { + top: $--input-small-height; + margin-top: -1px; + border: $--input-border; + line-height: 20px; + box-sizing: border-box; + transition: $--border-transition-base; + } + .el-input-number__decrease { + width: 18px; + right: 18px; + border-bottom-left-radius: $--input-border-radius; + } + .el-input-number__increase { + width: 19px; + border-bottom-right-radius: $--input-border-radius; + & ~ .el-input .el-input__inner { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + } + &:hover { + .el-input-number__decrease, + .el-input-number__increase + { + border-color: $--input-hover-border; + } + } + &:active { + .el-input-number__decrease, + .el-input-number__increase + { + border-color: $--input-focus-border; + } + } + } + } + + @include e(marks-text) { + margin-top: 0; + left: 15px; + transform: translateY(50%); + } + } +} diff --git a/packages/theme-chalk/src/spinner.scss b/packages/theme-chalk/src/spinner.scss new file mode 100644 index 0000000..b76ffc0 --- /dev/null +++ b/packages/theme-chalk/src/spinner.scss @@ -0,0 +1,44 @@ +@import "mixins/mixins"; + +@include b(time-spinner) { + width: 100%; + white-space: nowrap; +} + +@include b(spinner) { + display: inline-block; + vertical-align: middle; +} +@include b(spinner-inner) { + animation: rotate 2s linear infinite; + width: 50px; + height: 50px; + + & .path { + stroke: #ececec; + stroke-linecap: round; + animation: dash 1.5s ease-in-out infinite; + } + +} + +@keyframes rotate { + 100% { + transform: rotate(360deg); + } +} + +@keyframes dash { + 0% { + stroke-dasharray: 1, 150; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -35; + } + 100% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -124; + } +} diff --git a/packages/theme-chalk/src/step.scss b/packages/theme-chalk/src/step.scss new file mode 100644 index 0000000..37a831c --- /dev/null +++ b/packages/theme-chalk/src/step.scss @@ -0,0 +1,317 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(step) { + position: relative; + flex-shrink: 1; + + @include pseudo(last-of-type) { + @include e(line) { + display: none; + } + + // 只有未设置 space 的情况下才自适应宽度 + @include when(flex) { + flex-basis: auto !important; + flex-shrink: 0; + flex-grow: 0; + } + + @include e((main, description)) { + padding-right: 0; + } + } + + @include e(head) { + position: relative; + width: 100%; + + @include when(process) { + color: $--color-text-primary; + border-color: $--color-text-primary; + } + + @include when(wait) { + color: $--color-text-placeholder; + border-color: $--color-text-placeholder; + } + + @include when(success) { + color: $--color-success; + border-color: $--color-success; + } + + @include when(error) { + color: $--color-danger; + border-color: $--color-danger; + } + + @include when(finish) { + color: $--color-primary; + border-color: $--color-primary; + } + } + + @include e(icon) { + position: relative; + z-index: 1; + display: inline-flex; + justify-content: center; + align-items: center; + width: 24px; + height: 24px; + font-size: 14px; + box-sizing: border-box; + background: $--color-white; + transition: .15s ease-out; + + @include when(text) { + border-radius: 50%; + border: 2px solid; + border-color: inherit; + } + + @include when(icon) { + width: 40px; + } + } + + @include e(icon-inner) { + display: inline-block; + user-select: none; + text-align: center; + font-weight: bold; + line-height: 1; + color: inherit; + + &[class*=el-icon]:not(.is-status) { + font-size: 25px; + font-weight: normal; + } + + // 组件自身表示状态的图标 + @include when(status) { + transform: translateY(1px); + } + } + + @include e(line) { + position: absolute; + border-color: inherit; + background-color: $--color-text-placeholder; + } + + @include e(line-inner) { + display: block; + border-width: 1px; + border-style: solid; + border-color: inherit; + transition: .15s ease-out; + box-sizing: border-box; + width: 0; + height: 0; + } + + @include e(main) { + white-space: normal; + text-align: left; + } + + @include e(title) { + font-size: 16px; + line-height: 38px; + + @include when(process) { + font-weight: bold; + color: $--color-text-primary; + } + + @include when(wait) { + color: $--color-text-placeholder; + } + + @include when(success) { + color: $--color-success; + } + + @include when(error) { + color: $--color-danger; + } + + @include when(finish) { + color: $--color-primary; + } + } + + @include e(description) { + padding-right: 10%; + margin-top: -5px; + font-size: 12px; + line-height: 20px; + font-weight: normal; + + @include when(process) { + color: $--color-text-primary; + } + + @include when(wait) { + color: $--color-text-placeholder; + } + + @include when(success) { + color: $--color-success; + } + + @include when(error) { + color: $--color-danger; + } + + @include when(finish) { + color: $--color-primary; + } + } + + @include when(horizontal) { + display: inline-block; + + @include e(line) { + height: 2px; + top: 11px; + left: 0; + right: 0; + } + } + + @include when(vertical) { + display: flex; + + @include e(head) { + flex-grow: 0; + width: 24px; + } + + @include e(main) { + padding-left: 10px; + flex-grow: 1; + } + + @include e(title) { + line-height: 24px; + padding-bottom: 8px; + } + + @include e(line) { + width: 2px; + top: 0; + bottom: 0; + left: 11px; + } + + @include e(icon) { + @include when(icon) { + width: 24px; + } + } + } + + @include when(center) { + + @include e(head) { + text-align: center; + } + + @include e(main) { + text-align: center; + } + + @include e(description) { + padding-left: 20%; + padding-right: 20%; + } + + @include e(line) { + left: 50%; + right: -50%; + } + } + + @include when(simple) { + display: flex; + align-items: center; + + @include e(head) { + width: auto; + font-size: 0; + padding-right: 10px; + } + + @include e(icon) { + background: transparent; + width: 16px; + height: 16px; + font-size: 12px; + } + + @include e(icon-inner) { + &[class*=el-icon]:not(.is-status) { + font-size: 18px; + } + + &.is-status { + transform: scale(.8) translateY(1px); + } + } + + @include e(main) { + position: relative; + display: flex; + align-items: stretch; + flex-grow: 1; + } + + @include e(title) { + font-size: 16px; + line-height: 20px; + } + + @include pseudo('not(:last-of-type)') { + @include e(title) { + max-width: 50%; + word-break: break-all; + } + } + + @include e(arrow) { + flex-grow: 1; + display: flex; + align-items: center; + justify-content: center; + + &::before, + &::after { + content: ''; + display: inline-block; + position: absolute; + height: 15px; + width: 1px; + background: $--color-text-placeholder; + } + + &::before { + transform: rotate(-45deg) translateY(-4px); + transform-origin: 0 0; + } + + &::after { + transform: rotate(45deg) translateY(4px); + transform-origin: 100% 100%; + } + } + + @include pseudo(last-of-type) { + @include e(arrow) { + display: none; + } + } + } +} diff --git a/packages/theme-chalk/src/steps.scss b/packages/theme-chalk/src/steps.scss new file mode 100644 index 0000000..aa3464e --- /dev/null +++ b/packages/theme-chalk/src/steps.scss @@ -0,0 +1,20 @@ +@import "mixins/mixins"; + +@include b(steps) { + display: flex; + + @include m(simple) { + padding: 13px 8%; + border-radius: 4px; + background: $--background-color-base; + } + + @include m(horizontal) { + white-space: nowrap; + } + + @include m(vertical) { + height: 100%; + flex-flow: column; + } +} diff --git a/packages/theme-chalk/src/submenu.scss b/packages/theme-chalk/src/submenu.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/switch.scss b/packages/theme-chalk/src/switch.scss new file mode 100644 index 0000000..c38eede --- /dev/null +++ b/packages/theme-chalk/src/switch.scss @@ -0,0 +1,116 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(switch) { + display: inline-flex; + align-items: center; + position: relative; + font-size: $--switch-font-size; + line-height: $--switch-height; + height: $--switch-height; + vertical-align: middle; + @include when(disabled) { + & .el-switch__core, + & .el-switch__label { + cursor: not-allowed; + } + } + + @include e(label) { + transition: .2s; + height: $--switch-height; + display: inline-block; + font-size: $--switch-font-size; + font-weight: 500; + cursor: pointer; + vertical-align: middle; + color: $--color-text-primary; + + @include when(active) { + color: $--color-primary; + } + + @include m(left) { + margin-right: 10px; + } + @include m(right) { + margin-left: 10px; + } + & * { + line-height: 1; + font-size: $--switch-font-size; + display: inline-block; + } + } + + @include e(input) { + position: absolute; + width: 0; + height: 0; + opacity: 0; + margin: 0; + } + + @include e(core) { + margin: 0; + display: inline-block; + position: relative; + width: $--switch-width; + height: $--switch-height; + border: 1px solid $--switch-off-color; + outline: none; + border-radius: $--switch-core-border-radius; + box-sizing: border-box; + background: $--switch-off-color; + cursor: pointer; + transition: border-color .3s, background-color .3s; + vertical-align: middle; + + &:after { + content: ""; + position: absolute; + top: 1px; + left: 1px; + border-radius: $--border-radius-circle; + transition: all .3s; + width: $--switch-button-size; + height: $--switch-button-size; + background-color: $--color-white; + } + } + + @include when(checked) { + .el-switch__core { + border-color: $--switch-on-color; + background-color: $--switch-on-color; + &::after { + left: 100%; + margin-left: -$--switch-button-size - 1px; + } + } + } + + @include when(disabled) { + opacity: 0.6; + } + + @include m(wide) { + .el-switch__label { + &.el-switch__label--left { + span { + left: 10px; + } + } + &.el-switch__label--right { + span { + right: 10px; + } + } + } + } + + & .label-fade-enter, + & .label-fade-leave-active { + opacity: 0; + } +} diff --git a/packages/theme-chalk/src/tab-pane.scss b/packages/theme-chalk/src/tab-pane.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/theme-chalk/src/table-column.scss b/packages/theme-chalk/src/table-column.scss new file mode 100644 index 0000000..6fd54e7 --- /dev/null +++ b/packages/theme-chalk/src/table-column.scss @@ -0,0 +1,97 @@ +@import "mixins/mixins"; +@import "checkbox"; +@import "tag"; +@import "common/var"; + +@include b(table-column) { + @include m(selection) { + .cell { + padding-left: 14px; + padding-right: 14px; + } + } +} + +@include b(table-filter) { + border: solid 1px $--border-color-lighter; + border-radius: 2px; + background-color: $--color-white; + box-shadow: $--dropdown-menu-box-shadow; + box-sizing: border-box; + margin: 2px 0; + + /** used for dropdown mode */ + @include e(list) { + padding: 5px 0; + margin: 0; + list-style: none; + min-width: 100px; + } + + @include e(list-item) { + line-height: 36px; + padding: 0 10px; + cursor: pointer; + font-size: $--font-size-base; + + &:hover { + background-color: $--dropdown-menuItem-hover-fill; + color: $--dropdown-menuItem-hover-color; + } + + @include when(active) { + background-color: $--color-primary; + color: $--color-white; + } + } + + @include e(content) { + min-width: 100px; + } + + @include e(bottom) { + border-top: 1px solid $--border-color-lighter; + padding: 8px; + + button { + background: transparent; + border: none; + color: $--color-text-regular; + cursor: pointer; + font-size: $--font-size-small; + padding: 0 3px; + + &:hover { + color: $--color-primary; + } + + &:focus { + outline: none; + } + + &.is-disabled { + color: $--disabled-color-base; + cursor: not-allowed; + } + } + } + + @include e(wrap) { + max-height: 280px; + } + + @include e(checkbox-group) { + padding: 10px; + + label.el-checkbox { + display: block; + margin-right: 5px; + margin-bottom: 8px; + margin-left: 5px; + } + + .el-checkbox:last-child { + margin-bottom: 0; + } + } +} \ No newline at end of file diff --git a/packages/theme-chalk/src/table.scss b/packages/theme-chalk/src/table.scss new file mode 100644 index 0000000..319c5d1 --- /dev/null +++ b/packages/theme-chalk/src/table.scss @@ -0,0 +1,563 @@ +@import "mixins/mixins"; +@import "checkbox"; +@import "tag"; +@import "tooltip"; +@import "common/var"; + +@include b(table) { + position: relative; + overflow: hidden; + box-sizing: border-box; + flex: 1; + width: 100%; + max-width: 100%; + background-color: $--color-white; + font-size: 14px; + color: $--table-font-color; + + // 数据为空 + @include e(empty-block) { + min-height: 60px; + text-align: center; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + @include e(empty-text) { + // min-height doesn't work in IE10 and IE11 https://github.com/philipwalton/flexbugs#3-min-height-on-a-flex-container-wont-apply-to-its-flex-items + // set empty text line height up to contrainer min-height as workaround. + line-height: 60px; + width: 50%; + color: $--color-text-secondary; + } + + // 展开行 + @include e(expand-column) { + .cell { + padding: 0; + text-align: center; + } + } + + @include e(expand-icon) { + position: relative; + cursor: pointer; + color: #666; + font-size: 12px; + transition: transform 0.2s ease-in-out; + height: 20px; + + @include m(expanded) { + transform: rotate(90deg); + } + + > .el-icon { + position: absolute; + left: 50%; + top: 50%; + margin-left: -5px; + margin-top: -5px; + } + } + + @include e(expanded-cell) { + background-color: $--color-white; + + // 纯属为了增加权重 + &[class*=cell] { + padding: 20px 50px; + } + + &:hover { + background-color: transparent !important; + } + } + + @include e(placeholder) { + display: inline-block; + width: 20px; + } + + @include e(append-wrapper) { + // 避免外边距重合 https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing + overflow: hidden; + } + + @include m(fit) { + border-right: 0; + border-bottom: 0; + + th.gutter, td.gutter { + border-right-width: 1px; + } + } + + @include m(scrollable-x) { + .el-table__body-wrapper { + overflow-x: auto; + } + } + + @include m(scrollable-y) { + .el-table__body-wrapper { + overflow-y: auto; + } + } + + thead { + color: $--table-header-font-color; + font-weight: 500; + + &.is-group { + th { + background: $--background-color-base; + } + } + } + + th, td { + padding: 12px 0; + min-width: 0; + box-sizing: border-box; + text-overflow: ellipsis; + vertical-align: middle; + position: relative; + text-align: left; + + @include when(center) { + text-align: center; + } + + @include when(right) { + text-align: right; + } + + &.gutter { + width: 15px; + border-right-width: 0; + border-bottom-width: 0; + padding: 0; + } + + &.is-hidden { + > * { + visibility: hidden; + } + } + } + + @include m(medium) { + th, td { + padding: 10px 0; + } + } + + @include m(small) { + font-size: 12px; + th, td { + padding: 8px 0; + } + } + + @include m(mini) { + font-size: 12px; + th, td { + padding: 6px 0; + } + } + + tr { + background-color: $--color-white; + + input[type="checkbox"] { + margin: 0; + } + } + + th.is-leaf, td { + border-bottom: $--table-border; + } + + th.is-sortable { + cursor: pointer; + } + + th { + overflow: hidden; + user-select: none; + background-color: $--table-header-background-color; + + > .cell { + display: inline-block; + box-sizing: border-box; + position: relative; + vertical-align: middle; + padding-left: 10px; + padding-right: 10px; + width: 100%; + + &.highlight { + color: $--color-primary; + } + } + + &.required > div::before { + display: inline-block; + content: ""; + width: 8px; + height: 8px; + border-radius: 50%; + background: #ff4d51; + margin-right: 5px; + vertical-align: middle; + } + } + + td { + div { + box-sizing: border-box; + } + + &.gutter { + width: 0; + } + } + + .cell { + box-sizing: border-box; + overflow: hidden; + text-overflow: ellipsis; + white-space: normal; + word-break: break-all; + line-height: 23px; + padding-left: 10px; + padding-right: 10px; + + &.el-tooltip { + white-space: nowrap; + min-width: 50px; + } + } + + // 拥有多级表头 + @include m((group, border)) { + border: $--table-border; + + @include share-rule(border-pseudo) { + content: ''; + position: absolute; + background-color: $--table-border-color; + z-index: 1; + } + + // 表格右部伪 border + &::after { + @include extend-rule(border-pseudo); + top: 0; + right: 0; + width: 1px; + height: 100%; + } + } + + // 表格底部伪 border,总是有的 + &::before { + @include extend-rule(border-pseudo); + left: 0; + bottom: 0; + width: 100%; + height: 1px; + } + + // table--border + @include m(border) { + border-right: none; + border-bottom: none; + + &.el-loading-parent--relative { + border-color: transparent; + } + + th, td { + border-right: $--table-border; + + &:first-child .cell { + padding-left: 10px; + } + } + + th.gutter:last-of-type { + border-bottom: $--table-border; + border-bottom-width: 1px; + } + + & th { + border-bottom: $--table-border; + } + } + + @include m(hidden) { + visibility: hidden; + } + + @include e((fixed, fixed-right)) { + position: absolute; + top: 0; + left: 0; + overflow-x: hidden; + overflow-y: hidden; + box-shadow: $--table-fixed-box-shadow; + + &::before { + content: ''; + position: absolute; + left: 0; + bottom: 0; + width: 100%; + height: 1px; + background-color: $--border-color-lighter; + z-index: 4; + } + } + + @include e(fixed-right-patch) { + position: absolute; + top: -1px; + right: 0; + background-color: $--color-white; + border-bottom: $--table-border; + } + + @include e(fixed-right) { + top: 0; + left: auto; + right: 0; + + .el-table__fixed-header-wrapper, + .el-table__fixed-body-wrapper, + .el-table__fixed-footer-wrapper { + left: auto; + right: 0; + } + } + + @include e(fixed-header-wrapper) { + position: absolute; + left: 0; + top: 0; + z-index: 3; + } + + @include e(fixed-footer-wrapper) { + position: absolute; + left: 0; + bottom: 0; + z-index: 3; + + & tbody td { + border-top: $--table-border; + background-color: $--table-row-hover-background-color; + color: $--table-font-color; + } + } + + @include e(fixed-body-wrapper) { + position: absolute; + left: 0; + top: 37px; + overflow: hidden; + z-index: 3; + } + + @include e((header-wrapper, body-wrapper, footer-wrapper)) { + width: 100%; + } + + @include e(footer-wrapper) { + margin-top: -1px; + td { + border-top: $--table-border; + } + } + + @include e((header, body, footer)) { + table-layout: fixed; + border-collapse: separate; + } + + @include e((header-wrapper, footer-wrapper)) { + overflow: hidden; + + & tbody td { + background-color: $--table-row-hover-background-color; + color: $--table-font-color; + } + } + + @include e(body-wrapper) { + overflow: hidden; + position: relative; + + @include when(scrolling-none) { + ~ .el-table__fixed, + ~ .el-table__fixed-right { + box-shadow: none; + } + } + + @include when(scrolling-left) { + ~ .el-table__fixed { + box-shadow: none; + } + } + + @include when(scrolling-right) { + ~ .el-table__fixed-right { + box-shadow: none; + } + } + + .el-table--border { + @include when(scrolling-right) { + ~ .el-table__fixed-right { + border-left: $--table-border; + } + } + + @include when(scrolling-left) { + ~ .el-table__fixed { + border-right: $--table-border; + } + } + } + } + + .caret-wrapper { + display: inline-flex; + flex-direction: column; + align-items: center; + height: 34px; + width: 24px; + vertical-align: middle; + cursor: pointer; + overflow: initial; + position: relative; + } + + .sort-caret { + width: 0; + height: 0; + border: solid 5px transparent; + position: absolute; + left: 7px; + + &.ascending { + border-bottom-color: $--color-text-placeholder; + top: 5px; + } + + &.descending { + border-top-color: $--color-text-placeholder; + bottom: 7px; + } + } + + .ascending .sort-caret.ascending { + border-bottom-color: $--color-primary; + } + + .descending .sort-caret.descending { + border-top-color: $--color-primary; + } + + .hidden-columns { + visibility: hidden; + position: absolute; + z-index: -1; + } + + @include m(striped) { + & .el-table__body { + & tr.el-table__row--striped { + td { + background: #FAFAFA; + } + + &.current-row td { + background-color: $--table-current-row-background-color; + } + } + } + } + + @include e(body) { + tr.hover-row { + &, &.el-table__row--striped { + &, &.current-row { + > td { + background-color: $--table-row-hover-background-color; + } + } + } + } + + tr.current-row > td { + background-color: $--table-current-row-background-color; + } + } + + @include e(column-resize-proxy) { + position: absolute; + left: 200px; + top: 0; + bottom: 0; + width: 0; + border-left: $--table-border; + z-index: 10; + } + + @include e(column-filter-trigger) { + display: inline-block; + line-height: 34px; + cursor: pointer; + + & i { + color: $--color-info; + font-size: 12px; + transform: scale(.75); + } + } + + @include m(enable-row-transition) { + .el-table__body td { + transition: background-color .25s ease; + } + } + + @include m(enable-row-hover) { + .el-table__body tr:hover > td { + background-color: $--table-row-hover-background-color; + } + } + + @include m(fluid-height) { + .el-table__fixed, + .el-table__fixed-right { + bottom: 0; + overflow: hidden; + } + } + + [class*=el-table__row--level] { + .el-table__expand-icon { + display: inline-block; + width: 20px; + line-height: 20px; + height: 20px; + text-align: center; + margin-right: 3px; + } + } +} diff --git a/packages/theme-chalk/src/tabs.scss b/packages/theme-chalk/src/tabs.scss new file mode 100644 index 0000000..7385c2f --- /dev/null +++ b/packages/theme-chalk/src/tabs.scss @@ -0,0 +1,602 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(tabs) { + @include e(header) { + padding: 0; + position: relative; + margin: 0 0 15px; + } + @include e(active-bar) { + position: absolute; + bottom: 0; + left: 0; + height: 2px; + background-color: $--color-primary; + z-index: 1; + transition: transform .3s cubic-bezier(.645,.045,.355,1); + list-style: none; + } + @include e(new-tab) { + float: right; + border: 1px solid #d3dce6; + height: 18px; + width: 18px; + line-height: 18px; + margin: 12px 0 9px 10px; + border-radius: 3px; + text-align: center; + font-size: 12px; + color: #d3dce6; + cursor: pointer; + transition: all .15s; + + .el-icon-plus { + transform: scale(0.8, 0.8); + } + + &:hover { + color: $--color-primary; + } + } + @include e(nav-wrap) { + overflow: hidden; + margin-bottom: -1px; + position: relative; + + &::after { + content: ""; + position: absolute; + left: 0; + bottom: 0; + width: 100%; + height: 2px; + background-color: $--border-color-light; + z-index: $--index-normal; + } + + @include when(scrollable) { + padding: 0 20px; + box-sizing: border-box; + } + } + @include e(nav-scroll) { + overflow: hidden; + } + @include e((nav-next, nav-prev)) { + position: absolute; + cursor: pointer; + line-height: 44px; + font-size: 12px; + color: $--color-text-secondary; + } + @include e(nav-next) { + right: 0; + } + @include e(nav-prev) { + left: 0; + } + @include e(nav) { + white-space: nowrap; + position: relative; + transition: transform .3s; + float: left; + z-index: #{$--index-normal + 1}; + + @include when(stretch) { + min-width: 100%; + display: flex; + & > * { + flex: 1; + text-align: center; + } + } + } + @include e(item) { + padding: 0 20px; + height: 40px; + box-sizing: border-box; + line-height: 40px; + display: inline-block; + list-style: none; + font-size: 14px; + font-weight: 500; + color: $--color-text-primary; + position: relative; + + &:focus, &:focus:active { + outline: none; + } + + &:focus.is-active.is-focus:not(:active) { + box-shadow: 0 0 2px 2px $--color-primary inset; + border-radius: 3px; + } + + & .el-icon-close { + border-radius: 50%; + text-align: center; + transition: all .3s cubic-bezier(.645,.045,.355,1); + margin-left: 5px; + &:before { + transform: scale(.9); + display: inline-block; + } + + &:hover { + background-color: $--color-text-placeholder; + color: $--color-white; + } + } + + @include when(active) { + color: $--color-primary; + } + + &:hover { + color: $--color-primary; + cursor: pointer; + } + + @include when(disabled) { + color: $--disabled-color-base; + cursor: default; + } + } + @include e(content) { + overflow: hidden; + position: relative; + } + @include m(card) { + > .el-tabs__header { + border-bottom: 1px solid $--border-color-light; + } + > .el-tabs__header .el-tabs__nav-wrap::after { + content: none; + } + > .el-tabs__header .el-tabs__nav { + border: 1px solid $--border-color-light; + border-bottom: none; + border-radius: 4px 4px 0 0; + box-sizing: border-box; + } + > .el-tabs__header .el-tabs__active-bar { + display: none; + } + > .el-tabs__header .el-tabs__item .el-icon-close { + position: relative; + font-size: 12px; + width: 0; + height: 14px; + vertical-align: middle; + line-height: 15px; + overflow: hidden; + top: -1px; + right: -2px; + transform-origin: 100% 50%; + } + > .el-tabs__header .el-tabs__item { + border-bottom: 1px solid transparent; + border-left: 1px solid $--border-color-light; + transition: color .3s cubic-bezier(.645,.045,.355,1), padding .3s cubic-bezier(.645,.045,.355,1); + &:first-child { + border-left: none; + } + &.is-closable { + &:hover { + padding-left: 13px; + padding-right: 13px; + + & .el-icon-close { + width: 14px; + } + } + } + &.is-active { + border-bottom-color: $--color-white; + + &.is-closable { + padding-left: 20px; + padding-right: 20px; + + .el-icon-close { + width: 14px; + } + } + } + } + } + @include m(border-card) { + background: $--color-white; + border: 1px solid $--border-color-base; + box-shadow: 0 2px 4px 0 rgba(0,0,0,0.12), 0 0 6px 0 rgba(0,0,0,0.04); + + > .el-tabs__content { + padding: 15px; + } + > .el-tabs__header { + background-color: $--background-color-base; + border-bottom: 1px solid $--border-color-light; + margin: 0; + } + > .el-tabs__header .el-tabs__nav-wrap::after { + content: none; + } + > .el-tabs__header .el-tabs__item { + transition: all .3s cubic-bezier(.645,.045,.355,1); + border: 1px solid transparent; + margin-top: -1px; + color: $--color-text-secondary; + + &:first-child { + margin-left: -1px; + } + + & + .el-tabs__item { + margin-left: -1px; + } + + &.is-active { + color: $--color-primary; + background-color: $--color-white; + border-right-color: $--border-color-base; + border-left-color: $--border-color-base; + } + &:not(.is-disabled):hover { + color: $--color-primary; + } + &.is-disabled { + color: $--disabled-color-base; + } + } + + > .el-tabs__header .is-scrollable .el-tabs__item:first-child { + margin-left: 0; + } + } + @include m((top, bottom)) { + .el-tabs__item.is-top:nth-child(2), + .el-tabs__item.is-bottom:nth-child(2) { + padding-left: 0; + } + .el-tabs__item.is-top:last-child, + .el-tabs__item.is-bottom:last-child { + padding-right: 0; + } + + &.el-tabs--border-card, &.el-tabs--card, + .el-tabs--left, .el-tabs--right { + > .el-tabs__header { + .el-tabs__item:nth-child(2) { + padding-left: 20px; + } + .el-tabs__item:last-child { + padding-right: 20px; + } + } + } + } + @include m(bottom) { + .el-tabs__header.is-bottom { + margin-bottom: 0; + margin-top: 10px; + } + &.el-tabs--border-card { + .el-tabs__header.is-bottom { + border-bottom: 0; + border-top: 1px solid $--border-color-base; + } + .el-tabs__nav-wrap.is-bottom { + margin-top: -1px; + margin-bottom: 0; + } + .el-tabs__item.is-bottom:not(.is-active) { + border: 1px solid transparent; + } + .el-tabs__item.is-bottom { + margin: 0 -1px -1px -1px; + } + } + } + @include m((left, right)) { + overflow: hidden; + + .el-tabs__header.is-left, + .el-tabs__header.is-right, + .el-tabs__nav-wrap.is-left, + .el-tabs__nav-wrap.is-right, + .el-tabs__nav-scroll { + height: 100%; + } + + .el-tabs__active-bar.is-left, + .el-tabs__active-bar.is-right { + top: 0; + bottom: auto; + width: 2px; + height: auto; + } + + .el-tabs__nav-wrap.is-left, + .el-tabs__nav-wrap.is-right { + margin-bottom: 0; + + > .el-tabs__nav-prev, + > .el-tabs__nav-next { + height: 30px; + line-height: 30px; + width: 100%; + text-align: center; + cursor: pointer; + + i { + transform: rotateZ(90deg); + } + } + > .el-tabs__nav-prev { + left: auto; + top: 0; + } + > .el-tabs__nav-next { + right: auto; + bottom: 0; + } + + &.is-scrollable { + padding: 30px 0; + } + + &::after { + height: 100%; + width: 2px; + bottom: auto; + top: 0; + } + } + + .el-tabs__nav.is-left, + .el-tabs__nav.is-right { + float: none; + } + .el-tabs__item.is-left, + .el-tabs__item.is-right { + display: block; + } + } + @include m(left) { + .el-tabs__header.is-left { + float: left; + margin-bottom: 0; + margin-right: 10px; + } + .el-tabs__nav-wrap.is-left { + margin-right: -1px; + &::after { + left: auto; + right: 0; + } + } + .el-tabs__active-bar.is-left { + right: 0; + left: auto; + } + .el-tabs__item.is-left { + text-align: right; + } + + &.el-tabs--card { + .el-tabs__active-bar.is-left { + display: none; + } + .el-tabs__item.is-left { + border-left: none; + border-right: 1px solid $--border-color-light; + border-bottom: none; + border-top: 1px solid $--border-color-light; + text-align: left; + } + .el-tabs__item.is-left:first-child { + border-right: 1px solid $--border-color-light; + border-top: none; + } + .el-tabs__item.is-left.is-active { + border: 1px solid $--border-color-light; + border-right-color: #fff; + border-left: none; + border-bottom: none; + + &:first-child { + border-top: none; + } + &:last-child { + border-bottom: none; + } + } + + .el-tabs__nav { + border-radius: 4px 0 0 4px; + border-bottom: 1px solid $--border-color-light; + border-right: none; + } + + .el-tabs__new-tab { + float: none; + } + } + + &.el-tabs--border-card { + .el-tabs__header.is-left { + border-right: 1px solid #dfe4ed; + } + .el-tabs__item.is-left { + border: 1px solid transparent; + margin: -1px 0 -1px -1px; + + &.is-active { + border-color: transparent; + border-top-color: rgb(209, 219, 229); + border-bottom-color: rgb(209, 219, 229); + } + } + } + } + @include m(right) { + .el-tabs__header.is-right { + float: right; + margin-bottom: 0; + margin-left: 10px; + } + + .el-tabs__nav-wrap.is-right { + margin-left: -1px; + &::after { + left: 0; + right: auto; + } + } + + .el-tabs__active-bar.is-right { + left: 0; + } + + &.el-tabs--card { + .el-tabs__active-bar.is-right { + display: none; + } + .el-tabs__item.is-right { + border-bottom: none; + border-top: 1px solid $--border-color-light; + } + .el-tabs__item.is-right:first-child { + border-left: 1px solid $--border-color-light; + border-top: none; + } + .el-tabs__item.is-right.is-active { + border: 1px solid $--border-color-light; + border-left-color: #fff; + border-right: none; + border-bottom: none; + + &:first-child { + border-top: none; + } + &:last-child { + border-bottom: none; + } + } + + .el-tabs__nav { + border-radius: 0 4px 4px 0; + border-bottom: 1px solid $--border-color-light; + border-left: none; + } + } + &.el-tabs--border-card { + .el-tabs__header.is-right { + border-left: 1px solid #dfe4ed; + } + .el-tabs__item.is-right { + border: 1px solid transparent; + margin: -1px -1px -1px 0; + + &.is-active { + border-color: transparent; + border-top-color: rgb(209, 219, 229); + border-bottom-color: rgb(209, 219, 229); + } + } + } + } +} + +.slideInRight-transition, +.slideInLeft-transition { + display: inline-block; +} +.slideInRight-enter { + animation: slideInRight-enter .3s; +} +.slideInRight-leave { + position: absolute; + left: 0; + right: 0; + animation: slideInRight-leave .3s; +} +.slideInLeft-enter { + animation: slideInLeft-enter .3s; +} +.slideInLeft-leave { + position: absolute; + left: 0; + right: 0; + animation: slideInLeft-leave .3s; +} + +@keyframes slideInRight-enter { + 0% { + opacity: 0; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: translateX(100%); + transform: translateX(100%) + } + + to { + opacity: 1; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: translateX(0); + transform: translateX(0) + } +} +@keyframes slideInRight-leave { + 0% { + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: translateX(0); + transform: translateX(0); + opacity: 1 + } + + 100% { + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: translateX(100%); + transform: translateX(100%); + opacity: 0 + } +} +@keyframes slideInLeft-enter { + 0% { + opacity: 0; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: translateX(-100%); + transform: translateX(-100%) + } + + to { + opacity: 1; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: translateX(0); + transform: translateX(0) + } +} +@keyframes slideInLeft-leave { + 0% { + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: translateX(0); + transform: translateX(0); + opacity: 1 + } + + 100% { + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + opacity: 0 + } +} diff --git a/packages/theme-chalk/src/tag.scss b/packages/theme-chalk/src/tag.scss new file mode 100644 index 0000000..1622902 --- /dev/null +++ b/packages/theme-chalk/src/tag.scss @@ -0,0 +1,163 @@ +@import "mixins/mixins"; +@import "common/var"; + +@mixin genTheme($backgroundColorWeight, $borderColorWeight, $fontColorWeight, $hoverColorWeight) { + background-color: mix($--tag-primary-color, $--color-white, $backgroundColorWeight); + border-color: mix($--tag-primary-color, $--color-white, $borderColorWeight); + color: mix($--tag-primary-color, $--color-white, $fontColorWeight); + + @include when(hit) { + border-color: $--tag-primary-color; + } + + .el-tag__close { + color: mix($--tag-primary-color, $--color-white, $fontColorWeight); + &:hover { + color: $--color-white; + background-color: mix($--tag-primary-color, $--color-white, $hoverColorWeight); + } + } + + &.el-tag--info { + background-color: mix($--tag-info-color, $--color-white, $backgroundColorWeight); + border-color: mix($--tag-info-color, $--color-white, $borderColorWeight); + color: mix($--tag-info-color, $--color-white, $fontColorWeight); + + @include when(hit) { + border-color: $--tag-info-color; + } + + .el-tag__close { + color: mix($--tag-info-color, $--color-white, $fontColorWeight); + &:hover { + color: $--color-white; + background-color: mix($--tag-info-color, $--color-white, $hoverColorWeight); + } + } + } + + &.el-tag--success { + background-color: mix($--tag-success-color, $--color-white, $backgroundColorWeight); + border-color: mix($--tag-success-color, $--color-white, $borderColorWeight); + color: mix($--tag-success-color, $--color-white, $fontColorWeight); + + @include when(hit) { + border-color: $--tag-success-color; + } + + .el-tag__close { + color: mix($--tag-success-color, $--color-white, $fontColorWeight); + &:hover { + color: $--color-white; + background-color: mix($--tag-success-color, $--color-white, $hoverColorWeight); + } + } + } + + &.el-tag--warning { + background-color: mix($--tag-warning-color, $--color-white, $backgroundColorWeight); + border-color: mix($--tag-warning-color, $--color-white, $borderColorWeight); + color: mix($--tag-warning-color, $--color-white, $fontColorWeight); + + @include when(hit) { + border-color: $--tag-warning-color; + } + + .el-tag__close { + color: mix($--tag-warning-color, $--color-white, $fontColorWeight); + &:hover { + color: $--color-white; + background-color: mix($--tag-warning-color, $--color-white, $hoverColorWeight); + } + } + } + + &.el-tag--danger { + background-color: mix($--tag-danger-color, $--color-white, $backgroundColorWeight); + border-color: mix($--tag-danger-color, $--color-white, $borderColorWeight); + color: mix($--tag-danger-color, $--color-white, $fontColorWeight); + + @include when(hit) { + border-color: $--tag-danger-color; + } + + .el-tag__close { + color: mix($--tag-danger-color, $--color-white, $fontColorWeight); + &:hover { + color: $--color-white; + background-color: mix($--tag-danger-color, $--color-white, $hoverColorWeight); + } + } + } +} + +@include b(tag) { + @include genTheme(10%, 20%, 100%, 100%); + display: inline-block; + height: 32px; + padding: $--tag-padding; + line-height: 30px; + font-size: $--tag-font-size; + color: $--tag-primary-color; + border-width: 1px; + border-style: solid; + border-radius: $--tag-border-radius; + box-sizing: border-box; + white-space: nowrap; + + .el-icon-close { + border-radius: 50%; + text-align: center; + position: relative; + cursor: pointer; + font-size: 12px; + height: 16px; + width: 16px; + line-height: 16px; + vertical-align: middle; + top: -1px; + right: -5px; + + &::before { + display: block; + } + } + + @include m(dark) { + @include genTheme(100%, 100%, 0, 80%); + } + + @include m(plain) { + @include genTheme(0, 40%, 100%, 100%); + } + + @include m(medium) { + height: 28px; + line-height: 26px; + + .el-icon-close { + transform: scale(.8); + } + } + + @include m(small) { + height: 24px; + padding: 0 8px; + line-height: 22px; + + .el-icon-close { + transform: scale(.8); + } + } + + @include m(mini) { + height: 20px; + padding: 0 5px; + line-height: 19px; + + .el-icon-close { + margin-left: -3px; + transform: scale(.7); + } + } +} diff --git a/packages/theme-chalk/src/time-picker.scss b/packages/theme-chalk/src/time-picker.scss new file mode 100644 index 0000000..10aaf54 --- /dev/null +++ b/packages/theme-chalk/src/time-picker.scss @@ -0,0 +1,8 @@ +@import "./date-picker/picker.scss"; +@import "./date-picker/picker-panel.scss"; +@import "./date-picker/time-spinner.scss"; +@import "./date-picker/time-picker.scss"; +@import "./date-picker/time-range-picker.scss"; +@import "./input.scss"; +@import "./scrollbar.scss"; +@import "./popper"; diff --git a/packages/theme-chalk/src/time-select.scss b/packages/theme-chalk/src/time-select.scss new file mode 100644 index 0000000..0de3853 --- /dev/null +++ b/packages/theme-chalk/src/time-select.scss @@ -0,0 +1,37 @@ +@import "common/var"; +@import "./date-picker/picker.scss"; +@import "./date-picker/date-picker.scss"; +@import "./scrollbar.scss"; +@import "./popper"; + +.time-select { + margin: 5px 0; + min-width: 0; +} + +.time-select .el-picker-panel__content { + max-height: 200px; + margin: 0; +} + +.time-select-item { + padding: 8px 10px; + font-size: 14px; + line-height: 20px; +} + +.time-select-item.selected:not(.disabled) { + color: $--color-primary; + font-weight: bold; +} + +.time-select-item.disabled { + color: $--datepicker-border-color; + cursor: not-allowed; +} + +.time-select-item:hover { + background-color: $--background-color-base; + font-weight: bold; + cursor: pointer; +} diff --git a/packages/theme-chalk/src/timeline-item.scss b/packages/theme-chalk/src/timeline-item.scss new file mode 100644 index 0000000..b36ed2b --- /dev/null +++ b/packages/theme-chalk/src/timeline-item.scss @@ -0,0 +1,86 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(timeline-item) { + position: relative; + padding-bottom: 20px; + + @include e(wrapper) { + position: relative; + padding-left: 28px; + top: -3px; + } + + @include e(tail) { + position: absolute; + left: 4px; + height: 100%; + border-left: 2px solid $--timeline-node-color; + } + + @include e(icon) { + color: $--color-white; + font-size: $--font-size-small; + } + + @include e(node) { + position: absolute; + background-color: $--timeline-node-color; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + + @include m(normal) { + left: -1px; + width: $--timeline-node-size-normal; + height: $--timeline-node-size-normal; + } + @include m(large) { + left: -2px; + width: $--timeline-node-size-large; + height: $--timeline-node-size-large; + } + + @include m(primary) { + background-color: $--color-primary; + } + @include m(success) { + background-color: $--color-success; + } + @include m(warning) { + background-color: $--color-warning; + } + @include m(danger) { + background-color: $--color-danger; + } + @include m(info) { + background-color: $--color-info; + } + } + + @include e(dot) { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + } + + @include e(content) { + color: $--color-text-primary; + } + + @include e(timestamp) { + color: $--color-text-secondary; + line-height: 1; + font-size: $--font-size-small; + + @include when(top) { + margin-bottom: 8px; + padding-top: 4px; + } + @include when(bottom) { + margin-top: 8px; + } + } +} diff --git a/packages/theme-chalk/src/timeline.scss b/packages/theme-chalk/src/timeline.scss new file mode 100644 index 0000000..60a779e --- /dev/null +++ b/packages/theme-chalk/src/timeline.scss @@ -0,0 +1,14 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(timeline) { + margin: 0; + font-size: $--font-size-base; + list-style: none; + + & .el-timeline-item:last-child { + & .el-timeline-item__tail { + display: none; + } + } +} diff --git a/packages/theme-chalk/src/tooltip.scss b/packages/theme-chalk/src/tooltip.scss new file mode 100644 index 0000000..0a016a8 --- /dev/null +++ b/packages/theme-chalk/src/tooltip.scss @@ -0,0 +1,141 @@ +@import "mixins/mixins"; +@import "common/var"; + +@include b(tooltip) { + &:focus:not(.focusing), &:focus:hover { + outline-width: 0; + } + @include e(popper) { + position: absolute; + border-radius: 4px; + padding: $--tooltip-padding; + z-index: $--index-popper; + font-size: $--tooltip-font-size; + line-height: 1.2; + min-width: 10px; + word-wrap: break-word; + + .popper__arrow, + .popper__arrow::after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + } + + .popper__arrow { + border-width: $--tooltip-arrow-size; + } + + .popper__arrow::after { + content: " "; + border-width: 5px; + } + + &[x-placement^="top"] { + margin-bottom: #{$--tooltip-arrow-size + 6px}; + } + + &[x-placement^="top"] .popper__arrow { + bottom: -$--tooltip-arrow-size; + border-top-color: $--tooltip-border-color; + border-bottom-width: 0; + + &::after { + bottom: 1px; + margin-left: -5px; + border-top-color: $--tooltip-fill; + border-bottom-width: 0; + } + } + + &[x-placement^="bottom"] { + margin-top: #{$--tooltip-arrow-size + 6px}; + } + + &[x-placement^="bottom"] .popper__arrow { + top: -$--tooltip-arrow-size; + border-top-width: 0; + border-bottom-color: $--tooltip-border-color; + + &::after { + top: 1px; + margin-left: -5px; + border-top-width: 0; + border-bottom-color: $--tooltip-fill; + } + } + + &[x-placement^="right"] { + margin-left: #{$--tooltip-arrow-size + 6px}; + } + + &[x-placement^="right"] .popper__arrow { + left: -$--tooltip-arrow-size; + border-right-color: $--tooltip-border-color; + border-left-width: 0; + + &::after { + bottom: -5px; + left: 1px; + border-right-color: $--tooltip-fill; + border-left-width: 0; + } + } + + &[x-placement^="left"] { + margin-right: #{$--tooltip-arrow-size + 6px}; + } + + &[x-placement^="left"] .popper__arrow { + right: -$--tooltip-arrow-size; + border-right-width: 0; + border-left-color: $--tooltip-border-color; + + &::after { + right: 1px; + bottom: -5px; + margin-left: -5px; + border-right-width: 0; + border-left-color: $--tooltip-fill; + } + } + + @include when(dark) { + background: $--tooltip-fill; + color: $--tooltip-color; + } + + @include when(light) { + background: $--tooltip-color; + border: 1px solid $--tooltip-fill; + + &[x-placement^="top"] .popper__arrow { + border-top-color: $--tooltip-fill; + &::after { + border-top-color: $--tooltip-color; + } + } + &[x-placement^="bottom"] .popper__arrow { + border-bottom-color: $--tooltip-fill; + &::after { + border-bottom-color: $--tooltip-color; + } + } + &[x-placement^="left"] .popper__arrow { + border-left-color: $--tooltip-fill; + &::after { + border-left-color: $--tooltip-color; + } + } + &[x-placement^="right"] .popper__arrow { + border-right-color: $--tooltip-fill; + &::after { + border-right-color: $--tooltip-color; + } + } + } + } +} diff --git a/packages/theme-chalk/src/transfer.scss b/packages/theme-chalk/src/transfer.scss new file mode 100644 index 0000000..fea7d7b --- /dev/null +++ b/packages/theme-chalk/src/transfer.scss @@ -0,0 +1,227 @@ +@import "mixins/mixins"; +@import "mixins/utils"; +@import "common/var"; +@import "input"; +@import "button"; +@import "checkbox"; +@import "checkbox-group"; + +@include b(transfer) { + font-size: $--font-size-base; + + @include e(buttons) { + display: inline-block; + vertical-align: middle; + padding: 0 30px; + } + + @include e(button) { + display: block; + margin: 0 auto; + padding: 10px; + border-radius: 50%; + color: $--color-white; + background-color: $--color-primary; + font-size: 0; + + @include when(with-texts) { + border-radius: $--border-radius-base; + } + + @include when(disabled) { + border: $--border-base; + background-color: $--background-color-base; + color: $--color-text-placeholder; + + &:hover { + border: $--border-base; + background-color: $--background-color-base; + color: $--color-text-placeholder; + } + } + + &:first-child { + margin-bottom: 10px; + } + + &:nth-child(2) { + margin: 0; + } + + i, span { + font-size: 14px; + } + + & [class*="el-icon-"] + span { + margin-left: 0; + } + } +} + +@include b(transfer-panel) { + border: 1px solid $--transfer-border-color; + border-radius: $--transfer-border-radius; + overflow: hidden; + background: $--color-white; + display: inline-block; + vertical-align: middle; + width: $--transfer-panel-width; + max-height: 100%; + box-sizing: border-box; + position: relative; + + @include e(body) { + height: $--transfer-panel-body-height; + + @include when(with-footer) { + padding-bottom: $--transfer-panel-footer-height; + } + } + + @include e(list) { + margin: 0; + padding: 6px 0; + list-style: none; + height: $--transfer-panel-body-height; + overflow: auto; + box-sizing: border-box; + + @include when(filterable) { + height: #{$--transfer-panel-body-height - $--transfer-filter-height - 20px}; + padding-top: 0; + } + } + + @include e(item) { + height: $--transfer-item-height; + line-height: $--transfer-item-height; + padding-left: 15px; + display: block !important; + + & + .el-transfer-panel__item { + margin-left: 0; + } + + &.el-checkbox { + color: $--color-text-regular; + } + + &:hover { + color: $--color-primary; + } + + &.el-checkbox .el-checkbox__label { + width: 100%; + @include utils-ellipsis; + display: block; + box-sizing: border-box; + padding-left: 24px; + line-height: $--transfer-item-height; + } + + .el-checkbox__input { + position: absolute; + top: 8px; + } + } + + @include e(filter) { + text-align: center; + margin: 15px; + box-sizing: border-box; + display: block; + width: auto; + + .el-input__inner { + height: $--transfer-filter-height; + width: 100%; + font-size: 12px; + display: inline-block; + box-sizing: border-box; + border-radius: #{$--transfer-filter-height / 2}; + padding-right: 10px; + padding-left: 30px; + } + + .el-input__icon { + margin-left: 5px; + } + + .el-icon-circle-close { + cursor: pointer; + } + } + + .el-transfer-panel__header { + height: $--transfer-panel-header-height; + line-height: $--transfer-panel-header-height; + background: $--transfer-panel-header-background-color; + margin: 0; + padding-left: 15px; + border-bottom: 1px solid $--transfer-border-color; + box-sizing: border-box; + color: $--color-black; + + .el-checkbox { + display: block; + line-height: 40px; + + .el-checkbox__label { + font-size: 16px; + color: $--color-text-primary; + font-weight: normal; + + span { + position: absolute; + right: 15px; + color: $--color-text-secondary; + font-size: 12px; + font-weight: normal; + } + } + } + } + + .el-transfer-panel__footer { + height: $--transfer-panel-footer-height; + background: $--color-white; + margin: 0; + padding: 0; + border-top: 1px solid $--transfer-border-color; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + z-index: $--index-normal; + @include utils-vertical-center; + + .el-checkbox { + padding-left: 20px; + color: $--color-text-regular; + } + } + + .el-transfer-panel__empty { + margin: 0; + height: $--transfer-item-height; + line-height: $--transfer-item-height; + padding: 6px 15px 0; + color: $--color-text-secondary; + text-align: center; + } + + .el-checkbox__label { + padding-left: 8px; + } + + .el-checkbox__inner { + height: 14px; + width: 14px; + border-radius: 3px; + &::after { + height: 6px; + width: 3px; + left: 4px; + } + } +} diff --git a/packages/theme-chalk/src/tree.scss b/packages/theme-chalk/src/tree.scss new file mode 100644 index 0000000..c3b18de --- /dev/null +++ b/packages/theme-chalk/src/tree.scss @@ -0,0 +1,123 @@ +@import "mixins/mixins"; +@import "common/var"; +@import "common/transition"; +@import "checkbox"; + +@include b(tree) { + position: relative; + cursor: default; + background: $--color-white; + color: $--tree-font-color; + + @include e(empty-block) { + position: relative; + min-height: 60px; + text-align: center; + width: 100%; + height: 100%; + } + + @include e(empty-text) { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + color: $--color-text-secondary; + font-size: $--font-size-base; + } + + @include e(drop-indicator) { + position: absolute; + left: 0; + right: 0; + height: 1px; + background-color: $--color-primary; + } +} + +@include b(tree-node) { + white-space: nowrap; + outline: none; + &:focus { /* focus */ + > .el-tree-node__content { + background-color: $--tree-node-hover-background-color; + } + } + + @include when(drop-inner) { + > .el-tree-node__content .el-tree-node__label { + background-color: $--color-primary; + color: #fff; + } + } + + @include e(content) { + display: flex; + align-items: center; + height: 26px; + cursor: pointer; + + & > .el-tree-node__expand-icon { + padding: 6px; + } + & > label.el-checkbox { + margin-right: 8px; + } + &:hover { + background-color: $--tree-node-hover-background-color; + } + + .el-tree.is-dragging & { + cursor: move; + + & * { + pointer-events: none; + } + } + + .el-tree.is-dragging.is-drop-not-allow & { + cursor: not-allowed; + } + } + + @include e(expand-icon) { + cursor: pointer; + color: $--tree-expand-icon-color; + font-size: 12px; + + transform: rotate(0deg); + transition: transform 0.3s ease-in-out; + + &.expanded { + transform: rotate(90deg); + } + + &.is-leaf { + color: transparent; + cursor: default; + } + } + + @include e(label) { + font-size: $--font-size-base; + } + + @include e(loading-icon) { + margin-right: 8px; + font-size: $--font-size-base; + color: $--tree-expand-icon-color; + } + + & > .el-tree-node__children { + overflow: hidden; + background-color: transparent; + } + + &.is-expanded > .el-tree-node__children { + display: block; + } +} + +.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content { + background-color: mix($--color-white, $--color-primary, 92%); +} diff --git a/packages/theme-chalk/src/upload.scss b/packages/theme-chalk/src/upload.scss new file mode 100644 index 0000000..aebbc1c --- /dev/null +++ b/packages/theme-chalk/src/upload.scss @@ -0,0 +1,603 @@ +@import "mixins/mixins"; +@import "progress"; +@import "common/var"; + +@include b(upload) { + display: inline-block; + text-align: center; + cursor: pointer; + outline: none; + @include e(input) { + display: none; + } + + @include e(tip) { + font-size: 12px; + color: $--color-text-regular; + margin-top: 7px; + } + + iframe { + position: absolute; + z-index: -1; + top: 0; + left: 0; + opacity: 0; + filter: alpha(opacity=0); + } + + /* 照片墙模式 */ + @include m(picture-card) { + background-color: #fbfdff; + border: 1px dashed #c0ccda; + border-radius: 6px; + box-sizing: border-box; + width: 148px; + height: 148px; + cursor: pointer; + line-height: 146px; + vertical-align: top; + + i { + font-size: 28px; + color: #8c939d; + } + + &:hover { + border-color: $--color-primary; + color: $--color-primary; + } + } + &:focus { + border-color: $--color-primary; + color: $--color-primary; + + .el-upload-dragger { + border-color: $--color-primary; + } + } +} + +@include b(upload-dragger) { + background-color: #fff; + border: 1px dashed #d9d9d9; + border-radius: 6px; + box-sizing: border-box; + width: 360px; + height: 180px; + text-align: center; + cursor: pointer; + position: relative; + overflow: hidden; + + .el-icon-upload { + font-size: 67px; + color: $--color-text-placeholder; + margin: 40px 0 16px; + line-height: 50px; + } + + + .el-upload__tip { + text-align: center; + } + + ~ .el-upload__files { + border-top: $--border-base; + margin-top: 7px; + padding-top: 5px; + } + + .el-upload__text { + color: $--color-text-regular; + font-size: 14px; + text-align: center; + + em { + color: $--color-primary; + font-style: normal; + } + } + + &:hover { + border-color: $--color-primary; + } + + @include when(dragover) { + background-color: rgba(32, 159, 255, .06); + border: 2px dashed $--color-primary; + } +} + +@include b(upload-list) { + margin: 0; + padding: 0; + list-style: none; + + @include e(item) { + transition: all .5s cubic-bezier(.55,0,.1,1); + font-size: 14px; + color: $--color-text-regular; + line-height: 1.8; + margin-top: 5px; + position: relative; + box-sizing: border-box; + border-radius: 4px; + width: 100%; + + .el-progress { + position: absolute; + top: 20px; + width: 100%; + } + + .el-progress__text { + position: absolute; + right: 0; + top: -13px; + } + + .el-progress-bar { + margin-right: 0; + padding-right: 0; + } + + &:first-child { + margin-top: 10px; + } + + & .el-icon-upload-success { + color: $--color-success; + } + + .el-icon-close { + display: none; + position: absolute; + top: 5px; + right: 5px; + cursor: pointer; + opacity: .75; + color: $--color-text-regular; + //transform: scale(.7); + + &:hover { + opacity: 1; + } + } + + & .el-icon-close-tip { + display: none; + position: absolute; + top: 5px; + right: 5px; + font-size: 12px; + cursor: pointer; + opacity: 1; + color: $--color-primary; + } + + &:hover { + background-color: $--background-color-base; + + .el-icon-close { + display: inline-block; + } + + .el-progress__text { + display: none; + } + } + + @include when(success) { + .el-upload-list__item-status-label { + display: block; + } + + .el-upload-list__item-name:hover, .el-upload-list__item-name:focus { + color: $--link-hover-color; + cursor: pointer; + } + + &:focus:not(:hover) { /* 键盘focus */ + .el-icon-close-tip { + display: inline-block; + } + } + + &:not(.focusing):focus, &:active { /* click时 */ + outline-width: 0; + .el-icon-close-tip { + display: none; + } + } + + &:hover, &:focus { + .el-upload-list__item-status-label { + display: none; + } + } + } + } + + @include when(disabled) { + .el-upload-list__item:hover .el-upload-list__item-status-label { + display: block; + } + } + + @include e(item-name) { + color: $--color-text-regular; + display: block; + margin-right: 40px; + overflow: hidden; + padding-left: 4px; + text-overflow: ellipsis; + transition: color .3s; + white-space: nowrap; + + [class^="el-icon"] { + height: 100%; + margin-right: 7px; + color: $--color-text-secondary; + line-height: inherit; + } + } + + @include e(item-status-label) { + position: absolute; + right: 5px; + top: 0; + line-height: inherit; + display: none; + } + + @include e(item-delete) { + position: absolute; + right: 10px; + top: 0; + font-size: 12px; + color: $--color-text-regular; + display: none; + + &:hover { + color: $--color-primary; + } + } + + @include m(picture-card) { + margin: 0; + display: inline; + vertical-align: top; + + .el-upload-list__item { + overflow: hidden; + background-color: #fff; + border: 1px solid #c0ccda; + border-radius: 6px; + box-sizing: border-box; + width: 148px; + height: 148px; + margin: 0 8px 8px 0; + display: inline-block; + + .el-icon-check, + .el-icon-circle-check { + color: $--color-white; + } + + .el-icon-close { + display: none; + } + &:hover { + .el-upload-list__item-status-label { + display: none; + } + + .el-progress__text { + display: block; + } + } + } + + .el-upload-list__item-name { + display: none; + } + + .el-upload-list__item-thumbnail { + width: 100%; + height: 100%; + } + + .el-upload-list__item-status-label { + position: absolute; + right: -15px; + top: -6px; + width: 40px; + height: 24px; + background: #13ce66; + text-align: center; + transform: rotate(45deg); + box-shadow: 0 0 1pc 1px rgba(0,0,0,0.2); + + i { + font-size: 12px; + margin-top: 11px; + transform: rotate(-45deg); + } + } + + .el-upload-list__item-actions { + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + cursor: default; + text-align: center; + color: #fff; + opacity: 0; + font-size: 20px; + background-color: rgba(0, 0, 0, .5); + transition: opacity .3s; + &::after { + display: inline-block; + content: ""; + height: 100%; + vertical-align: middle + } + + span { + display: none; + cursor: pointer; + } + + span + span { + margin-left: 15px; + } + + .el-upload-list__item-delete { + position: static; + font-size: inherit; + color: inherit; + } + + &:hover { + opacity: 1; + span { + display: inline-block; + } + } + } + + .el-progress { + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + bottom: auto; + width: 126px; + + .el-progress__text { + top: 50%; + } + } + } + + @include m(picture) { + .el-upload-list__item { + overflow: hidden; + z-index: 0; + background-color: #fff; + border: 1px solid #c0ccda; + border-radius: 6px; + box-sizing: border-box; + margin-top: 10px; + padding: 10px 10px 10px 90px; + height: 92px; + + .el-icon-check, + .el-icon-circle-check { + color: $--color-white; + } + + &:hover { + .el-upload-list__item-status-label { + background: transparent; + box-shadow: none; + top: -2px; + right: -12px; + } + + .el-progress__text { + display: block; + } + } + + &.is-success { + .el-upload-list__item-name { + line-height: 70px; + margin-top: 0; + i { + display: none; + } + } + } + } + + .el-upload-list__item-thumbnail { + vertical-align: middle; + display: inline-block; + width: 70px; + height: 70px; + float: left; + position: relative; + z-index: 1; + margin-left: -80px; + background-color: $--color-white + } + + .el-upload-list__item-name { + display: block; + margin-top: 20px; + + i { + font-size: 70px; + line-height: 1; + position: absolute; + left: 9px; + top: 10px; + } + } + + .el-upload-list__item-status-label { + position: absolute; + right: -17px; + top: -7px; + width: 46px; + height: 26px; + background: #13ce66; + text-align: center; + transform: rotate(45deg); + box-shadow: 0 1px 1px #ccc; + + i { + font-size: 12px; + margin-top: 12px; + transform: rotate(-45deg); + } + } + + .el-progress { + position: relative; + top: -7px; + } + } +} + +@include b(upload-cover) { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: hidden; + z-index: 10; + cursor: default; + @include utils-vertical-center; + + img { + display: block; + width: 100%; + height: 100%; + } + + @include e(label) { + position: absolute; + right: -15px; + top: -6px; + width: 40px; + height: 24px; + background: #13ce66; + text-align: center; + transform: rotate(45deg); + box-shadow: 0 0 1pc 1px rgba(0,0,0,0.2); + + i { + font-size: 12px; + margin-top: 11px; + transform: rotate(-45deg); + color: #fff; + } + } + + @include e(progress) { + display: inline-block; + vertical-align: middle; + position: static; + width: 243px; + + + .el-upload__inner { + opacity: 0; + } + } + + @include e(content) { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + + @include e(interact) { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(#000, .72); + text-align: center; + + .btn { + display: inline-block; + color: $--color-white; + font-size: 14px; + cursor: pointer; + vertical-align: middle; + transition: $--md-fade-transition; + margin-top: 60px; + + i { + margin-top: 0; + } + + span { + opacity: 0; + transition: opacity .15s linear; + } + + &:not(:first-child) { + margin-left: 35px; + } + + &:hover { + transform: translateY(-13px); + + span { + opacity: 1; + } + } + + i { + color: $--color-white; + display: block; + font-size: 24px; + line-height: inherit; + margin: 0 auto 5px; + } + } + } + + @include e(title) { + position: absolute; + bottom: 0; + left: 0; + background-color: $--color-white; + height: 36px; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-weight: normal; + text-align: left; + padding: 0 10px; + margin: 0; + line-height: 36px; + font-size: 14px; + color: $--color-text-primary; + } + + + .el-upload__inner { + opacity: 0; + position: relative; + z-index: 1; + } +} diff --git a/packages/time-picker/index.js b/packages/time-picker/index.js new file mode 100644 index 0000000..ad692a7 --- /dev/null +++ b/packages/time-picker/index.js @@ -0,0 +1,8 @@ +import TimePicker from '../date-picker/src/picker/time-picker'; + +/* istanbul ignore next */ +TimePicker.install = function(Vue) { + Vue.component(TimePicker.name, TimePicker); +}; + +export default TimePicker; diff --git a/packages/time-select/index.js b/packages/time-select/index.js new file mode 100644 index 0000000..3a51dcd --- /dev/null +++ b/packages/time-select/index.js @@ -0,0 +1,8 @@ +import TimeSelect from '../date-picker/src/picker/time-select'; + +/* istanbul ignore next */ +TimeSelect.install = function(Vue) { + Vue.component(TimeSelect.name, TimeSelect); +}; + +export default TimeSelect; diff --git a/packages/timeline-item/index.js b/packages/timeline-item/index.js new file mode 100644 index 0000000..a9e5245 --- /dev/null +++ b/packages/timeline-item/index.js @@ -0,0 +1,8 @@ +import ElTimelineItem from '../timeline/src/item'; + +/* istanbul ignore next */ +ElTimelineItem.install = function(Vue) { + Vue.component(ElTimelineItem.name, ElTimelineItem); +}; + +export default ElTimelineItem; diff --git a/packages/timeline/index.js b/packages/timeline/index.js new file mode 100644 index 0000000..ddfa6da --- /dev/null +++ b/packages/timeline/index.js @@ -0,0 +1,8 @@ +import Timeline from './src/main'; + +/* istanbul ignore next */ +Timeline.install = function(Vue) { + Vue.component(Timeline.name, Timeline); +}; + +export default Timeline; diff --git a/packages/timeline/src/item.vue b/packages/timeline/src/item.vue new file mode 100644 index 0000000..86771bb --- /dev/null +++ b/packages/timeline/src/item.vue @@ -0,0 +1,73 @@ + + + diff --git a/packages/timeline/src/main.vue b/packages/timeline/src/main.vue new file mode 100644 index 0000000..09c8114 --- /dev/null +++ b/packages/timeline/src/main.vue @@ -0,0 +1,33 @@ + diff --git a/packages/tooltip/index.js b/packages/tooltip/index.js new file mode 100644 index 0000000..1e9ac98 --- /dev/null +++ b/packages/tooltip/index.js @@ -0,0 +1,8 @@ +import Tooltip from './src/main'; + +/* istanbul ignore next */ +Tooltip.install = function(Vue) { + Vue.component(Tooltip.name, Tooltip); +}; + +export default Tooltip; diff --git a/packages/tooltip/src/main.js b/packages/tooltip/src/main.js new file mode 100644 index 0000000..6b700bb --- /dev/null +++ b/packages/tooltip/src/main.js @@ -0,0 +1,241 @@ +import Popper from 'element-ui/src/utils/vue-popper'; +import debounce from 'throttle-debounce/debounce'; +import { addClass, removeClass, on, off } from 'element-ui/src/utils/dom'; +import { generateId } from 'element-ui/src/utils/util'; +import Vue from 'vue'; + +export default { + name: 'ElTooltip', + + mixins: [Popper], + + props: { + openDelay: { + type: Number, + default: 0 + }, + disabled: Boolean, + manual: Boolean, + effect: { + type: String, + default: 'dark' + }, + arrowOffset: { + type: Number, + default: 0 + }, + popperClass: String, + content: String, + visibleArrow: { + default: true + }, + transition: { + type: String, + default: 'el-fade-in-linear' + }, + popperOptions: { + default() { + return { + boundariesPadding: 10, + gpuAcceleration: false + }; + } + }, + enterable: { + type: Boolean, + default: true + }, + hideAfter: { + type: Number, + default: 0 + }, + tabindex: { + type: Number, + default: 0 + } + }, + + data() { + return { + tooltipId: `el-tooltip-${generateId()}`, + timeoutPending: null, + focusing: false + }; + }, + beforeCreate() { + if (this.$isServer) return; + + this.popperVM = new Vue({ + data: { node: '' }, + render(h) { + return this.node; + } + }).$mount(); + + this.debounceClose = debounce(200, () => this.handleClosePopper()); + }, + + render(h) { + if (this.popperVM) { + this.popperVM.node = ( + +
{ this.setExpectedState(false); this.debounceClose(); } } + onMouseenter= { () => { this.setExpectedState(true); } } + ref="popper" + role="tooltip" + id={this.tooltipId} + aria-hidden={ (this.disabled || !this.showPopper) ? 'true' : 'false' } + v-show={!this.disabled && this.showPopper} + class={ + ['el-tooltip__popper', 'is-' + this.effect, this.popperClass] + }> + { this.$slots.content || this.content } +
+
); + } + + const firstElement = this.getFirstElement(); + if (!firstElement) return null; + + const data = firstElement.data = firstElement.data || {}; + data.staticClass = this.addTooltipClass(data.staticClass); + + return firstElement; + }, + + mounted() { + this.referenceElm = this.$el; + if (this.$el.nodeType === 1) { + this.$el.setAttribute('aria-describedby', this.tooltipId); + this.$el.setAttribute('tabindex', this.tabindex); + on(this.referenceElm, 'mouseenter', this.show); + on(this.referenceElm, 'mouseleave', this.hide); + on(this.referenceElm, 'focus', () => { + if (!this.$slots.default || !this.$slots.default.length) { + this.handleFocus(); + return; + } + const instance = this.$slots.default[0].componentInstance; + if (instance && instance.focus) { + instance.focus(); + } else { + this.handleFocus(); + } + }); + on(this.referenceElm, 'blur', this.handleBlur); + on(this.referenceElm, 'click', this.removeFocusing); + } + // fix issue https://github.com/ElemeFE/element/issues/14424 + if (this.value && this.popperVM) { + this.popperVM.$nextTick(() => { + if (this.value) { + this.updatePopper(); + } + }); + } + }, + watch: { + focusing(val) { + if (val) { + addClass(this.referenceElm, 'focusing'); + } else { + removeClass(this.referenceElm, 'focusing'); + } + } + }, + methods: { + show() { + this.setExpectedState(true); + this.handleShowPopper(); + }, + + hide() { + this.setExpectedState(false); + this.debounceClose(); + }, + handleFocus() { + this.focusing = true; + this.show(); + }, + handleBlur() { + this.focusing = false; + this.hide(); + }, + removeFocusing() { + this.focusing = false; + }, + + addTooltipClass(prev) { + if (!prev) { + return 'el-tooltip'; + } else { + return 'el-tooltip ' + prev.replace('el-tooltip', ''); + } + }, + + handleShowPopper() { + if (!this.expectedState || this.manual) return; + clearTimeout(this.timeout); + this.timeout = setTimeout(() => { + this.showPopper = true; + }, this.openDelay); + + if (this.hideAfter > 0) { + this.timeoutPending = setTimeout(() => { + this.showPopper = false; + }, this.hideAfter); + } + }, + + handleClosePopper() { + if (this.enterable && this.expectedState || this.manual) return; + clearTimeout(this.timeout); + + if (this.timeoutPending) { + clearTimeout(this.timeoutPending); + } + this.showPopper = false; + + if (this.disabled) { + this.doDestroy(); + } + }, + + setExpectedState(expectedState) { + if (expectedState === false) { + clearTimeout(this.timeoutPending); + } + this.expectedState = expectedState; + }, + + getFirstElement() { + const slots = this.$slots.default; + if (!Array.isArray(slots)) return null; + let element = null; + for (let index = 0; index < slots.length; index++) { + if (slots[index] && slots[index].tag) { + element = slots[index]; + }; + } + return element; + } + }, + + beforeDestroy() { + this.popperVM && this.popperVM.$destroy(); + }, + + destroyed() { + const reference = this.referenceElm; + if (reference.nodeType === 1) { + off(reference, 'mouseenter', this.show); + off(reference, 'mouseleave', this.hide); + off(reference, 'focus', this.handleFocus); + off(reference, 'blur', this.handleBlur); + off(reference, 'click', this.removeFocusing); + } + } +}; diff --git a/packages/transfer/index.js b/packages/transfer/index.js new file mode 100644 index 0000000..0283e8b --- /dev/null +++ b/packages/transfer/index.js @@ -0,0 +1,8 @@ +import Transfer from './src/main'; + +/* istanbul ignore next */ +Transfer.install = function(Vue) { + Vue.component(Transfer.name, Transfer); +}; + +export default Transfer; diff --git a/packages/transfer/src/main.vue b/packages/transfer/src/main.vue new file mode 100644 index 0000000..1e93e39 --- /dev/null +++ b/packages/transfer/src/main.vue @@ -0,0 +1,231 @@ + + + diff --git a/packages/transfer/src/transfer-panel.vue b/packages/transfer/src/transfer-panel.vue new file mode 100644 index 0000000..6cfe754 --- /dev/null +++ b/packages/transfer/src/transfer-panel.vue @@ -0,0 +1,251 @@ + + + diff --git a/packages/tree/index.js b/packages/tree/index.js new file mode 100644 index 0000000..e52d6a5 --- /dev/null +++ b/packages/tree/index.js @@ -0,0 +1,8 @@ +import Tree from './src/tree.vue'; + +/* istanbul ignore next */ +Tree.install = function(Vue) { + Vue.component(Tree.name, Tree); +}; + +export default Tree; diff --git a/packages/tree/src/model/node.js b/packages/tree/src/model/node.js new file mode 100644 index 0000000..657b3b8 --- /dev/null +++ b/packages/tree/src/model/node.js @@ -0,0 +1,485 @@ +import objectAssign from 'element-ui/src/utils/merge'; +import { markNodeData, NODE_KEY } from './util'; +import { arrayFindIndex } from 'element-ui/src/utils/util'; + +export const getChildState = node => { + let all = true; + let none = true; + let allWithoutDisable = true; + for (let i = 0, j = node.length; i < j; i++) { + const n = node[i]; + if (n.checked !== true || n.indeterminate) { + all = false; + if (!n.disabled) { + allWithoutDisable = false; + } + } + if (n.checked !== false || n.indeterminate) { + none = false; + } + } + + return { all, none, allWithoutDisable, half: !all && !none }; +}; + +const reInitChecked = function(node) { + if (node.childNodes.length === 0) return; + + const {all, none, half} = getChildState(node.childNodes); + if (all) { + node.checked = true; + node.indeterminate = false; + } else if (half) { + node.checked = false; + node.indeterminate = true; + } else if (none) { + node.checked = false; + node.indeterminate = false; + } + + const parent = node.parent; + if (!parent || parent.level === 0) return; + + if (!node.store.checkStrictly) { + reInitChecked(parent); + } +}; + +const getPropertyFromData = function(node, prop) { + const props = node.store.props; + const data = node.data || {}; + const config = props[prop]; + + if (typeof config === 'function') { + return config(data, node); + } else if (typeof config === 'string') { + return data[config]; + } else if (typeof config === 'undefined') { + const dataProp = data[prop]; + return dataProp === undefined ? '' : dataProp; + } +}; + +let nodeIdSeed = 0; + +export default class Node { + constructor(options) { + this.id = nodeIdSeed++; + this.text = null; + this.checked = false; + this.indeterminate = false; + this.data = null; + this.expanded = false; + this.parent = null; + this.visible = true; + this.isCurrent = false; + + for (let name in options) { + if (options.hasOwnProperty(name)) { + this[name] = options[name]; + } + } + + // internal + this.level = 0; + this.loaded = false; + this.childNodes = []; + this.loading = false; + + if (this.parent) { + this.level = this.parent.level + 1; + } + + const store = this.store; + if (!store) { + throw new Error('[Node]store is required!'); + } + store.registerNode(this); + + const props = store.props; + if (props && typeof props.isLeaf !== 'undefined') { + const isLeaf = getPropertyFromData(this, 'isLeaf'); + if (typeof isLeaf === 'boolean') { + this.isLeafByUser = isLeaf; + } + } + + if (store.lazy !== true && this.data) { + this.setData(this.data); + + if (store.defaultExpandAll) { + this.expanded = true; + } + } else if (this.level > 0 && store.lazy && store.defaultExpandAll) { + this.expand(); + } + if (!Array.isArray(this.data)) { + markNodeData(this, this.data); + } + if (!this.data) return; + const defaultExpandedKeys = store.defaultExpandedKeys; + const key = store.key; + if (key && defaultExpandedKeys && defaultExpandedKeys.indexOf(this.key) !== -1) { + this.expand(null, store.autoExpandParent); + } + + if (key && store.currentNodeKey !== undefined && this.key === store.currentNodeKey) { + store.currentNode = this; + store.currentNode.isCurrent = true; + } + + if (store.lazy) { + store._initDefaultCheckedNode(this); + } + + this.updateLeafState(); + } + + setData(data) { + if (!Array.isArray(data)) { + markNodeData(this, data); + } + + this.data = data; + this.childNodes = []; + + let children; + if (this.level === 0 && this.data instanceof Array) { + children = this.data; + } else { + children = getPropertyFromData(this, 'children') || []; + } + + for (let i = 0, j = children.length; i < j; i++) { + this.insertChild({ data: children[i] }); + } + } + + get label() { + return getPropertyFromData(this, 'label'); + } + + get key() { + const nodeKey = this.store.key; + if (this.data) return this.data[nodeKey]; + return null; + } + + get disabled() { + return getPropertyFromData(this, 'disabled'); + } + + get nextSibling() { + const parent = this.parent; + if (parent) { + const index = parent.childNodes.indexOf(this); + if (index > -1) { + return parent.childNodes[index + 1]; + } + } + return null; + } + + get previousSibling() { + const parent = this.parent; + if (parent) { + const index = parent.childNodes.indexOf(this); + if (index > -1) { + return index > 0 ? parent.childNodes[index - 1] : null; + } + } + return null; + } + + contains(target, deep = true) { + const walk = function(parent) { + const children = parent.childNodes || []; + let result = false; + for (let i = 0, j = children.length; i < j; i++) { + const child = children[i]; + if (child === target || (deep && walk(child))) { + result = true; + break; + } + } + return result; + }; + + return walk(this); + } + + remove() { + const parent = this.parent; + if (parent) { + parent.removeChild(this); + } + } + + insertChild(child, index, batch) { + if (!child) throw new Error('insertChild error: child is required.'); + + if (!(child instanceof Node)) { + if (!batch) { + const children = this.getChildren(true); + if (children.indexOf(child.data) === -1) { + if (typeof index === 'undefined' || index < 0) { + children.push(child.data); + } else { + children.splice(index, 0, child.data); + } + } + } + objectAssign(child, { + parent: this, + store: this.store + }); + child = new Node(child); + } + + child.level = this.level + 1; + + if (typeof index === 'undefined' || index < 0) { + this.childNodes.push(child); + } else { + this.childNodes.splice(index, 0, child); + } + + this.updateLeafState(); + } + + insertBefore(child, ref) { + let index; + if (ref) { + index = this.childNodes.indexOf(ref); + } + this.insertChild(child, index); + } + + insertAfter(child, ref) { + let index; + if (ref) { + index = this.childNodes.indexOf(ref); + if (index !== -1) index += 1; + } + this.insertChild(child, index); + } + + removeChild(child) { + const children = this.getChildren() || []; + const dataIndex = children.indexOf(child.data); + if (dataIndex > -1) { + children.splice(dataIndex, 1); + } + + const index = this.childNodes.indexOf(child); + + if (index > -1) { + this.store && this.store.deregisterNode(child); + child.parent = null; + this.childNodes.splice(index, 1); + } + + this.updateLeafState(); + } + + removeChildByData(data) { + let targetNode = null; + + for (let i = 0; i < this.childNodes.length; i++) { + if (this.childNodes[i].data === data) { + targetNode = this.childNodes[i]; + break; + } + } + + if (targetNode) { + this.removeChild(targetNode); + } + } + + expand(callback, expandParent) { + const done = () => { + if (expandParent) { + let parent = this.parent; + while (parent.level > 0) { + parent.expanded = true; + parent = parent.parent; + } + } + this.expanded = true; + if (callback) callback(); + }; + + if (this.shouldLoadData()) { + this.loadData((data) => { + if (data instanceof Array) { + if (this.checked) { + this.setChecked(true, true); + } else if (!this.store.checkStrictly) { + reInitChecked(this); + } + done(); + } + }); + } else { + done(); + } + } + + doCreateChildren(array, defaultProps = {}) { + array.forEach((item) => { + this.insertChild(objectAssign({ data: item }, defaultProps), undefined, true); + }); + } + + collapse() { + this.expanded = false; + } + + shouldLoadData() { + return this.store.lazy === true && this.store.load && !this.loaded; + } + + updateLeafState() { + if (this.store.lazy === true && this.loaded !== true && typeof this.isLeafByUser !== 'undefined') { + this.isLeaf = this.isLeafByUser; + return; + } + const childNodes = this.childNodes; + if (!this.store.lazy || (this.store.lazy === true && this.loaded === true)) { + this.isLeaf = !childNodes || childNodes.length === 0; + return; + } + this.isLeaf = false; + } + + setChecked(value, deep, recursion, passValue) { + this.indeterminate = value === 'half'; + this.checked = value === true; + + if (this.store.checkStrictly) return; + + if (!(this.shouldLoadData() && !this.store.checkDescendants)) { + let { all, allWithoutDisable } = getChildState(this.childNodes); + + if (!this.isLeaf && (!all && allWithoutDisable)) { + this.checked = false; + value = false; + } + + const handleDescendants = () => { + if (deep) { + const childNodes = this.childNodes; + for (let i = 0, j = childNodes.length; i < j; i++) { + const child = childNodes[i]; + passValue = passValue || value !== false; + const isCheck = child.disabled ? child.checked : passValue; + child.setChecked(isCheck, deep, true, passValue); + } + const { half, all } = getChildState(childNodes); + if (!all) { + this.checked = all; + this.indeterminate = half; + } + } + }; + + if (this.shouldLoadData()) { + // Only work on lazy load data. + this.loadData(() => { + handleDescendants(); + reInitChecked(this); + }, { + checked: value !== false + }); + return; + } else { + handleDescendants(); + } + } + + const parent = this.parent; + if (!parent || parent.level === 0) return; + + if (!recursion) { + reInitChecked(parent); + } + } + + getChildren(forceInit = false) { // this is data + if (this.level === 0) return this.data; + const data = this.data; + if (!data) return null; + + const props = this.store.props; + let children = 'children'; + if (props) { + children = props.children || 'children'; + } + + if (data[children] === undefined) { + data[children] = null; + } + + if (forceInit && !data[children]) { + data[children] = []; + } + + return data[children]; + } + + updateChildren() { + const newData = this.getChildren() || []; + const oldData = this.childNodes.map((node) => node.data); + + const newDataMap = {}; + const newNodes = []; + + newData.forEach((item, index) => { + const key = item[NODE_KEY]; + const isNodeExists = !!key && arrayFindIndex(oldData, data => data[NODE_KEY] === key) >= 0; + if (isNodeExists) { + newDataMap[key] = { index, data: item }; + } else { + newNodes.push({ index, data: item }); + } + }); + + if (!this.store.lazy) { + oldData.forEach((item) => { + if (!newDataMap[item[NODE_KEY]]) this.removeChildByData(item); + }); + } + + newNodes.forEach(({ index, data }) => { + this.insertChild({ data }, index); + }); + + this.updateLeafState(); + } + + loadData(callback, defaultProps = {}) { + if (this.store.lazy === true && this.store.load && !this.loaded && (!this.loading || Object.keys(defaultProps).length)) { + this.loading = true; + + const resolve = (children) => { + this.loaded = true; + this.loading = false; + this.childNodes = []; + + this.doCreateChildren(children, defaultProps); + + this.updateLeafState(); + if (callback) { + callback.call(this, children); + } + }; + + this.store.load(this, resolve); + } else { + if (callback) { + callback.call(this); + } + } + } +} diff --git a/packages/tree/src/model/tree-store.js b/packages/tree/src/model/tree-store.js new file mode 100644 index 0000000..d0bcd3e --- /dev/null +++ b/packages/tree/src/model/tree-store.js @@ -0,0 +1,340 @@ +import Node from './node'; +import { getNodeKey } from './util'; + +export default class TreeStore { + constructor(options) { + this.currentNode = null; + this.currentNodeKey = null; + + for (let option in options) { + if (options.hasOwnProperty(option)) { + this[option] = options[option]; + } + } + + this.nodesMap = {}; + + this.root = new Node({ + data: this.data, + store: this + }); + + if (this.lazy && this.load) { + const loadFn = this.load; + loadFn(this.root, (data) => { + this.root.doCreateChildren(data); + this._initDefaultCheckedNodes(); + }); + } else { + this._initDefaultCheckedNodes(); + } + } + + filter(value) { + const filterNodeMethod = this.filterNodeMethod; + const lazy = this.lazy; + const traverse = function(node) { + const childNodes = node.root ? node.root.childNodes : node.childNodes; + + childNodes.forEach((child) => { + child.visible = filterNodeMethod.call(child, value, child.data, child); + + traverse(child); + }); + + if (!node.visible && childNodes.length) { + let allHidden = true; + allHidden = !childNodes.some(child => child.visible); + + if (node.root) { + node.root.visible = allHidden === false; + } else { + node.visible = allHidden === false; + } + } + if (!value) return; + + if (node.visible && !node.isLeaf && !lazy) node.expand(); + }; + + traverse(this); + } + + setData(newVal) { + const instanceChanged = newVal !== this.root.data; + if (instanceChanged) { + this.root.setData(newVal); + this._initDefaultCheckedNodes(); + } else { + this.root.updateChildren(); + } + } + + getNode(data) { + if (data instanceof Node) return data; + const key = typeof data !== 'object' ? data : getNodeKey(this.key, data); + return this.nodesMap[key] || null; + } + + insertBefore(data, refData) { + const refNode = this.getNode(refData); + refNode.parent.insertBefore({ data }, refNode); + } + + insertAfter(data, refData) { + const refNode = this.getNode(refData); + refNode.parent.insertAfter({ data }, refNode); + } + + remove(data) { + const node = this.getNode(data); + + if (node && node.parent) { + if (node === this.currentNode) { + this.currentNode = null; + } + node.parent.removeChild(node); + } + } + + append(data, parentData) { + const parentNode = parentData ? this.getNode(parentData) : this.root; + + if (parentNode) { + parentNode.insertChild({ data }); + } + } + + _initDefaultCheckedNodes() { + const defaultCheckedKeys = this.defaultCheckedKeys || []; + const nodesMap = this.nodesMap; + + defaultCheckedKeys.forEach((checkedKey) => { + const node = nodesMap[checkedKey]; + + if (node) { + node.setChecked(true, !this.checkStrictly); + } + }); + } + + _initDefaultCheckedNode(node) { + const defaultCheckedKeys = this.defaultCheckedKeys || []; + + if (defaultCheckedKeys.indexOf(node.key) !== -1) { + node.setChecked(true, !this.checkStrictly); + } + } + + setDefaultCheckedKey(newVal) { + if (newVal !== this.defaultCheckedKeys) { + this.defaultCheckedKeys = newVal; + this._initDefaultCheckedNodes(); + } + } + + registerNode(node) { + const key = this.key; + if (!key || !node || !node.data) return; + + const nodeKey = node.key; + if (nodeKey !== undefined) this.nodesMap[node.key] = node; + } + + deregisterNode(node) { + const key = this.key; + if (!key || !node || !node.data) return; + + node.childNodes.forEach(child => { + this.deregisterNode(child); + }); + + delete this.nodesMap[node.key]; + } + + getCheckedNodes(leafOnly = false, includeHalfChecked = false) { + const checkedNodes = []; + const traverse = function(node) { + const childNodes = node.root ? node.root.childNodes : node.childNodes; + + childNodes.forEach((child) => { + if ((child.checked || (includeHalfChecked && child.indeterminate)) && (!leafOnly || (leafOnly && child.isLeaf))) { + checkedNodes.push(child.data); + } + + traverse(child); + }); + }; + + traverse(this); + + return checkedNodes; + } + + getCheckedKeys(leafOnly = false) { + return this.getCheckedNodes(leafOnly).map((data) => (data || {})[this.key]); + } + + getHalfCheckedNodes() { + const nodes = []; + const traverse = function(node) { + const childNodes = node.root ? node.root.childNodes : node.childNodes; + + childNodes.forEach((child) => { + if (child.indeterminate) { + nodes.push(child.data); + } + + traverse(child); + }); + }; + + traverse(this); + + return nodes; + } + + getHalfCheckedKeys() { + return this.getHalfCheckedNodes().map((data) => (data || {})[this.key]); + } + + _getAllNodes() { + const allNodes = []; + const nodesMap = this.nodesMap; + for (let nodeKey in nodesMap) { + if (nodesMap.hasOwnProperty(nodeKey)) { + allNodes.push(nodesMap[nodeKey]); + } + } + + return allNodes; + } + + updateChildren(key, data) { + const node = this.nodesMap[key]; + if (!node) return; + const childNodes = node.childNodes; + for (let i = childNodes.length - 1; i >= 0; i--) { + const child = childNodes[i]; + this.remove(child.data); + } + for (let i = 0, j = data.length; i < j; i++) { + const child = data[i]; + this.append(child, node.data); + } + } + + _setCheckedKeys(key, leafOnly = false, checkedKeys) { + const allNodes = this._getAllNodes().sort((a, b) => b.level - a.level); + const cache = Object.create(null); + const keys = Object.keys(checkedKeys); + allNodes.forEach(node => node.setChecked(false, false)); + for (let i = 0, j = allNodes.length; i < j; i++) { + const node = allNodes[i]; + const nodeKey = node.data[key].toString(); + let checked = keys.indexOf(nodeKey) > -1; + if (!checked) { + if (node.checked && !cache[nodeKey]) { + node.setChecked(false, false); + } + continue; + } + + let parent = node.parent; + while (parent && parent.level > 0) { + cache[parent.data[key]] = true; + parent = parent.parent; + } + + if (node.isLeaf || this.checkStrictly) { + node.setChecked(true, false); + continue; + } + node.setChecked(true, true); + + if (leafOnly) { + node.setChecked(false, false); + const traverse = function(node) { + const childNodes = node.childNodes; + childNodes.forEach((child) => { + if (!child.isLeaf) { + child.setChecked(false, false); + } + traverse(child); + }); + }; + traverse(node); + } + } + } + + setCheckedNodes(array, leafOnly = false) { + const key = this.key; + const checkedKeys = {}; + array.forEach((item) => { + checkedKeys[(item || {})[key]] = true; + }); + + this._setCheckedKeys(key, leafOnly, checkedKeys); + } + + setCheckedKeys(keys, leafOnly = false) { + this.defaultCheckedKeys = keys; + const key = this.key; + const checkedKeys = {}; + keys.forEach((key) => { + checkedKeys[key] = true; + }); + + this._setCheckedKeys(key, leafOnly, checkedKeys); + } + + setDefaultExpandedKeys(keys) { + keys = keys || []; + this.defaultExpandedKeys = keys; + + keys.forEach((key) => { + const node = this.getNode(key); + if (node) node.expand(null, this.autoExpandParent); + }); + } + + setChecked(data, checked, deep) { + const node = this.getNode(data); + + if (node) { + node.setChecked(!!checked, deep); + } + } + + getCurrentNode() { + return this.currentNode; + } + + setCurrentNode(currentNode) { + const prevCurrentNode = this.currentNode; + if (prevCurrentNode) { + prevCurrentNode.isCurrent = false; + } + this.currentNode = currentNode; + this.currentNode.isCurrent = true; + } + + setUserCurrentNode(node) { + const key = node[this.key]; + const currNode = this.nodesMap[key]; + this.setCurrentNode(currNode); + } + + setCurrentNodeKey(key) { + if (key === null || key === undefined) { + this.currentNode && (this.currentNode.isCurrent = false); + this.currentNode = null; + return; + } + const node = this.getNode(key); + if (node) { + this.setCurrentNode(node); + } + } +}; diff --git a/packages/tree/src/model/util.js b/packages/tree/src/model/util.js new file mode 100644 index 0000000..dcc891b --- /dev/null +++ b/packages/tree/src/model/util.js @@ -0,0 +1,27 @@ +export const NODE_KEY = '$treeNodeId'; + +export const markNodeData = function(node, data) { + if (!data || data[NODE_KEY]) return; + Object.defineProperty(data, NODE_KEY, { + value: node.id, + enumerable: false, + configurable: false, + writable: false + }); +}; + +export const getNodeKey = function(key, data) { + if (!key) return data[NODE_KEY]; + return data[key]; +}; + +export const findNearestComponent = (element, componentName) => { + let target = element; + while (target && target.tagName !== 'BODY') { + if (target.__vue__ && target.__vue__.$options.name === componentName) { + return target.__vue__; + } + target = target.parentNode; + } + return null; +}; diff --git a/packages/tree/src/tree-node.vue b/packages/tree/src/tree-node.vue new file mode 100644 index 0000000..3c922db --- /dev/null +++ b/packages/tree/src/tree-node.vue @@ -0,0 +1,279 @@ + + + diff --git a/packages/tree/src/tree.vue b/packages/tree/src/tree.vue new file mode 100644 index 0000000..5b1c1b4 --- /dev/null +++ b/packages/tree/src/tree.vue @@ -0,0 +1,496 @@ + + + diff --git a/packages/upload/index.js b/packages/upload/index.js new file mode 100644 index 0000000..d53883b --- /dev/null +++ b/packages/upload/index.js @@ -0,0 +1,8 @@ +import Upload from './src'; + +/* istanbul ignore next */ +Upload.install = function(Vue) { + Vue.component(Upload.name, Upload); +}; + +export default Upload; diff --git a/packages/upload/src/ajax.js b/packages/upload/src/ajax.js new file mode 100644 index 0000000..e5744c4 --- /dev/null +++ b/packages/upload/src/ajax.js @@ -0,0 +1,85 @@ +function getError(action, option, xhr) { + let msg; + if (xhr.response) { + msg = `${xhr.response.error || xhr.response}`; + } else if (xhr.responseText) { + msg = `${xhr.responseText}`; + } else { + msg = `fail to post ${action} ${xhr.status}`; + } + + const err = new Error(msg); + err.status = xhr.status; + err.method = 'post'; + err.url = action; + return err; +} + +function getBody(xhr) { + const text = xhr.responseText || xhr.response; + if (!text) { + return text; + } + + try { + return JSON.parse(text); + } catch (e) { + return text; + } +} + +export default function upload(option) { + if (typeof XMLHttpRequest === 'undefined') { + return; + } + + const xhr = new XMLHttpRequest(); + const action = option.action; + + if (xhr.upload) { + xhr.upload.onprogress = function progress(e) { + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + option.onProgress(e); + }; + } + + const formData = new FormData(); + + if (option.data) { + Object.keys(option.data).forEach(key => { + formData.append(key, option.data[key]); + }); + } + + formData.append(option.filename, option.file, option.file.name); + + xhr.onerror = function error(e) { + option.onError(e); + }; + + xhr.onload = function onload() { + if (xhr.status < 200 || xhr.status >= 300) { + return option.onError(getError(action, option, xhr)); + } + + option.onSuccess(getBody(xhr)); + }; + + xhr.open('post', action, true); + + if (option.withCredentials && 'withCredentials' in xhr) { + xhr.withCredentials = true; + } + + const headers = option.headers || {}; + + for (let item in headers) { + if (headers.hasOwnProperty(item) && headers[item] !== null) { + xhr.setRequestHeader(item, headers[item]); + } + } + xhr.send(formData); + return xhr; +} diff --git a/packages/upload/src/index.vue b/packages/upload/src/index.vue new file mode 100644 index 0000000..e735653 --- /dev/null +++ b/packages/upload/src/index.vue @@ -0,0 +1,338 @@ + diff --git a/packages/upload/src/upload-dragger.vue b/packages/upload/src/upload-dragger.vue new file mode 100644 index 0000000..b3293c6 --- /dev/null +++ b/packages/upload/src/upload-dragger.vue @@ -0,0 +1,70 @@ + + + diff --git a/packages/upload/src/upload-list.vue b/packages/upload/src/upload-list.vue new file mode 100644 index 0000000..7178d4f --- /dev/null +++ b/packages/upload/src/upload-list.vue @@ -0,0 +1,105 @@ + + diff --git a/packages/upload/src/upload.vue b/packages/upload/src/upload.vue new file mode 100644 index 0000000..200ca0a --- /dev/null +++ b/packages/upload/src/upload.vue @@ -0,0 +1,211 @@ + diff --git a/src/directives/mousewheel.js b/src/directives/mousewheel.js new file mode 100644 index 0000000..d8cbad5 --- /dev/null +++ b/src/directives/mousewheel.js @@ -0,0 +1,18 @@ +import normalizeWheel from 'normalize-wheel'; + +const isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1; + +const mousewheel = function(element, callback) { + if (element && element.addEventListener) { + element.addEventListener(isFirefox ? 'DOMMouseScroll' : 'mousewheel', function(event) { + const normalized = normalizeWheel(event); + callback && callback.apply(this, [event, normalized]); + }); + } +}; + +export default { + bind(el, binding) { + mousewheel(el, binding.value); + } +}; diff --git a/src/directives/repeat-click.js b/src/directives/repeat-click.js new file mode 100644 index 0000000..9aaef3a --- /dev/null +++ b/src/directives/repeat-click.js @@ -0,0 +1,24 @@ +import { once, on } from 'element-ui/src/utils/dom'; + +export default { + bind(el, binding, vnode) { + let interval = null; + let startTime; + const handler = () => vnode.context[binding.expression].apply(); + const clear = () => { + if (Date.now() - startTime < 100) { + handler(); + } + clearInterval(interval); + interval = null; + }; + + on(el, 'mousedown', (e) => { + if (e.button !== 0) return; + startTime = Date.now(); + once(document, 'mouseup', clear); + clearInterval(interval); + interval = setInterval(handler, 100); + }); + } +}; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..e2fa516 --- /dev/null +++ b/src/index.js @@ -0,0 +1,288 @@ +/* Automatically generated by './build/bin/build-entry.js' */ + +import Pagination from '../packages/pagination/index.js'; +import Dialog from '../packages/dialog/index.js'; +import Autocomplete from '../packages/autocomplete/index.js'; +import Dropdown from '../packages/dropdown/index.js'; +import DropdownMenu from '../packages/dropdown-menu/index.js'; +import DropdownItem from '../packages/dropdown-item/index.js'; +import Menu from '../packages/menu/index.js'; +import Submenu from '../packages/submenu/index.js'; +import MenuItem from '../packages/menu-item/index.js'; +import MenuItemGroup from '../packages/menu-item-group/index.js'; +import Input from '../packages/input/index.js'; +import InputNumber from '../packages/input-number/index.js'; +import Radio from '../packages/radio/index.js'; +import RadioGroup from '../packages/radio-group/index.js'; +import RadioButton from '../packages/radio-button/index.js'; +import Checkbox from '../packages/checkbox/index.js'; +import CheckboxButton from '../packages/checkbox-button/index.js'; +import CheckboxGroup from '../packages/checkbox-group/index.js'; +import Switch from '../packages/switch/index.js'; +import Select from '../packages/select/index.js'; +import Option from '../packages/option/index.js'; +import OptionGroup from '../packages/option-group/index.js'; +import Button from '../packages/button/index.js'; +import ButtonGroup from '../packages/button-group/index.js'; +import Table from '../packages/table/index.js'; +import TableColumn from '../packages/table-column/index.js'; +import DatePicker from '../packages/date-picker/index.js'; +import TimeSelect from '../packages/time-select/index.js'; +import TimePicker from '../packages/time-picker/index.js'; +import Popover from '../packages/popover/index.js'; +import Tooltip from '../packages/tooltip/index.js'; +import MessageBox from '../packages/message-box/index.js'; +import Breadcrumb from '../packages/breadcrumb/index.js'; +import BreadcrumbItem from '../packages/breadcrumb-item/index.js'; +import Form from '../packages/form/index.js'; +import FormItem from '../packages/form-item/index.js'; +import Tabs from '../packages/tabs/index.js'; +import TabPane from '../packages/tab-pane/index.js'; +import Tag from '../packages/tag/index.js'; +import Tree from '../packages/tree/index.js'; +import Alert from '../packages/alert/index.js'; +import Notification from '../packages/notification/index.js'; +import Slider from '../packages/slider/index.js'; +import Loading from '../packages/loading/index.js'; +import Icon from '../packages/icon/index.js'; +import Row from '../packages/row/index.js'; +import Col from '../packages/col/index.js'; +import Upload from '../packages/upload/index.js'; +import Progress from '../packages/progress/index.js'; +import Spinner from '../packages/spinner/index.js'; +import Message from '../packages/message/index.js'; +import Badge from '../packages/badge/index.js'; +import Card from '../packages/card/index.js'; +import Rate from '../packages/rate/index.js'; +import Steps from '../packages/steps/index.js'; +import Step from '../packages/step/index.js'; +import Carousel from '../packages/carousel/index.js'; +import Scrollbar from '../packages/scrollbar/index.js'; +import CarouselItem from '../packages/carousel-item/index.js'; +import Collapse from '../packages/collapse/index.js'; +import CollapseItem from '../packages/collapse-item/index.js'; +import Cascader from '../packages/cascader/index.js'; +import ColorPicker from '../packages/color-picker/index.js'; +import Transfer from '../packages/transfer/index.js'; +import Container from '../packages/container/index.js'; +import Header from '../packages/header/index.js'; +import Aside from '../packages/aside/index.js'; +import Main from '../packages/main/index.js'; +import Footer from '../packages/footer/index.js'; +import Timeline from '../packages/timeline/index.js'; +import TimelineItem from '../packages/timeline-item/index.js'; +import Link from '../packages/link/index.js'; +import Divider from '../packages/divider/index.js'; +import Image from '../packages/image/index.js'; +import Calendar from '../packages/calendar/index.js'; +import Backtop from '../packages/backtop/index.js'; +import InfiniteScroll from '../packages/infinite-scroll/index.js'; +import PageHeader from '../packages/page-header/index.js'; +import CascaderPanel from '../packages/cascader-panel/index.js'; +import Avatar from '../packages/avatar/index.js'; +import Drawer from '../packages/drawer/index.js'; +import Popconfirm from '../packages/popconfirm/index.js'; +import locale from 'element-ui/src/locale'; +import CollapseTransition from 'element-ui/src/transitions/collapse-transition'; + +const components = [ + Pagination, + Dialog, + Autocomplete, + Dropdown, + DropdownMenu, + DropdownItem, + Menu, + Submenu, + MenuItem, + MenuItemGroup, + Input, + InputNumber, + Radio, + RadioGroup, + RadioButton, + Checkbox, + CheckboxButton, + CheckboxGroup, + Switch, + Select, + Option, + OptionGroup, + Button, + ButtonGroup, + Table, + TableColumn, + DatePicker, + TimeSelect, + TimePicker, + Popover, + Tooltip, + Breadcrumb, + BreadcrumbItem, + Form, + FormItem, + Tabs, + TabPane, + Tag, + Tree, + Alert, + Slider, + Icon, + Row, + Col, + Upload, + Progress, + Spinner, + Badge, + Card, + Rate, + Steps, + Step, + Carousel, + Scrollbar, + CarouselItem, + Collapse, + CollapseItem, + Cascader, + ColorPicker, + Transfer, + Container, + Header, + Aside, + Main, + Footer, + Timeline, + TimelineItem, + Link, + Divider, + Image, + Calendar, + Backtop, + PageHeader, + CascaderPanel, + Avatar, + Drawer, + Popconfirm, + CollapseTransition +]; + +const install = function(Vue, opts = {}) { + locale.use(opts.locale); + locale.i18n(opts.i18n); + + components.forEach(component => { + Vue.component(component.name, component); + }); + + Vue.use(InfiniteScroll); + Vue.use(Loading.directive); + + Vue.prototype.$ELEMENT = { + size: opts.size || '', + zIndex: opts.zIndex || 2000 + }; + + Vue.prototype.$loading = Loading.service; + Vue.prototype.$msgbox = MessageBox; + Vue.prototype.$alert = MessageBox.alert; + Vue.prototype.$confirm = MessageBox.confirm; + Vue.prototype.$prompt = MessageBox.prompt; + Vue.prototype.$notify = Notification; + Vue.prototype.$message = Message; + +}; + +/* istanbul ignore if */ +if (typeof window !== 'undefined' && window.Vue) { + install(window.Vue); +} + +export default { + version: '2.15.1', + locale: locale.use, + i18n: locale.i18n, + install, + CollapseTransition, + Loading, + Pagination, + Dialog, + Autocomplete, + Dropdown, + DropdownMenu, + DropdownItem, + Menu, + Submenu, + MenuItem, + MenuItemGroup, + Input, + InputNumber, + Radio, + RadioGroup, + RadioButton, + Checkbox, + CheckboxButton, + CheckboxGroup, + Switch, + Select, + Option, + OptionGroup, + Button, + ButtonGroup, + Table, + TableColumn, + DatePicker, + TimeSelect, + TimePicker, + Popover, + Tooltip, + MessageBox, + Breadcrumb, + BreadcrumbItem, + Form, + FormItem, + Tabs, + TabPane, + Tag, + Tree, + Alert, + Notification, + Slider, + Icon, + Row, + Col, + Upload, + Progress, + Spinner, + Message, + Badge, + Card, + Rate, + Steps, + Step, + Carousel, + Scrollbar, + CarouselItem, + Collapse, + CollapseItem, + Cascader, + ColorPicker, + Transfer, + Container, + Header, + Aside, + Main, + Footer, + Timeline, + TimelineItem, + Link, + Divider, + Image, + Calendar, + Backtop, + InfiniteScroll, + PageHeader, + CascaderPanel, + Avatar, + Drawer, + Popconfirm +}; diff --git a/src/locale/format.js b/src/locale/format.js new file mode 100644 index 0000000..dacfa31 --- /dev/null +++ b/src/locale/format.js @@ -0,0 +1,46 @@ +import { hasOwn } from 'element-ui/src/utils/util'; + +const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g; +/** + * String format template + * - Inspired: + * https://github.com/Matt-Esch/string-template/index.js + */ +export default function(Vue) { + + /** + * template + * + * @param {String} string + * @param {Array} ...args + * @return {String} + */ + + function template(string, ...args) { + if (args.length === 1 && typeof args[0] === 'object') { + args = args[0]; + } + + if (!args || !args.hasOwnProperty) { + args = {}; + } + + return string.replace(RE_NARGS, (match, prefix, i, index) => { + let result; + + if (string[index - 1] === '{' && + string[index + match.length] === '}') { + return i; + } else { + result = hasOwn(args, i) ? args[i] : null; + if (result === null || result === undefined) { + return ''; + } + + return result; + } + }); + } + + return template; +} diff --git a/src/locale/index.js b/src/locale/index.js new file mode 100644 index 0000000..eabeb80 --- /dev/null +++ b/src/locale/index.js @@ -0,0 +1,48 @@ +import defaultLang from 'element-ui/src/locale/lang/zh-CN'; +import Vue from 'vue'; +import deepmerge from 'deepmerge'; +import Format from './format'; + +const format = Format(Vue); +let lang = defaultLang; +let merged = false; +let i18nHandler = function() { + const vuei18n = Object.getPrototypeOf(this || Vue).$t; + if (typeof vuei18n === 'function' && !!Vue.locale) { + if (!merged) { + merged = true; + Vue.locale( + Vue.config.lang, + deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true }) + ); + } + return vuei18n.apply(this, arguments); + } +}; + +export const t = function(path, options) { + let value = i18nHandler.apply(this, arguments); + if (value !== null && value !== undefined) return value; + + const array = path.split('.'); + let current = lang; + + for (let i = 0, j = array.length; i < j; i++) { + const property = array[i]; + value = current[property]; + if (i === j - 1) return format(value, options); + if (!value) return ''; + current = value; + } + return ''; +}; + +export const use = function(l) { + lang = l || lang; +}; + +export const i18n = function(fn) { + i18nHandler = fn || i18nHandler; +}; + +export default { use, t, i18n }; diff --git a/src/locale/lang/af-ZA.js b/src/locale/lang/af-ZA.js new file mode 100644 index 0000000..391be2e --- /dev/null +++ b/src/locale/lang/af-ZA.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Bevestig', + clear: 'Maak skoon' + }, + datepicker: { + now: 'Nou', + today: 'Vandag', + cancel: 'Kanselleer', + clear: 'Maak skoon', + confirm: 'Bevestig', + selectDate: 'Kies datum', + selectTime: 'Kies tyd', + startDate: 'Begindatum', + startTime: 'Begintyd', + endDate: 'Einddatum', + endTime: 'Eindtyd', + prevYear: 'Previous Year', // to be translated + nextYear: 'Next Year', // to be translated + prevMonth: 'Previous Month', // to be translated + nextMonth: 'Next Month', // to be translated + year: 'Jaar', + month1: 'Jan', + month2: 'Feb', + month3: 'Mrt', + month4: 'Apr', + month5: 'Mei', + month6: 'Jun', + month7: 'Jul', + month8: 'Aug', + month9: 'Sep', + month10: 'Okt', + month11: 'Nov', + month12: 'Des', + // week: 'week', + weeks: { + sun: 'So', + mon: 'Ma', + tue: 'Di', + wed: 'Wo', + thu: 'Do', + fri: 'Vr', + sat: 'Sa' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mrt', + apr: 'Apr', + may: 'Mei', + jun: 'Jun', + jul: 'Jul', + aug: 'Aug', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Des' + } + }, + select: { + loading: 'Laai', + noMatch: 'Geen toepaslike data', + noData: 'Geen data', + placeholder: 'Kies' + }, + cascader: { + noMatch: 'Geen toepaslike data', + loading: 'Laai', + placeholder: 'Kies', + noData: 'Geen data' + }, + pagination: { + goto: 'Gaan na', + pagesize: '/page', + total: 'Totaal {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Boodskap', + confirm: 'Bevestig', + cancel: 'Kanselleer', + error: 'Ongeldige invoer' + }, + upload: { + deleteTip: 'press delete to remove', // to be translated + delete: 'Verwyder', + preview: 'Voorskou', + continue: 'Gaan voort' + }, + table: { + emptyText: 'Geen Data', + confirmFilter: 'Bevestig', + resetFilter: 'Herstel', + clearFilter: 'Alles', + sumText: 'Som' + }, + tree: { + emptyText: 'Geen Data' + }, + transfer: { + noMatch: 'Geen toepaslike data', + noData: 'Geen data', + titles: ['Lys 1', 'Lys 2'], + filterPlaceholder: 'Voer sleutelwoord in', + noCheckedFormat: '{total} items', + hasCheckedFormat: '{checked}/{total} gekies' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/ar.js b/src/locale/lang/ar.js new file mode 100644 index 0000000..401913f --- /dev/null +++ b/src/locale/lang/ar.js @@ -0,0 +1,119 @@ +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: 'إختر', + noData: 'لايوجد بيانات' + }, + pagination: { + goto: 'أذهب إلى', + pagesize: '/صفحة', + total: 'الكل {total}', + pageClassifier: '' + }, + messagebox: { + title: 'العنوان', + confirm: 'موافق', + cancel: 'إلغاء', + error: 'مدخل غير صحيح' + }, + upload: { + delete: 'حذف', + preview: 'عرض', + continue: 'إستمرار' + }, + table: { + emptyText: 'لايوجد بيانات', + confirmFilter: 'تأكيد', + resetFilter: 'حذف', + clearFilter: 'الكل', + sumText: 'المجموع' + }, + tree: { + emptyText: 'لايوجد بيانات' + }, + transfer: { + noMatch: 'لايوجد بيانات مطابقة', + noData: 'لايوجد بيانات', + titles: ['قائمة 1', 'قائمة 2'], + filterPlaceholder: 'ادخل كلمة', + noCheckedFormat: '{total} عناصر', + hasCheckedFormat: '{checked}/{total} مختار' + }, + image: { + error: 'فشل' + }, + pageHeader: { + title: 'عودة' + }, + popconfirm: { + confirmButtonText: 'تأكيد', + cancelButtonText: 'إلغاء' + } + } +}; diff --git a/src/locale/lang/bg.js b/src/locale/lang/bg.js new file mode 100644 index 0000000..fb5b7bf --- /dev/null +++ b/src/locale/lang/bg.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Изчисти' + }, + datepicker: { + now: 'Сега', + today: 'Днес', + cancel: 'Откажи', + 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 + 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: 'Избери', + noData: 'Няма данни' + }, + pagination: { + goto: 'Иди на', + pagesize: '/страница', + total: 'Общо {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Съобщение', + confirm: 'ОК', + cancel: 'Откажи', + error: 'Невалидни данни' + }, + upload: { + deleteTip: 'press delete to remove', // to be translated + delete: 'Изтрий', + preview: 'Прегледай', + continue: 'Продължи' + }, + table: { + emptyText: 'Няма данни', + confirmFilter: 'Потвърди', + resetFilter: 'Изчисти', + clearFilter: 'Всички', + sumText: 'Sum' // to be translated + }, + tree: { + emptyText: 'Няма данни' + }, + transfer: { + noMatch: 'Няма намерени', + noData: 'Няма данни', + titles: ['List 1', 'List 2'], // to be translated + filterPlaceholder: 'Enter keyword', // to be translated + noCheckedFormat: '{total} items', // to be translated + hasCheckedFormat: '{checked}/{total} checked' // to be translated + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/ca.js b/src/locale/lang/ca.js new file mode 100644 index 0000000..9b82bc6 --- /dev/null +++ b/src/locale/lang/ca.js @@ -0,0 +1,119 @@ +export default { + el: { + colorpicker: { + confirm: 'Confirmar', + clear: 'Netejar' + }, + datepicker: { + now: 'Ara', + today: 'Avui', + cancel: 'Cancel·lar', + clear: 'Netejar', + confirm: 'Confirmar', + selectDate: 'Seleccionar data', + selectTime: 'Seleccionar hora', + startDate: 'Data Inici', + startTime: 'Hora Inici', + endDate: 'Data Final', + endTime: 'Hora Final', + prevYear: 'Any anterior', + nextYear: 'Pròxim Any', + prevMonth: 'Mes anterior', + nextMonth: 'Pròxim Mes', + year: '', + month1: 'Gener', + month2: 'Febrer', + month3: 'Març', + month4: 'Abril', + month5: 'Maig', + month6: 'Juny', + month7: 'Juliol', + month8: 'Agost', + month9: 'Setembre', + month10: 'Octubre', + month11: 'Novembre', + month12: 'Desembre', + // week: 'setmana', + weeks: { + sun: 'Dg', + mon: 'Dl', + tue: 'Dt', + wed: 'Dc', + thu: 'Dj', + fri: 'Dv', + sat: 'Ds' + }, + months: { + jan: 'Gen', + feb: 'Febr', + mar: 'Març', + apr: 'Abr', + may: 'Maig', + jun: 'Juny', + jul: 'Jul', + aug: 'Ag', + sep: 'Set', + oct: 'Oct', + nov: 'Nov', + dec: 'Des' + } + }, + select: { + loading: 'Carregant', + noMatch: 'No hi ha dades que coincideixin', + noData: 'Sense Dades', + placeholder: 'Seleccionar' + }, + cascader: { + noMatch: 'No hi ha dades que coincideixin', + loading: 'Carregant', + placeholder: 'Seleccionar', + noData: 'Sense Dades' + }, + pagination: { + goto: 'Anar a', + pagesize: '/pagina', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + confirm: 'Acceptar', + cancel: 'Cancel·lar', + error: 'Entrada invàlida' + }, + upload: { + deleteTip: 'premi eliminar per descartar', + delete: 'Eliminar', + preview: 'Vista Prèvia', + continue: 'Continuar' + }, + table: { + emptyText: 'Sense Dades', + confirmFilter: 'Confirmar', + resetFilter: 'Netejar', + clearFilter: 'Tot', + sumText: 'Tot' + }, + tree: { + emptyText: 'Sense Dades' + }, + transfer: { + noMatch: 'No hi ha dades que coincideixin', + noData: 'Sense Dades', + titles: ['Llista 1', 'Llista 2'], + filterPlaceholder: 'Introdueix la paraula clau', + noCheckedFormat: '{total} ítems', + hasCheckedFormat: '{checked}/{total} seleccionats' + }, + image: { + error: 'HA FALLAT' + }, + pageHeader: { + title: 'Tornar' + }, + popconfirm: { + confirmButtonText: 'Si', + cancelButtonText: 'No' + } + } +}; diff --git a/src/locale/lang/cs-CZ.js b/src/locale/lang/cs-CZ.js new file mode 100644 index 0000000..a2e19ba --- /dev/null +++ b/src/locale/lang/cs-CZ.js @@ -0,0 +1,122 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Vymazat' + }, + datepicker: { + now: 'Teď', + today: 'Dnes', + cancel: 'Zrušit', + clear: 'Vymazat', + confirm: 'OK', + selectDate: 'Vybrat datum', + selectTime: 'Vybrat čas', + startDate: 'Datum začátku', + startTime: 'Čas začátku', + endDate: 'Datum konce', + endTime: 'Čas konce', + prevYear: 'Předchozí rok', + nextYear: 'Příští rok', + prevMonth: 'Předchozí měsíc', + nextMonth: 'Příští měsíc', + day: 'Den', + week: 'Týden', + month: 'Měsíc', + year: 'Rok', + month1: 'Leden', + month2: 'Únor', + month3: 'Březen', + month4: 'Duben', + month5: 'Květen', + month6: 'Červen', + month7: 'Červenec', + month8: 'Srpen', + month9: 'Září', + month10: 'Říjen', + month11: 'Listopad', + month12: 'Prosinec', + weeks: { + sun: 'Ne', + mon: 'Po', + tue: 'Út', + wed: 'St', + thu: 'Čt', + fri: 'Pá', + sat: 'So' + }, + months: { + jan: 'Led', + feb: 'Úno', + mar: 'Bře', + apr: 'Dub', + may: 'Kvě', + jun: 'Čer', + jul: 'Čvc', + aug: 'Srp', + sep: 'Zář', + oct: 'Říj', + nov: 'Lis', + dec: 'Pro' + } + }, + select: { + loading: 'Načítání', + noMatch: 'Žádná shoda', + noData: 'Žádná data', + placeholder: 'Vybrat' + }, + cascader: { + noMatch: 'Žádná shoda', + loading: 'Načítání', + placeholder: 'Vybrat', + noData: 'Žádná data' + }, + pagination: { + goto: 'Jít na', + pagesize: 'na stranu', + total: 'Celkem {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Zpráva', + confirm: 'OK', + cancel: 'Zrušit', + error: 'Neplatný vstup' + }, + upload: { + deleteTip: 'Stisknout pro smazání', + delete: 'Vymazat', + preview: 'Náhled', + continue: 'Pokračovat' + }, + table: { + emptyText: 'Žádná data', + confirmFilter: 'Potvrdit', + resetFilter: 'Resetovat', + clearFilter: 'Vše', + sumText: 'Celkem' + }, + tree: { + emptyText: 'Žádná data' + }, + transfer: { + noMatch: 'Žádná shoda', + noData: 'Žádná data', + titles: ['Seznam 1', 'Seznam 2'], + filterPlaceholder: 'Klíčové slovo', + noCheckedFormat: '{total} položek', + hasCheckedFormat: '{checked}/{total} vybráno' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/da.js b/src/locale/lang/da.js new file mode 100644 index 0000000..35a25d7 --- /dev/null +++ b/src/locale/lang/da.js @@ -0,0 +1,119 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Ryd' + }, + datepicker: { + now: 'Nu', + today: 'I dag', + cancel: 'Annuller', + clear: 'Ryd', + confirm: 'OK', + selectDate: 'Vælg dato', + selectTime: 'Vælg tidspunkt', + startDate: 'Startdato', + startTime: 'Starttidspunkt', + endDate: 'Slutdato', + endTime: 'Sluttidspunkt', + prevYear: 'Forrige år', + nextYear: 'Næste år', + prevMonth: 'Forrige måned', + nextMonth: 'Næste måned', + year: '', + month1: 'Januar', + month2: 'Februar', + month3: 'Marts', + month4: 'April', + month5: 'Maj', + month6: 'Juni', + month7: 'Juli', + month8: 'August', + month9: 'September', + month10: 'Oktober', + month11: 'November', + month12: 'December', + week: 'uge', + weeks: { + sun: 'Søn', + mon: 'Man', + tue: 'Tir', + wed: 'Ons', + thu: 'Tor', + fri: 'Fre', + sat: 'Lør' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Maj', + jun: 'Jun', + jul: 'Jul', + aug: 'Aug', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Dec' + } + }, + select: { + loading: 'Henter', + noMatch: 'Ingen matchende data', + noData: 'Ingen data', + placeholder: 'Vælg' + }, + cascader: { + noMatch: 'Ingen matchende data', + loading: 'Henter', + placeholder: 'Vælg', + noData: 'Ingen data' + }, + pagination: { + goto: 'Gå til', + pagesize: '/side', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + confirm: 'OK', + cancel: 'Annuller', + error: 'Ugyldig input' + }, + upload: { + deleteTip: 'tryk slet for at fjerne', + delete: 'Slet', + preview: 'Forhåndsvisning', + continue: 'Fortsæt' + }, + table: { + emptyText: 'Ingen data', + confirmFilter: 'Bekræft', + resetFilter: 'Nulstil', + clearFilter: 'Alle', + sumText: 'Sum' + }, + tree: { + emptyText: 'Ingen data' + }, + transfer: { + noMatch: 'Ingen matchende data', + noData: 'Ingen data', + titles: ['Liste 1', 'Liste 2'], + filterPlaceholder: 'Indtast søgeord', + noCheckedFormat: '{total} emner', + hasCheckedFormat: '{checked}/{total} valgt' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/de.js b/src/locale/lang/de.js new file mode 100644 index 0000000..a3ad3d5 --- /dev/null +++ b/src/locale/lang/de.js @@ -0,0 +1,121 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Leeren' + }, + datepicker: { + now: 'Jetzt', + today: 'Heute', + cancel: 'Abbrechen', + clear: 'Leeren', + confirm: 'OK', + selectDate: 'Datum wählen', + selectTime: 'Uhrzeit wählen', + startDate: 'Startdatum', + startTime: 'Startzeit', + endDate: 'Enddatum', + endTime: 'Endzeit', + prevYear: 'Letztes Jahr', + nextYear: 'Nächtes Jahr', + prevMonth: 'Letzter Monat', + nextMonth: 'Nächster Monat', + day: 'Tag', + week: 'Woche', + month: 'Monat', + year: '', + month1: 'Januar', + month2: 'Februar', + month3: 'März', + month4: 'April', + month5: 'Mai', + month6: 'Juni', + month7: 'Juli', + month8: 'August', + month9: 'September', + month10: 'Oktober', + month11: 'November', + month12: 'Dezember', + weeks: { + sun: 'So', + mon: 'Mo', + tue: 'Di', + wed: 'Mi', + thu: 'Do', + fri: 'Fr', + sat: 'Sa' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mär', + apr: 'Apr', + may: 'Mai', + jun: 'Jun', + jul: 'Jul', + aug: 'Aug', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Dez' + } + }, + select: { + loading: 'Lädt.', + noMatch: 'Nichts gefunden.', + noData: 'Keine Daten', + placeholder: 'Daten wählen' + }, + cascader: { + noMatch: 'Nichts gefunden.', + loading: 'Lädt.', + placeholder: 'Daten wählen', + noData: 'Keine Daten' + }, + pagination: { + goto: 'Gehe zu', + pagesize: ' pro Seite', + total: 'Gesamt {total}', + pageClassifier: '' + }, + messagebox: { + confirm: 'OK', + cancel: 'Abbrechen', + error: 'Fehler' + }, + upload: { + deleteTip: 'Klicke löschen zum entfernen', + delete: 'Löschen', + preview: 'Vorschau', + continue: 'Fortsetzen' + }, + table: { + emptyText: 'Keine Daten', + confirmFilter: 'Anwenden', + resetFilter: 'Zurücksetzen', + clearFilter: 'Alles ', + sumText: 'Summe' + }, + tree: { + emptyText: 'Keine Einträge' + }, + transfer: { + noMatch: 'Nichts gefunden.', + noData: 'Keine Einträge', + titles: ['Liste 1', 'Liste 2'], + filterPlaceholder: 'Einträge filtern', + noCheckedFormat: '{total} Einträge', + hasCheckedFormat: '{checked}/{total} ausgewählt' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/ee.js b/src/locale/lang/ee.js new file mode 100644 index 0000000..d9d4914 --- /dev/null +++ b/src/locale/lang/ee.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Tühjenda' + }, + datepicker: { + now: 'Praegu', + today: 'Täna', + cancel: 'Tühista', + clear: 'Tühjenda', + confirm: 'OK', + selectDate: 'Vali kuupäev', + selectTime: 'Vali kellaaeg', + startDate: 'Alguskuupäev', + startTime: 'Algusaeg', + endDate: 'Lõpukuupäev', + endTime: 'Lõpuaeg', + prevYear: 'Eelmine aasta', + nextYear: 'Järgmine aasta', + prevMonth: 'Eelmine kuu', + nextMonth: 'Järgmine kuu', + year: '', + month1: 'Jaanuar', + month2: 'Veebruar', + month3: 'Märts', + month4: 'Aprill', + month5: 'Mai', + month6: 'Juuni', + month7: 'Juuli', + month8: 'August', + month9: 'September', + month10: 'Oktoober', + month11: 'November', + month12: 'Detsember', + // week: 'nädal', + weeks: { + sun: 'P', + mon: 'E', + tue: 'T', + wed: 'K', + thu: 'N', + fri: 'R', + sat: 'L' + }, + months: { + jan: 'Jaan', + feb: 'Veeb', + mar: 'Mär', + apr: 'Apr', + may: 'Mai', + jun: 'Juun', + jul: 'Juul', + aug: 'Aug', + sep: 'Sept', + oct: 'Okt', + nov: 'Nov', + dec: 'Dets' + } + }, + select: { + loading: 'Laadimine', + noMatch: 'Sobivad andmed puuduvad', + noData: 'Andmed puuduvad', + placeholder: 'Vali' + }, + cascader: { + noMatch: 'Sobivad andmed puuduvad', + loading: 'Laadimine', + placeholder: 'Vali', + noData: 'Andmed puuduvad' + }, + pagination: { + goto: 'Mine lehele', + pagesize: '/page', + total: 'Kokku {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Teade', + confirm: 'OK', + cancel: 'Tühista', + error: 'Vigane sisend' + }, + upload: { + deleteTip: 'Vajuta "Kustuta", et eemaldada', + delete: 'Kustuta', + preview: 'Eelvaate', + continue: 'Jätka' + }, + table: { + emptyText: 'Andmed puuduvad', + confirmFilter: 'Kinnita', + resetFilter: 'Taasta', + clearFilter: 'Kõik', + sumText: 'Summa' + }, + tree: { + emptyText: 'Andmed puuduvad' + }, + transfer: { + noMatch: 'Sobivad andmed puuduvad', + noData: 'Andmed puuduvad', + titles: ['Loend 1', 'Loend 2'], + filterPlaceholder: 'Sisesta märksõna', + noCheckedFormat: '{total} objekti', + hasCheckedFormat: '{checked}/{total} valitud' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/el.js b/src/locale/lang/el.js new file mode 100644 index 0000000..8722a69 --- /dev/null +++ b/src/locale/lang/el.js @@ -0,0 +1,120 @@ +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: 'Επιλογή', + noData: 'Χωρίς δεδομένα' + }, + 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} επιλεγμένα' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/en.js b/src/locale/lang/en.js new file mode 100644 index 0000000..b096f42 --- /dev/null +++ b/src/locale/lang/en.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Clear' + }, + datepicker: { + now: 'Now', + today: 'Today', + cancel: 'Cancel', + clear: 'Clear', + confirm: 'OK', + selectDate: 'Select date', + selectTime: 'Select time', + startDate: 'Start Date', + startTime: 'Start Time', + endDate: 'End Date', + endTime: 'End Time', + prevYear: 'Previous Year', + nextYear: 'Next Year', + prevMonth: 'Previous Month', + nextMonth: 'Next Month', + year: '', + month1: 'January', + month2: 'February', + month3: 'March', + month4: 'April', + month5: 'May', + month6: 'June', + month7: 'July', + month8: 'August', + month9: 'September', + month10: 'October', + month11: 'November', + month12: 'December', + week: 'week', + weeks: { + sun: 'Sun', + mon: 'Mon', + tue: 'Tue', + wed: 'Wed', + thu: 'Thu', + fri: 'Fri', + sat: 'Sat' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'May', + jun: 'Jun', + jul: 'Jul', + aug: 'Aug', + sep: 'Sep', + oct: 'Oct', + nov: 'Nov', + dec: 'Dec' + } + }, + select: { + loading: 'Loading', + noMatch: 'No matching data', + noData: 'No data', + placeholder: 'Select' + }, + cascader: { + noMatch: 'No matching data', + loading: 'Loading', + placeholder: 'Select', + noData: 'No data' + }, + pagination: { + goto: 'Go to', + pagesize: '/page', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Message', + confirm: 'OK', + cancel: 'Cancel', + error: 'Illegal input' + }, + upload: { + deleteTip: 'press delete to remove', + delete: 'Delete', + preview: 'Preview', + continue: 'Continue' + }, + table: { + emptyText: 'No Data', + confirmFilter: 'Confirm', + resetFilter: 'Reset', + clearFilter: 'All', + sumText: 'Sum' + }, + tree: { + emptyText: 'No Data' + }, + transfer: { + noMatch: 'No matching data', + noData: 'No 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 + }, + image: { + error: 'FAILED' + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', + cancelButtonText: 'No' + } + } +}; diff --git a/src/locale/lang/eo.js b/src/locale/lang/eo.js new file mode 100644 index 0000000..da1d8de --- /dev/null +++ b/src/locale/lang/eo.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Bone', + clear: 'Malplenigi' + }, + datepicker: { + now: 'Nun', + today: 'Hodiaŭ', + cancel: 'Nuligi', + clear: 'Malplenigi', + confirm: 'Bone', + selectDate: 'Elektu daton', + selectTime: 'Elektu horon', + startDate: 'Komenca Dato', + startTime: 'Komenca Horo', + endDate: 'Fina Dato', + endTime: 'Fina Horo', + prevYear: 'Antaŭa Jaro', + nextYear: 'Sekva Jaro', + prevMonth: 'Antaŭa Monato', + nextMonth: 'Sekva Monato', + year: 'Jaro', + month1: 'Januaro', + month2: 'Februaro', + month3: 'Marto', + month4: 'Aprilo', + month5: 'Majo', + month6: 'Junio', + month7: 'Julio', + month8: 'Aŭgusto', + month9: 'Septembro', + month10: 'Oktobro', + month11: 'Novembro', + month12: 'Decembro', + week: 'Semajno', + weeks: { + sun: 'Dim', + mon: 'Lun', + tue: 'Mar', + wed: 'Mer', + thu: 'Ĵaŭ', + fri: 'Ven', + sat: 'Sab' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Maj', + jun: 'Jun', + jul: 'Jul', + aug: 'Aŭg', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Dec' + } + }, + select: { + loading: 'Ŝarĝante', + noMatch: 'Neniuj kongruaj datumoj', + noData: 'Neniuj datumoj', + placeholder: 'Bonvolu elekti' + }, + cascader: { + noMatch: 'Neniuj kongruaj datumoj', + loading: 'Ŝarĝante', + placeholder: 'Bonvolu elekti', + noData: 'Neniuj datumoj' + }, + pagination: { + goto: 'Iru al', + pagesize: '/ paĝo', + total: 'Entute {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Mesaĝo', + confirm: 'Bone', + cancel: 'Nuligi', + error: 'Nevalida Enigo!' + }, + upload: { + deleteTip: 'Premu "Delete" por forigi', + delete: 'Forigi', + preview: 'Antaŭrigardi', + continue: 'Daŭrigi' + }, + table: { + emptyText: 'Neniuj datumoj', + confirmFilter: 'Konfirmi', + resetFilter: 'Restarigi', + clearFilter: 'Ĉiuj', + sumText: 'Sumo' + }, + tree: { + emptyText: 'Neniuj datumoj' + }, + transfer: { + noMatch: 'Neniuj kongruaj datumoj', + noData: 'Neniuj datumoj', + titles: ['Listo 1', 'Listo 2'], + filterPlaceholder: 'Enigu ŝlosilvorton', + noCheckedFormat: '{total} elementoj', + hasCheckedFormat: '{checked}/{total} elektitaj' + }, + image: { + error: 'MALSUKCESIS' + }, + pageHeader: { + title: 'Reen' + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/es.js b/src/locale/lang/es.js new file mode 100644 index 0000000..8a19eef --- /dev/null +++ b/src/locale/lang/es.js @@ -0,0 +1,119 @@ +export default { + el: { + colorpicker: { + confirm: 'Confirmar', + clear: 'Despejar' + }, + datepicker: { + now: 'Ahora', + today: 'Hoy', + cancel: 'Cancelar', + clear: 'Despejar', + confirm: 'Confirmar', + selectDate: 'Seleccionar fecha', + selectTime: 'Seleccionar hora', + startDate: 'Fecha Incial', + startTime: 'Hora Inicial', + endDate: 'Fecha Final', + endTime: 'Hora Final', + prevYear: 'Año Anterior', + nextYear: 'Próximo Año', + prevMonth: 'Mes Anterior', + nextMonth: 'Próximo Mes', + year: '', + month1: 'enero', + month2: 'febrero', + month3: 'marzo', + month4: 'abril', + month5: 'mayo', + month6: 'junio', + month7: 'julio', + month8: 'agosto', + month9: 'septiembre', + month10: 'octubre', + month11: 'noviembre', + month12: 'diciembre', + // week: 'semana', + weeks: { + sun: 'dom', + mon: 'lun', + tue: 'mar', + wed: 'mié', + thu: 'jue', + fri: 'vie', + sat: 'sáb' + }, + months: { + jan: 'ene', + feb: 'feb', + mar: 'mar', + apr: 'abr', + may: 'may', + jun: 'jun', + jul: 'jul', + aug: 'ago', + sep: 'sep', + oct: 'oct', + nov: 'nov', + dec: 'dic' + } + }, + select: { + loading: 'Cargando', + noMatch: 'No hay datos que coincidan', + noData: 'Sin datos', + placeholder: 'Seleccionar' + }, + cascader: { + noMatch: 'No hay datos que coincidan', + loading: 'Cargando', + placeholder: 'Seleccionar', + noData: 'Sin datos' + }, + pagination: { + goto: 'Ir a', + pagesize: '/página', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + confirm: 'Aceptar', + cancel: 'Cancelar', + error: 'Entrada inválida' + }, + upload: { + deleteTip: 'Pulse Eliminar para retirar', + delete: 'Eliminar', + preview: 'Vista Previa', + continue: 'Continuar' + }, + table: { + emptyText: 'Sin Datos', + confirmFilter: 'Confirmar', + resetFilter: 'Reiniciar', + clearFilter: 'Despejar', + sumText: 'Suma' + }, + tree: { + emptyText: 'Sin Datos' + }, + transfer: { + noMatch: 'No hay datos que coincidan', + noData: 'Sin datos', + titles: ['Lista 1', 'Lista 2'], + filterPlaceholder: 'Ingresar palabra clave', + noCheckedFormat: '{total} artículos', + hasCheckedFormat: '{checked}/{total} revisados' + }, + image: { + error: 'HA FALLADO' + }, + pageHeader: { + title: 'Volver' + }, + popconfirm: { + confirmButtonText: 'Si', + cancelButtonText: 'No' + } + } +}; diff --git a/src/locale/lang/eu.js b/src/locale/lang/eu.js new file mode 100644 index 0000000..7da9aa4 --- /dev/null +++ b/src/locale/lang/eu.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Ados', + clear: 'Garbitu' + }, + datepicker: { + now: 'Orain', + today: 'Gaur', + cancel: 'Utzi', + clear: 'Garbitu', + confirm: 'Ados', + selectDate: 'Hautatu data', + selectTime: 'Hautatu ordua', + startDate: 'Hasierako data', + startTime: 'Hasierako ordua', + endDate: 'Amaierako data', + endTime: 'Amaierako ordua', + prevYear: 'Aurreko urtea', + nextYear: 'Hurrengo urtea', + prevMonth: 'Aurreko hilabetea', + nextMonth: 'Hurrengo hilabetea', + year: '', + month1: 'Urtarrila', + month2: 'Otsaila', + month3: 'Martxoa', + month4: 'Apirila', + month5: 'Maiatza', + month6: 'Ekaina', + month7: 'Uztaila', + month8: 'Abuztua', + month9: 'Iraila', + month10: 'Urria', + month11: 'Azaroa', + month12: 'Abendua', + // week: 'astea', + weeks: { + sun: 'ig.', + mon: 'al.', + tue: 'ar.', + wed: 'az.', + thu: 'og.', + fri: 'ol.', + sat: 'lr.' + }, + months: { + jan: 'urt', + feb: 'ots', + mar: 'mar', + apr: 'api', + may: 'mai', + jun: 'eka', + jul: 'uzt', + aug: 'abu', + sep: 'ira', + oct: 'urr', + nov: 'aza', + dec: 'abe' + } + }, + select: { + loading: 'Kargatzen', + noMatch: 'Bat datorren daturik ez', + noData: 'Daturik ez', + placeholder: 'Hautatu' + }, + cascader: { + noMatch: 'Bat datorren daturik ez', + loading: 'Kargatzen', + placeholder: 'Hautatu', + noData: 'Daturik ez' + }, + pagination: { + goto: 'Joan', + pagesize: '/orria', + total: 'Guztira {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Mezua', + confirm: 'Ados', + cancel: 'Utzi', + error: 'Sarrera baliogabea' + }, + upload: { + deleteTip: 'sakatu Ezabatu kentzeko', + delete: 'Ezabatu', + preview: 'Aurrebista', + continue: 'Jarraitu' + }, + table: { + emptyText: 'Daturik ez', + confirmFilter: 'Baieztatu', + resetFilter: 'Berrezarri', + clearFilter: 'Guztia', + sumText: 'Batura' + }, + tree: { + emptyText: 'Daturik ez' + }, + transfer: { + noMatch: 'Bat datorren daturik ez', + noData: 'Daturik ez', + titles: ['Zerrenda 1', 'Zerrenda 2'], // to be translated + filterPlaceholder: 'Sartu gako-hitza', // to be translated + noCheckedFormat: '{total} elementu', // to be translated + hasCheckedFormat: '{checked}/{total} hautatuta' // to be translated + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/fa.js b/src/locale/lang/fa.js new file mode 100644 index 0000000..3e00457 --- /dev/null +++ b/src/locale/lang/fa.js @@ -0,0 +1,120 @@ +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: '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: 'انتخاب کنید', + noData: 'اطلاعاتی وجود ندارد' + }, + 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} مورد انتخاب شده است' + }, + image: { + error: 'خطا در بارگیری تصویر' + }, + pageHeader: { + title: 'بازگشت' + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/fi.js b/src/locale/lang/fi.js new file mode 100644 index 0000000..9f1e7c7 --- /dev/null +++ b/src/locale/lang/fi.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Tyhjennä' + }, + datepicker: { + now: 'Nyt', + today: 'Tänään', + cancel: 'Peruuta', + clear: 'Tyhjennä', + confirm: 'OK', + selectDate: 'Valitse päivä', + selectTime: 'Valitse aika', + startDate: 'Aloituspäivä', + startTime: 'Aloitusaika', + endDate: 'Lopetuspäivä', + endTime: 'Lopetusaika', + prevYear: 'Edellinen vuosi', + nextYear: 'Seuraava vuosi', + prevMonth: 'Edellinen kuukausi', + nextMonth: 'Seuraava kuukausi', + year: '', + month1: 'tammikuu', + month2: 'helmikuu', + month3: 'maaliskuu', + month4: 'huhtikuu', + month5: 'toukokuu', + month6: 'kesäkuu', + month7: 'heinäkuu', + month8: 'elokuu', + month9: 'syyskuu', + month10: 'lokakuu', + month11: 'marraskuu', + month12: 'joulukuu', + // week: 'week', + weeks: { + sun: 'su', + mon: 'ma', + tue: 'ti', + wed: 'ke', + thu: 'to', + fri: 'pe', + sat: 'la' + }, + months: { + jan: 'tammi', + feb: 'helmi', + mar: 'maalis', + apr: 'huhti', + may: 'touko', + jun: 'kesä', + jul: 'heinä', + aug: 'elo', + sep: 'syys', + oct: 'loka', + nov: 'marras', + dec: 'joulu' + } + }, + select: { + loading: 'Lataa', + noMatch: 'Ei vastaavia tietoja', + noData: 'Ei tietoja', + placeholder: 'Valitse' + }, + cascader: { + noMatch: 'Ei vastaavia tietoja', + loading: 'Lataa', + placeholder: 'Valitse', + noData: 'Ei tietoja' + }, + pagination: { + goto: 'Mene', + pagesize: '/sivu', + total: 'Yhteensä {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Viesti', + confirm: 'OK', + cancel: 'Peruuta', + error: 'Virheellinen syöte' + }, + upload: { + deleteTip: 'Poista Delete-näppäimellä', + delete: 'Poista', + preview: 'Esikatsele', + continue: 'Jatka' + }, + table: { + emptyText: 'Ei tietoja', + confirmFilter: 'Vahvista', + resetFilter: 'Tyhjennä', + clearFilter: 'Kaikki', + sumText: 'Summa' + }, + tree: { + emptyText: 'Ei tietoja' + }, + transfer: { + noMatch: 'Ei vastaavia tietoja', + noData: 'Ei tietoja', + titles: ['Luettelo 1', 'Luettelo 2'], + filterPlaceholder: 'Syötä hakusana', + noCheckedFormat: '{total} kohdetta', + hasCheckedFormat: '{checked}/{total} valittu' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/fr.js b/src/locale/lang/fr.js new file mode 100644 index 0000000..13a31a2 --- /dev/null +++ b/src/locale/lang/fr.js @@ -0,0 +1,119 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Effacer' + }, + datepicker: { + now: 'Maintenant', + today: 'Auj.', + cancel: 'Annuler', + clear: 'Effacer', + confirm: 'OK', + selectDate: 'Choisir date', + selectTime: 'Choisir horaire', + startDate: 'Date début', + startTime: 'Horaire début', + endDate: 'Date fin', + endTime: 'Horaire fin', + prevYear: 'Année précédente', + nextYear: 'Année suivante', + prevMonth: 'Mois précédent', + nextMonth: 'Mois suivant', + year: '', // In french, like in english, we don't say "Année" after the year number. + month1: 'Janvier', + month2: 'Février', + month3: 'Mars', + month4: 'Avril', + month5: 'Mai', + month6: 'Juin', + month7: 'Juillet', + month8: 'Août', + month9: 'Septembre', + month10: 'Octobre', + month11: 'Novembre', + month12: 'Décembre', + // week: 'Semaine', + weeks: { + sun: 'Dim', + mon: 'Lun', + tue: 'Mar', + wed: 'Mer', + thu: 'Jeu', + fri: 'Ven', + sat: 'Sam' + }, + months: { + jan: 'Jan', + feb: 'Fév', + mar: 'Mar', + apr: 'Avr', + may: 'Mai', + jun: 'Jun', + jul: 'Jul', + aug: 'Aoû', + sep: 'Sep', + oct: 'Oct', + nov: 'Nov', + dec: 'Déc' + } + }, + select: { + loading: 'Chargement', + noMatch: 'Aucune correspondance', + noData: 'Aucune donnée', + placeholder: 'Choisir' + }, + cascader: { + noMatch: 'Aucune correspondance', + loading: 'Chargement', + placeholder: 'Choisir', + noData: 'Aucune donnée' + }, + pagination: { + goto: 'Aller à', + pagesize: '/page', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + confirm: 'Confirmer', + cancel: 'Annuler', + error: 'Erreur' + }, + upload: { + deleteTip: 'Cliquer sur supprimer pour retirer le fichier', + delete: 'Supprimer', + preview: 'Aperçu', + continue: 'Continuer' + }, + table: { + emptyText: 'Aucune donnée', + confirmFilter: 'Confirmer', + resetFilter: 'Réinitialiser', + clearFilter: 'Tous', + sumText: 'Somme' + }, + tree: { + emptyText: 'Aucune donnée' + }, + transfer: { + noMatch: 'Aucune correspondance', + noData: 'Aucune donnée', + titles: ['Liste 1', 'Liste 2'], + filterPlaceholder: 'Entrer un mot clef', + noCheckedFormat: '{total} elements', + hasCheckedFormat: '{checked}/{total} coché(s)' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/he.js b/src/locale/lang/he.js new file mode 100644 index 0000000..c63163c --- /dev/null +++ b/src/locale/lang/he.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'אישור', + clear: 'נקה' + }, + datepicker: { + now: 'כעת', + today: 'היום', + cancel: 'בטל', + 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 + year: '', + month1: 'ינואר', + month2: 'פברואר', + month3: 'מרץ', + month4: 'אפריל', + month5: 'מאי', + month6: 'יוני', + month7: 'יולי', + month8: 'אוגוסט', + month9: 'ספטמבר', + month10: 'אוקטובר', + month11: 'נובמבר', + month12: 'דצמבר', + // week: 'week', + weeks: { + sun: 'א׳', + mon: 'ב׳', + tue: 'ג׳', + wed: 'ד׳', + thu: 'ה׳', + fri: 'ו׳', + sat: 'שבת' + }, + months: { + jan: 'ינואר', + feb: 'פברואר', + mar: 'מרץ', + apr: 'אפריל', + may: 'מאי', + jun: 'יוני', + jul: 'יולי', + aug: 'אוגוסט', + sep: 'ספטמבר', + oct: 'אוקטובר', + nov: 'נובמבר', + dec: 'דצמבר' + } + }, + select: { + loading: 'טוען', + noMatch: 'לא נמצאו נתונים', + noData: 'ללא נתונים', + placeholder: 'בחר' + }, + cascader: { + noMatch: 'ללא נתונים מתאימים', + loading: 'טוען', + placeholder: 'בחר', + noData: 'ללא נתונים' + }, + pagination: { + goto: 'עבור ל', + pagesize: '/page', + total: 'כולל {total}', + pageClassifier: '' + }, + messagebox: { + title: 'הודעה', + confirm: 'אישור', + cancel: 'בטל', + error: 'קלט לא תקין' + }, + upload: { + deleteTip: 'press delete to remove', // to be translated + delete: 'מחק', + preview: 'תצוגה מקדימה', + continue: 'המשך' + }, + table: { + emptyText: 'אין נתונים', + confirmFilter: 'אישור', + resetFilter: 'נקה', + clearFilter: 'הכל', + sumText: 'סך' + }, + tree: { + emptyText: 'אין נתונים' + }, + transfer: { + noMatch: 'אין נתונים מתאימים', + noData: 'ללא נתונים', + titles: ['רשימה 1', 'רשימה 2'], + filterPlaceholder: 'הקלד', + noCheckedFormat: 'פריטים {total}', + hasCheckedFormat: ' אישור {checked}/{total}' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/hr.js b/src/locale/lang/hr.js new file mode 100644 index 0000000..9b38016 --- /dev/null +++ b/src/locale/lang/hr.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Očisti' + }, + datepicker: { + now: 'Sada', + today: 'Danas', + cancel: 'Otkaži', + clear: 'Očisti', + confirm: 'OK', + selectDate: 'Odaberi datum', + selectTime: 'Odaberi vrijeme', + startDate: 'Datum početka', + startTime: 'Vrijeme početka', + endDate: 'Datum završetka', + endTime: 'Vrijeme završetka', + prevYear: 'Prethodna godina', + nextYear: 'Sljedeća godina', + prevMonth: 'Prethodni mjesec', + nextMonth: 'Sljedeći mjesec', + year: '', + month1: 'Siječanj', + month2: 'Veljača', + month3: 'Ožujak', + month4: 'Travanj', + month5: 'Svibanj', + month6: 'Lipanj', + month7: 'Srpanj', + month8: 'Kolovoz', + month9: 'Rujan', + month10: 'Listopad', + month11: 'Studeni', + month12: 'Prosinac', + week: 'tjedan', + weeks: { + sun: 'Pon', + mon: 'Uto', + tue: 'Sri', + wed: 'Čet', + thu: 'Pet', + fri: 'Sub', + sat: 'Ned' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'May', + jun: 'Jun', + jul: 'Jul', + aug: 'Aug', + sep: 'Sep', + oct: 'Oct', + nov: 'Nov', + dec: 'Dec' + } + }, + select: { + loading: 'Učitavanje', + noMatch: 'Nema pronađenih podataka', + noData: 'Nema podataka', + placeholder: 'Izaberi' + }, + cascader: { + noMatch: 'Nema pronađenih podataka', + loading: 'Učitavanje', + placeholder: 'Izaberi', + noData: 'Nema podataka' + }, + pagination: { + goto: 'Idi na', + pagesize: '/stranica', + total: 'Ukupno {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Poruka', + confirm: 'OK', + cancel: 'Otkaži', + error: 'Pogrešan unos' + }, + upload: { + deleteTip: 'pritisnite izbriši za brisanje', + delete: 'Izbriši', + preview: 'Pregled', + continue: 'Nastavak' + }, + table: { + emptyText: 'Nema podataka', + confirmFilter: 'Potvrdi', + resetFilter: 'Resetiraj', + clearFilter: 'Sve', + sumText: 'Suma' + }, + tree: { + emptyText: 'Nema podataka' + }, + transfer: { + noMatch: 'Nema pronađenih podataka', + noData: 'Nema podataka', + titles: ['Lista 1', 'Lista 2'], // to be translated + filterPlaceholder: 'Unesite ključnu riječ', // to be translated + noCheckedFormat: '{total} stavki', // to be translated + hasCheckedFormat: '{checked}/{total} checked' // to be translated + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/hu.js b/src/locale/lang/hu.js new file mode 100644 index 0000000..d4c5e76 --- /dev/null +++ b/src/locale/lang/hu.js @@ -0,0 +1,119 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Törlés' + }, + datepicker: { + now: 'Most', + today: 'Ma', + cancel: 'Mégse', + clear: 'Törlés', + confirm: 'OK', + selectDate: 'Dátum', + selectTime: 'Időpont', + startDate: 'Dátum-tól', + startTime: 'Időpont-tól', + endDate: 'Dátum-ig', + endTime: 'Időpont-ig', + prevYear: 'Előző év', + nextYear: 'Következő év', + prevMonth: 'Előző hónap', + nextMonth: 'Következő hónap', + year: '', + month1: 'Január', + month2: 'Február', + month3: 'Március', + month4: 'Április', + month5: 'Május', + month6: 'Június', + month7: 'Július', + month8: 'Augusztus', + month9: 'Szeptember', + month10: 'Október', + month11: 'November', + month12: 'December', + weeks: { + sun: 'Vas', + mon: 'Hét', + tue: 'Ked', + wed: 'Sze', + thu: 'Csü', + fri: 'Pén', + sat: 'Szo' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Már', + apr: 'Ápr', + may: 'Máj', + jun: 'Jún', + jul: 'Júl', + aug: 'Aug', + sep: 'Szep', + oct: 'Okt', + nov: 'Nov', + dec: 'Dec' + } + }, + select: { + loading: 'Betöltés', + noMatch: 'Nincs találat', + noData: 'Nincs adat', + placeholder: 'Válassz' + }, + cascader: { + noMatch: 'Nincs találat', + loading: 'Betöltés', + placeholder: 'Válassz', + noData: 'Nincs adat' + }, + pagination: { + goto: 'Ugrás', + pagesize: '/oldal', + total: 'Össz {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Üzenet', + confirm: 'OK', + cancel: 'Mégse', + error: 'Hibás adat' + }, + upload: { + deleteTip: 'kattints a törléshez', + delete: 'Törlés', + preview: 'Előnézet', + continue: 'Tovább' + }, + table: { + emptyText: 'Nincs adat', + confirmFilter: 'Megerősít', + resetFilter: 'Alaphelyet', + clearFilter: 'Mind', + sumText: 'Összeg' + }, + tree: { + emptyText: 'Nincs adat' + }, + transfer: { + noMatch: 'Nincs találat', + noData: 'Nincs adat', + titles: ['Lista 1', 'Lista 2'], + filterPlaceholder: 'Kulcsszó', + noCheckedFormat: '{total} elem', + hasCheckedFormat: '{checked}/{total} kiválasztva' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/hy-AM.js b/src/locale/lang/hy-AM.js new file mode 100644 index 0000000..f8d55f8 --- /dev/null +++ b/src/locale/lang/hy-AM.js @@ -0,0 +1,120 @@ +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: 'Ընտրել', + noData: 'Տվյալներ չկան' + }, + 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} ընտրուած է' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/id.js b/src/locale/lang/id.js new file mode 100644 index 0000000..3a83858 --- /dev/null +++ b/src/locale/lang/id.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Pilih', + clear: 'Kosongkan' + }, + datepicker: { + now: 'Sekarang', + today: 'Hari ini', + cancel: 'Batal', + clear: 'Kosongkan', + confirm: 'Ya', + selectDate: 'Pilih tanggal', + selectTime: 'Pilih waktu', + startDate: 'Tanggal Mulai', + startTime: 'Waktu Mulai', + endDate: 'Tanggal Selesai', + endTime: 'Waktu Selesai', + prevYear: 'Tahun Sebelumnya', + nextYear: 'Tahun Selanjutnya', + prevMonth: 'Bulan Sebelumnya', + nextMonth: 'Bulan Selanjutnya', + year: 'Tahun', + month1: 'Januari', + month2: 'Februari', + month3: 'Maret', + month4: 'April', + month5: 'Mei', + month6: 'Juni', + month7: 'Juli', + month8: 'Agustus', + month9: 'September', + month10: 'Oktober', + month11: 'November', + month12: 'Desember', + // week: 'minggu', + weeks: { + sun: 'Min', + mon: 'Sen', + tue: 'Sel', + wed: 'Rab', + thu: 'Kam', + fri: 'Jum', + sat: 'Sab' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Mei', + jun: 'Jun', + jul: 'Jul', + aug: 'Agu', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Des' + } + }, + select: { + loading: 'Memuat', + noMatch: 'Tidak ada data yg cocok', + noData: 'Tidak ada data', + placeholder: 'Pilih' + }, + cascader: { + noMatch: 'Tidak ada data yg cocok', + loading: 'Memuat', + placeholder: 'Pilih', + noData: 'Tidak ada data' + }, + pagination: { + goto: 'Pergi ke', + pagesize: '/laman', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Pesan', + confirm: 'Ya', + cancel: 'Batal', + error: 'Masukan ilegal' + }, + upload: { + deleteTip: 'Tekan hapus untuk melanjutkan', + delete: 'Hapus', + preview: 'Pratinjau', + continue: 'Lanjutkan' + }, + table: { + emptyText: 'Tidak ada data', + confirmFilter: 'Konfirmasi', + resetFilter: 'Atur ulang', + clearFilter: 'Semua', + sumText: 'Jml' + }, + tree: { + emptyText: 'Tidak ada data' + }, + transfer: { + noMatch: 'Tidak ada data yg cocok', + noData: 'Tidak ada data', + titles: ['Senarai 1', 'Senarai 2'], + filterPlaceholder: 'Masukan kata kunci', + noCheckedFormat: '{total} butir', + hasCheckedFormat: '{checked}/{total} terpilih' + }, + image: { + error: 'GAGAL' + }, + pageHeader: { + title: 'Kembali' + }, + popconfirm: { + confirmButtonText: 'Ya', + cancelButtonText: 'Tidak' + } + } +}; diff --git a/src/locale/lang/it.js b/src/locale/lang/it.js new file mode 100644 index 0000000..40bc974 --- /dev/null +++ b/src/locale/lang/it.js @@ -0,0 +1,119 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Pulisci' + }, + datepicker: { + now: 'Ora', + today: 'Oggi', + cancel: 'Cancella', + clear: 'Pulisci', + confirm: 'OK', + selectDate: 'Seleziona data', + selectTime: 'Seleziona ora', + startDate: 'Data inizio', + startTime: 'Ora inizio', + endDate: 'Data fine', + endTime: 'Ora fine', + prevYear: 'Anno precedente', + nextYear: 'Anno successivo', + prevMonth: 'Mese precedente', + nextMonth: 'Mese successivo', + year: '', + month1: 'Gennaio', + month2: 'Febbraio', + month3: 'Marzo', + month4: 'Aprile', + month5: 'Maggio', + month6: 'Giugno', + month7: 'Luglio', + month8: 'Agosto', + month9: 'Settembre', + month10: 'Ottobre', + month11: 'Novembre', + month12: 'Dicembre', + // week: 'settimana', + weeks: { + sun: 'Dom', + mon: 'Lun', + tue: 'Mar', + wed: 'Mer', + thu: 'Gio', + fri: 'Ven', + sat: 'Sab' + }, + months: { + jan: 'Gen', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Mag', + jun: 'Giu', + jul: 'Lug', + aug: 'Ago', + sep: 'Set', + oct: 'Ott', + nov: 'Nov', + dec: 'Dic' + } + }, + select: { + loading: 'Caricamento', + noMatch: 'Nessuna corrispondenza', + noData: 'Nessun dato', + placeholder: 'Seleziona' + }, + cascader: { + noMatch: 'Nessuna corrispondenza', + loading: 'Caricamento', + placeholder: 'Seleziona', + noData: 'Nessun dato' + }, + pagination: { + goto: 'Vai a', + pagesize: '/page', + total: 'Totale {total}', + pageClassifier: '' + }, + messagebox: { + confirm: 'OK', + cancel: 'Cancella', + error: 'Input non valido' + }, + upload: { + deleteTip: 'Premi cancella per rimuovere', + delete: 'Cancella', + preview: 'Anteprima', + continue: 'Continua' + }, + table: { + emptyText: 'Nessun dato', + confirmFilter: 'Conferma', + resetFilter: 'Reset', + clearFilter: 'Tutti', + sumText: 'Somma' + }, + tree: { + emptyText: 'Nessun dato' + }, + transfer: { + noMatch: 'Nessuna corrispondenza', + noData: 'Nessun dato', + titles: ['Lista 1', 'Lista 2'], + filterPlaceholder: 'Inserisci filtro', + noCheckedFormat: '{total} elementi', + hasCheckedFormat: '{checked}/{total} selezionati' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/ja.js b/src/locale/lang/ja.js new file mode 100644 index 0000000..a6b62be --- /dev/null +++ b/src/locale/lang/ja.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'クリア' + }, + datepicker: { + now: '現在', + today: '今日', + cancel: 'キャンセル', + clear: 'クリア', + confirm: 'OK', + 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: '選択してください', + noData: 'データなし' + }, + pagination: { + goto: '', + pagesize: '件/ページ', + total: '総計 {total} 件', + pageClassifier: 'ページ目へ' + }, + messagebox: { + title: 'メッセージ', + confirm: 'OK', + cancel: 'キャンセル', + error: '正しくない入力' + }, + upload: { + deleteTip: 'Delキーを押して削除する', + delete: '削除する', + preview: 'プレビュー', + continue: '続行する' + }, + table: { + emptyText: 'データなし', + confirmFilter: '確認', + resetFilter: '初期化', + clearFilter: 'すべて', + sumText: '合計' + }, + tree: { + emptyText: 'データなし' + }, + transfer: { + noMatch: 'データなし', + noData: 'データなし', + titles: ['リスト 1', 'リスト 2'], + filterPlaceholder: 'キーワードを入力', + noCheckedFormat: '総計 {total} 件', + hasCheckedFormat: '{checked}/{total} を選択した' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/kg.js b/src/locale/lang/kg.js new file mode 100644 index 0000000..8c8526f --- /dev/null +++ b/src/locale/lang/kg.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Мурунку', + clear: 'ачык' + }, + datepicker: { + now: 'азыр', + today: 'бүгүн', + cancel: 'жокко чыгарылды', + clear: 'ачык', + confirm: 'белгилөө', + selectDate: 'дата', + selectTime: 'тандоо убактысы', + startDate: 'Башталган датасы', + startTime: 'Start убакыт', + endDate: 'Бүткөн датасы', + endTime: 'End убакыт', + 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: 'тандоо', + noData: 'маалымат жок' + }, + 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} сан' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/km.js b/src/locale/lang/km.js new file mode 100644 index 0000000..6819c42 --- /dev/null +++ b/src/locale/lang/km.js @@ -0,0 +1,120 @@ +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: 'ជ្រើសរើស', + noData: 'គ្មានទិន្ន័យ' + }, + 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: ['បញ្ជី ១', 'បញ្ជី ២'], + filterPlaceholder: 'បញ្ចូលពាក្យ', + noCheckedFormat: '{total} ធាតុ', + hasCheckedFormat: '{checked}/{total} បានគូសធីក' + }, + image: { + error: 'បរាជ័យ' + }, + pageHeader: { + title: 'Back' + }, + popconfirm: { + confirmButtonText: 'ព្រម', + cancelButtonText: 'មិនព្រម' + } + } +}; diff --git a/src/locale/lang/ko.js b/src/locale/lang/ko.js new file mode 100644 index 0000000..b5b4c5e --- /dev/null +++ b/src/locale/lang/ko.js @@ -0,0 +1,120 @@ +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: '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: '선택', + noData: '데이터 없음' + }, + 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: ['리스트 1', '리스트 2'], + filterPlaceholder: ' 입력하세요', + noCheckedFormat: '{total} 항목', + hasCheckedFormat: '{checked}/{total} 선택됨' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/ku.js b/src/locale/lang/ku.js new file mode 100644 index 0000000..5188ba7 --- /dev/null +++ b/src/locale/lang/ku.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Temam', + clear: 'Paqij bike' + }, + datepicker: { + now: 'Niha', + today: 'Îro', + cancel: 'Betal bike', + clear: 'Paqij bike', + confirm: 'Temam', + selectDate: 'Dîrokê bibijêre', + selectTime: 'Demê bibijêre', + startDate: 'Dîroka Destpêkê', + startTime: 'Dema Destpêkê', + endDate: 'Dîroka Dawî', + endTime: 'Dema Dawî', + prevYear: 'Sala Pêş', + nextYear: 'Sala Paş', + prevMonth: 'Meha Pêş', + nextMonth: 'Meha Paş', + year: 'Sal', + month1: 'Rêbendan', + month2: 'Reşemeh', + month3: 'Adar', + month4: 'Avrêl', + month5: 'Gulan', + month6: 'Pûşber', + month7: 'Tîrmeh', + month8: 'Gilavêj', + month9: 'Rezber', + month10: 'Kewçêr', + month11: 'Sarmawaz', + month12: 'Berfanbar', + // week: 'week', + weeks: { + sun: 'Yek', + mon: 'Duş', + tue: 'Sêş', + wed: 'Çar', + thu: 'Pên', + fri: 'În', + sat: 'Şem' + }, + months: { + jan: 'Rêb', + feb: 'Reş', + mar: 'Ada', + apr: 'Avr', + may: 'Gul', + jun: 'Pûş', + jul: 'Tîr', + aug: 'Gil', + sep: 'Rez', + oct: 'Kew', + nov: 'Sar', + dec: 'Ber' + } + }, + select: { + loading: 'Bardibe', + noMatch: 'Li hembere ve agahî tune', + noData: 'Agahî tune', + placeholder: 'Bibijêre' + }, + cascader: { + noMatch: 'Li hembere ve agahî tune', + loading: 'Bardibe', + placeholder: 'Bibijêre', + noData: 'Agahî tune' + }, + pagination: { + goto: 'Biçe', + pagesize: '/rupel', + total: 'Tevahî {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Peyam', + confirm: 'Temam', + cancel: 'Betal bike', + error: 'Beyana çewt' + }, + upload: { + deleteTip: 'ji bo rake pêl "delete" bike', + delete: 'Rake', + preview: 'Pêşdîtin', + continue: 'Berdewam' + }, + table: { + emptyText: 'Agahî tune', + confirmFilter: 'Piştrast bike', + resetFilter: 'Jê bibe', + clearFilter: 'Hemû', + sumText: 'Kom' + }, + tree: { + emptyText: 'Agahî tune' + }, + transfer: { + noMatch: 'Li hembere ve agahî tune', + noData: 'Agahî tune', + titles: ['Lîste 1', 'Lîste 2'], + filterPlaceholder: 'Binivîse', + noCheckedFormat: '{total} lib', + hasCheckedFormat: '{checked}/{total} bijartin' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/kz.js b/src/locale/lang/kz.js new file mode 100644 index 0000000..acfc8e2 --- /dev/null +++ b/src/locale/lang/kz.js @@ -0,0 +1,120 @@ +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: 'Таңдаңыз', + noData: 'Деректер жоқ' + }, + 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} құсбелгісі қойылды' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/lt.js b/src/locale/lang/lt.js new file mode 100644 index 0000000..988de6b --- /dev/null +++ b/src/locale/lang/lt.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Valyti' + }, + datepicker: { + now: 'Dabar', + today: 'Šiandien', + cancel: 'Atšaukti', + clear: 'Valyti', + 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', + noData: 'Nėra duomenų' + }, + 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}' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/lv.js b/src/locale/lang/lv.js new file mode 100644 index 0000000..b9497ea --- /dev/null +++ b/src/locale/lang/lv.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Labi', + clear: 'Notīrīt' + }, + datepicker: { + now: 'Tagad', + today: 'Šodien', + cancel: 'Atcelt', + clear: 'Notīrīt', + confirm: 'Labi', + selectDate: 'Izvēlēties datumu', + selectTime: 'Izvēlēties laiku', + startDate: 'Sākuma datums', + startTime: 'Sākuma laiks', + endDate: 'Beigu datums', + endTime: 'Beigu laiks', + prevYear: 'Iepriekšējais gads', + nextYear: 'Nākamais gads', + prevMonth: 'Iepriekšējais mēnesis', + nextMonth: 'Nākamais mēnesis', + year: '', + month1: 'Janvāris', + month2: 'Februāris', + month3: 'Marts', + month4: 'Aprīlis', + month5: 'Maijs', + month6: 'Jūnijs', + month7: 'Jūlijs', + month8: 'Augusts', + month9: 'Septembris', + month10: 'Oktobris', + month11: 'Novembris', + month12: 'Decembris', + // week: 'nedēļa', + weeks: { + sun: 'Sv', + mon: 'Pr', + tue: 'Ot', + wed: 'Tr', + thu: 'Ce', + fri: 'Pk', + sat: 'Se' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Mai', + jun: 'Jūn', + jul: 'Jūl', + aug: 'Aug', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Dec' + } + }, + select: { + loading: 'Ielādē', + noMatch: 'Nav atbilstošu datu', + noData: 'Nav datu', + placeholder: 'Izvēlēties' + }, + cascader: { + noMatch: 'Nav atbilstošu datu', + loading: 'Ielādē', + placeholder: 'Izvēlēties', + noData: 'Nav datu' + }, + pagination: { + goto: 'Iet uz', + pagesize: '/lapa', + total: 'Kopā {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Paziņojums', + confirm: 'Labi', + cancel: 'Atcelt', + error: 'Nederīga ievade' + }, + upload: { + deleteTip: 'Nospiediet dzēst lai izņemtu', + delete: 'Dzēst', + preview: 'Priekšskatīt', + continue: 'Turpināt' + }, + table: { + emptyText: 'Nav datu', + confirmFilter: 'Apstiprināt', + resetFilter: 'Atiestatīt', + clearFilter: 'Visi', + sumText: 'Summa' + }, + tree: { + emptyText: 'Nav datu' + }, + transfer: { + noMatch: 'Nav atbilstošu datu', + noData: 'Nav datu', + titles: ['Saraksts 1', 'Saraksts 2'], + filterPlaceholder: 'Ievadīt atslēgvārdu', + noCheckedFormat: '{total} vienības', + hasCheckedFormat: '{checked}/{total} atzīmēti' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/mn.js b/src/locale/lang/mn.js new file mode 100644 index 0000000..a0e3f6d --- /dev/null +++ b/src/locale/lang/mn.js @@ -0,0 +1,120 @@ +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: 'Сонгох', + noData: 'Өгөгдөл байхгүй' + }, + 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} сонгосон' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/nb-NO.js b/src/locale/lang/nb-NO.js new file mode 100644 index 0000000..843a67e --- /dev/null +++ b/src/locale/lang/nb-NO.js @@ -0,0 +1,119 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Tøm' + }, + datepicker: { + now: 'Nå', + today: 'I dag', + cancel: 'Avbryt', + clear: 'Tøm', + confirm: 'OK', + selectDate: 'Velg dato', + selectTime: 'Velg tidspunkt', + startDate: 'Start Dato', + startTime: 'Start Tidspunkt', + endDate: 'Sluttdato', + endTime: 'Sluttidspunkt', + prevYear: 'Previous Year', // to be translated + nextYear: 'Next Year', // to be translated + prevMonth: 'Previous Month', // to be translated + nextMonth: 'Next Month', // to be translated + year: '', + month1: 'Januar', + month2: 'Februar', + month3: 'Mars', + month4: 'April', + month5: 'Mai', + month6: 'Juni', + month7: 'Juli', + month8: 'August', + month9: 'September', + month10: 'Oktober', + month11: 'November', + month12: 'Desember', + // week: 'week', + weeks: { + sun: 'Søn', + mon: 'Man', + tue: 'Tir', + wed: 'Ons', + thu: 'Tor', + fri: 'Fre', + sat: 'Lør' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Mai', + jun: 'Jun', + jul: 'Jul', + aug: 'Aug', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Des' + } + }, + select: { + loading: 'Laster', + noMatch: 'Ingen samsvarende data', + noData: 'Ingen data', + placeholder: 'Velg' + }, + cascader: { + noMatch: 'Ingen samsvarende data', + loading: 'Laster', + placeholder: 'Velg', + noData: 'Ingen data' + }, + pagination: { + goto: 'Gå til', + pagesize: '/side', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + confirm: 'OK', + cancel: 'Avbryt', + error: 'Ugyldig input' + }, + upload: { + deleteTip: 'press delete to remove', // to be translated + delete: 'Slett', + preview: 'Forhåndsvisning', + continue: 'Fortsett' + }, + table: { + emptyText: 'Ingen Data', + confirmFilter: 'Bekreft', + resetFilter: 'Tilbakestill', + clearFilter: 'Alle', + sumText: 'Sum' // to be translated + }, + tree: { + emptyText: 'Ingen Data' + }, + transfer: { + noMatch: 'Ingen samsvarende data', + noData: 'Ingen 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 + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/nl.js b/src/locale/lang/nl.js new file mode 100644 index 0000000..6d08431 --- /dev/null +++ b/src/locale/lang/nl.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Bevestig', + clear: 'Wissen' + }, + datepicker: { + now: 'Nu', + today: 'Vandaag', + cancel: 'Annuleren', + clear: 'Legen', + confirm: 'Bevestig', + selectDate: 'Selecteer datum', + selectTime: 'Selecteer tijd', + startDate: 'Startdatum', + startTime: 'Starttijd', + endDate: 'Einddatum', + endTime: 'Eindtijd', + prevYear: 'Vorig jaar', + nextYear: 'Volgend jaar', + prevMonth: 'Vorige maand', + nextMonth: 'Volgende maand', + year: '', + month1: 'januari', + month2: 'februari', + month3: 'maart', + month4: 'april', + month5: 'mei', + month6: 'juni', + month7: 'juli', + month8: 'augustus', + month9: 'september', + month10: 'oktober', + month11: 'november', + month12: 'december', + // week: 'week', + weeks: { + sun: 'Zo', + mon: 'Ma', + tue: 'Di', + wed: 'Wo', + thu: 'Do', + fri: 'Vr', + sat: 'Za' + }, + months: { + jan: 'jan', + feb: 'feb', + mar: 'maa', + apr: 'apr', + may: 'mei', + jun: 'jun', + jul: 'jul', + aug: 'aug', + sep: 'sep', + oct: 'okt', + nov: 'nov', + dec: 'dec' + } + }, + select: { + loading: 'Laden', + noMatch: 'Geen overeenkomende resultaten', + noData: 'Geen data', + placeholder: 'Selecteer' + }, + cascader: { + noMatch: 'Geen overeenkomende resultaten', + loading: 'Laden', + placeholder: 'Selecteer', + noData: 'Geen data' + }, + pagination: { + goto: 'Ga naar', + pagesize: '/pagina', + total: 'Totaal {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Bericht', + confirm: 'Bevestig', + cancel: 'Annuleren', + error: 'Ongeldige invoer' + }, + upload: { + deleteTip: 'Kies verwijder om te wissen', + delete: 'Verwijder', + preview: 'Voorbeeld', + continue: 'Doorgaan' + }, + table: { + emptyText: 'Geen data', + confirmFilter: 'Bevestigen', + resetFilter: 'Reset', + clearFilter: 'Alles', + sumText: 'Som' + }, + tree: { + emptyText: 'Geen data' + }, + transfer: { + noMatch: 'Geen overeenkomende resultaten', + noData: 'Geen data', + titles: ['Lijst 1', 'Lijst 2'], + filterPlaceholder: 'Geef zoekwoerd', + noCheckedFormat: '{total} items', + hasCheckedFormat: '{checked}/{total} geselecteerd' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/pl.js b/src/locale/lang/pl.js new file mode 100644 index 0000000..72af963 --- /dev/null +++ b/src/locale/lang/pl.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Wyczyść' + }, + datepicker: { + now: 'Teraz', + today: 'Dzisiaj', + cancel: 'Anuluj', + clear: 'Wyczyść', + confirm: 'OK', + selectDate: 'Wybierz datę', + selectTime: 'Wybierz godzinę', + startDate: 'Data początkowa', + startTime: 'Godzina początkowa', + endDate: 'Data końcowa', + endTime: 'Czas końcowa', + prevYear: 'Poprzedni rok', + nextYear: 'Następny rok', + prevMonth: 'Poprzedni miesiąc', + nextMonth: 'Następny miesiąc', + year: 'rok', + month1: 'styczeń', + month2: 'luty', + month3: 'marzec', + month4: 'kwiecień', + month5: 'maj', + month6: 'czerwiec', + month7: 'lipiec', + month8: 'sierpień', + month9: 'wrzesień', + month10: 'październik', + month11: 'listopad', + month12: 'grudzień', + week: 'tydzień', + weeks: { + sun: 'niedz.', + mon: 'pon.', + tue: 'wt.', + wed: 'śr.', + thu: 'czw.', + fri: 'pt.', + sat: 'sob.' + }, + months: { + jan: 'STY', + feb: 'LUT', + mar: 'MAR', + apr: 'KWI', + may: 'MAJ', + jun: 'CZE', + jul: 'LIP', + aug: 'SIE', + sep: 'WRZ', + oct: 'PAŹ', + nov: 'LIS', + dec: 'GRU' + } + }, + select: { + loading: 'Ładowanie', + noMatch: 'Brak dopasowań', + noData: 'Brak danych', + placeholder: 'Wybierz' + }, + cascader: { + noMatch: 'Brak dopasowań', + loading: 'Ładowanie', + placeholder: 'Wybierz', + noData: 'Brak danych' + }, + pagination: { + goto: 'Idź do', + pagesize: '/strona', + total: 'Wszystkich {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Wiadomość', + confirm: 'OK', + cancel: 'Anuluj', + error: 'Wiadomość zawiera niedozwolone znaki' + }, + upload: { + deleteTip: 'kliknij kasuj aby usunąć', + delete: 'Kasuj', + preview: 'Podgląd', + continue: 'Kontynuuj' + }, + table: { + emptyText: 'Brak danych', + confirmFilter: 'Potwierdź', + resetFilter: 'Resetuj', + clearFilter: 'Wszystko', + sumText: 'Razem' + }, + tree: { + emptyText: 'Brak danych' + }, + transfer: { + noMatch: 'Brak dopasowań', + noData: 'Brak danych', + titles: ['Lista 1', 'Lista 2'], + filterPlaceholder: 'Wpisz szukaną frazę', + noCheckedFormat: 'razem: {total}', + hasCheckedFormat: 'wybranych: {checked}/{total}' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/pt-br.js b/src/locale/lang/pt-br.js new file mode 100644 index 0000000..42ae6aa --- /dev/null +++ b/src/locale/lang/pt-br.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Confirmar', + clear: 'Limpar' + }, + datepicker: { + now: 'Agora', + today: 'Hoje', + cancel: 'Cancelar', + clear: 'Limpar', + confirm: 'Confirmar', + selectDate: 'Selecione a data', + selectTime: 'Selecione a hora', + startDate: 'Data inicial', + startTime: 'Hora inicial', + endDate: 'Data final', + endTime: 'Hora final', + prevYear: 'Ano anterior', + nextYear: 'Próximo ano', + prevMonth: 'Mês anterior', + nextMonth: 'Próximo mês', + year: '', + month1: 'Janeiro', + month2: 'Fevereiro', + month3: 'Março', + month4: 'Abril', + month5: 'Maio', + month6: 'Junho', + month7: 'Julho', + month8: 'Agosto', + month9: 'Setembro', + month10: 'Outubro', + month11: 'Novembro', + month12: 'Dezembro', + // week: 'semana', + weeks: { + sun: 'Dom', + mon: 'Seg', + tue: 'Ter', + wed: 'Qua', + thu: 'Qui', + fri: 'Sex', + sat: 'Sab' + }, + months: { + jan: 'Jan', + feb: 'Fev', + mar: 'Mar', + apr: 'Abr', + may: 'Mai', + jun: 'Jun', + jul: 'Jul', + aug: 'Ago', + sep: 'Set', + oct: 'Out', + nov: 'Nov', + dec: 'Dez' + } + }, + select: { + loading: 'Carregando', + noMatch: 'Sem resultados', + noData: 'Sem dados', + placeholder: 'Selecione' + }, + cascader: { + noMatch: 'Sem resultados', + loading: 'Carregando', + placeholder: 'Selecione', + noData: 'Sem dados' + }, + pagination: { + goto: 'Ir para', + pagesize: '/página', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Mensagem', + confirm: 'Confirmar', + cancel: 'Cancelar', + error: 'Erro!' + }, + upload: { + deleteTip: 'aperte delete para apagar', + delete: 'Apagar', + preview: 'Pré-visualizar', + continue: 'Continuar' + }, + table: { + emptyText: 'Sem dados', + confirmFilter: 'Confirmar', + resetFilter: 'Limpar', + clearFilter: 'Todos', + sumText: 'Total' + }, + tree: { + emptyText: 'Sem dados' + }, + transfer: { + noMatch: 'Sem resultados', + noData: 'Sem dados', + titles: ['Lista 1', 'Lista 2'], + filterPlaceholder: 'Digite uma palavra-chave', + noCheckedFormat: '{total} itens', + hasCheckedFormat: '{checked}/{total} selecionados' + }, + image: { + error: 'Erro ao carregar imagem' + }, + pageHeader: { + title: 'Voltar' + }, + popconfirm: { + confirmButtonText: 'Sim', + cancelButtonText: 'Não' + } + } +}; diff --git a/src/locale/lang/pt.js b/src/locale/lang/pt.js new file mode 100644 index 0000000..722e0a7 --- /dev/null +++ b/src/locale/lang/pt.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Confirmar', + clear: 'Limpar' + }, + datepicker: { + now: 'Agora', + today: 'Hoje', + cancel: 'Cancelar', + clear: 'Limpar', + confirm: 'Confirmar', + selectDate: 'Selecione a data', + selectTime: 'Selecione a hora', + startDate: 'Data de inicio', + startTime: 'Hora de inicio', + endDate: 'Data de fim', + endTime: 'Hora de fim', + prevYear: 'Previous Year', // to be translated + nextYear: 'Next Year', // to be translated + prevMonth: 'Previous Month', // to be translated + nextMonth: 'Next Month', // to be translated + year: '', + month1: 'Janeiro', + month2: 'Fevereiro', + month3: 'Março', + month4: 'Abril', + month5: 'Maio', + month6: 'Junho', + month7: 'Julho', + month8: 'Agosto', + month9: 'Setembro', + month10: 'Outubro', + month11: 'Novembro', + month12: 'Dezembro', + // week: 'semana', + weeks: { + sun: 'Dom', + mon: 'Seg', + tue: 'Ter', + wed: 'Qua', + thu: 'Qui', + fri: 'Sex', + sat: 'Sab' + }, + months: { + jan: 'Jan', + feb: 'Fev', + mar: 'Mar', + apr: 'Abr', + may: 'Mai', + jun: 'Jun', + jul: 'Jul', + aug: 'Ago', + sep: 'Set', + oct: 'Out', + nov: 'Nov', + dec: 'Dez' + } + }, + select: { + loading: 'A carregar', + noMatch: 'Sem correspondência', + noData: 'Sem dados', + placeholder: 'Selecione' + }, + cascader: { + noMatch: 'Sem correspondência', + loading: 'A carregar', + placeholder: 'Selecione', + noData: 'Sem dados' + }, + pagination: { + goto: 'Ir para', + pagesize: '/pagina', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Mensagem', + confirm: 'Confirmar', + cancel: 'Cancelar', + error: 'Erro!' + }, + upload: { + deleteTip: 'press delete to remove', // to be translated + delete: 'Apagar', + preview: 'Previsualizar', + continue: 'Continuar' + }, + table: { + emptyText: 'Sem dados', + confirmFilter: 'Confirmar', + resetFilter: 'Limpar', + clearFilter: 'Todos', + sumText: 'Sum' // to be translated + }, + tree: { + emptyText: 'Sem dados' + }, + transfer: { + noMatch: 'Sem correspondência', + noData: 'Sem dados', + 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 + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/ro.js b/src/locale/lang/ro.js new file mode 100644 index 0000000..3f5646b --- /dev/null +++ b/src/locale/lang/ro.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Șterge' + }, + datepicker: { + now: 'Acum', + today: 'Azi', + cancel: 'Anulează', + clear: 'Șterge', + confirm: 'OK', + selectDate: 'Selectează data', + selectTime: 'Selectează ora', + startDate: 'Data de început', + startTime: 'Ora de început', + endDate: 'Data de sfârșit', + endTime: 'Ora de sfârșit', + prevYear: 'Anul trecut', + nextYear: 'Anul următor', + prevMonth: 'Luna trecută', + nextMonth: 'Luna următoare', + year: '', + month1: 'Ianuarie', + month2: 'Februarie', + month3: 'Martie', + month4: 'Aprilie', + month5: 'Mai', + month6: 'Iunie', + month7: 'Iulie', + month8: 'August', + month9: 'Septembrie', + month10: 'Octombrie', + month11: 'Noiembrie', + month12: 'Decembrie', + // week: 'week', + weeks: { + sun: 'Du', + mon: 'Lu', + tue: 'Ma', + wed: 'Mi', + thu: 'Jo', + fri: 'Vi', + sat: 'Sâ' + }, + months: { + jan: 'Ian', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Mai', + jun: 'Iun', + jul: 'Iul', + aug: 'Aug', + sep: 'Sep', + oct: 'Oct', + nov: 'Noi', + dec: 'Dec' + } + }, + select: { + loading: 'Se încarcă', + noMatch: 'Nu există date potrivite', + noData: 'Nu există date', + placeholder: 'Selectează' + }, + cascader: { + noMatch: 'Nu există date potrivite', + loading: 'Se încarcă', + placeholder: 'Selectează', + noData: 'Nu există date' + }, + pagination: { + goto: 'Go to', + pagesize: '/pagina', + total: 'Total {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Mesaj', + confirm: 'OK', + cancel: 'Anulează', + error: 'Date introduse eronate' + }, + upload: { + deleteTip: 'apăsați pe ștergeți pentru a elimina', + delete: 'șterge', + preview: 'previzualizare', + continue: 'continuă' + }, + table: { + emptyText: 'Nu există date', + confirmFilter: 'Confirmă', + resetFilter: 'Resetează', + clearFilter: 'Tot', + sumText: 'Suma' + }, + tree: { + emptyText: 'Nu există date' + }, + transfer: { + noMatch: 'Nu există date potrivite', + noData: 'Nu există date', + titles: ['Lista 1', 'Lista 2'], + filterPlaceholder: 'Introduceți cuvântul cheie', + noCheckedFormat: '{total} elemente', + hasCheckedFormat: '{checked}/{total} verificate' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/ru-RU.js b/src/locale/lang/ru-RU.js new file mode 100644 index 0000000..af95018 --- /dev/null +++ b/src/locale/lang/ru-RU.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Очистить' + }, + datepicker: { + now: 'Сейчас', + today: 'Сегодня', + cancel: 'Отмена', + clear: 'Очистить', + confirm: 'OK', + 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: 'Выбрать', + noData: 'Нет данных' + }, + pagination: { + goto: 'Перейти', + pagesize: ' на странице', + total: 'Всего {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Сообщение', + confirm: 'OK', + 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} выбрано' + }, + image: { + error: 'Произошла ошибка' + }, + pageHeader: { + title: 'Назад' + }, + popconfirm: { + confirmButtonText: 'OK', + cancelButtonText: 'Отмена' + } + } +}; diff --git a/src/locale/lang/sk.js b/src/locale/lang/sk.js new file mode 100644 index 0000000..7c7103c --- /dev/null +++ b/src/locale/lang/sk.js @@ -0,0 +1,122 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Zmazať' + }, + datepicker: { + now: 'Teraz', + today: 'Dnes', + cancel: 'Zrušiť', + clear: 'Zmazať', + confirm: 'OK', + selectDate: 'Vybrať dátum', + selectTime: 'Vybrať čas', + startDate: 'Dátum začiatku', + startTime: 'Čas začiatku', + endDate: 'Dátum konca', + endTime: 'Čas konca', + prevYear: 'Predošlý rok', + nextYear: 'Ďalší rok', + prevMonth: 'Predošlý mesiac', + nextMonth: 'Ďalší mesiac', + day: 'Deň', + week: 'Týždeň', + month: 'Mesiac', + year: 'Rok', + month1: 'Január', + month2: 'Február', + month3: 'Marec', + month4: 'Apríl', + month5: 'Máj', + month6: 'Jún', + month7: 'Júl', + month8: 'August', + month9: 'September', + month10: 'Október', + month11: 'November', + month12: 'December', + weeks: { + sun: 'Ne', + mon: 'Po', + tue: 'Ut', + wed: 'St', + thu: 'Št', + fri: 'Pi', + sat: 'So' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Máj', + jun: 'Jún', + jul: 'Júl', + aug: 'Aug', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Dec' + } + }, + select: { + loading: 'Načítavanie', + noMatch: 'Žiadna zhoda', + noData: 'Žiadne dáta', + placeholder: 'Vybrať' + }, + cascader: { + noMatch: 'Žiadna zhoda', + loading: 'Načítavanie', + placeholder: 'Vybrať', + noData: 'Žiadne dáta' + }, + pagination: { + goto: 'Choď na', + pagesize: 'na stranu', + total: 'Všetko {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Správa', + confirm: 'OK', + cancel: 'Zrušiť', + error: 'Neplatný vstup' + }, + upload: { + deleteTip: 'pre odstránenie stisni klávesu Delete', + delete: 'Vymazať', + preview: 'Prehliadať', + continue: 'Pokračovať' + }, + table: { + emptyText: 'Žiadne dáta', + confirmFilter: 'Potvrdiť', + resetFilter: 'Zresetovať', + clearFilter: 'Všetko', + sumText: 'Spolu' + }, + tree: { + emptyText: 'Žiadne dáta' + }, + transfer: { + noMatch: 'Žiadna zhoda', + noData: 'Žiadne dáta', + titles: ['Zoznam 1', 'Zoznam 2'], + filterPlaceholder: 'Filtrovať podľa', + noCheckedFormat: '{total} položiek', + hasCheckedFormat: '{checked}/{total} označených' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/sl.js b/src/locale/lang/sl.js new file mode 100644 index 0000000..8c64be8 --- /dev/null +++ b/src/locale/lang/sl.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'V redu', + clear: 'Počisti' + }, + datepicker: { + now: 'Zdaj', + today: 'Danes', + cancel: 'Prekliči', + clear: 'Počisti', + confirm: 'Potrdi', + selectDate: 'Izberi datum', + selectTime: 'Izberi čas', + startDate: 'Začetni datum', + startTime: 'Začetni čas', + endDate: 'Končni datum', + endTime: 'Končni čas', + prevYear: 'Prejšnje leto', + nextYear: 'Naslednje leto', + prevMonth: 'Prejšnji mesec', + nextMonth: 'Naslednji mesec', + year: '', + month1: 'Jan', + month2: 'Feb', + month3: 'Mar', + month4: 'Apr', + month5: 'Maj', + month6: 'Jun', + month7: 'Jul', + month8: 'Avg', + month9: 'Sep', + month10: 'Okt', + month11: 'Nov', + month12: 'Dec', + week: 'teden', + weeks: { + sun: 'Ned', + mon: 'Pon', + tue: 'Tor', + wed: 'Sre', + thu: 'Čet', + fri: 'Pet', + sat: 'Sob' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Maj', + jun: 'Jun', + jul: 'Jul', + aug: 'Avg', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Dec' + } + }, + select: { + loading: 'Nalaganje', + noMatch: 'Ni ustreznih podatkov', + noData: 'Ni podatkov', + placeholder: 'Izberi' + }, + cascader: { + noMatch: 'Ni ustreznih podatkov', + loading: 'Nalaganje', + placeholder: 'Izberi', + noData: 'Ni podatkov' + }, + pagination: { + goto: 'Pojdi na', + pagesize: '/stran', + total: 'Skupno {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Sporočilo', + confirm: 'V redu', + cancel: 'Prekliči', + error: 'Nedovoljen vnos' + }, + upload: { + deleteTip: 'press delete to remove', // to be translated + delete: 'Izbriši', + preview: 'Predogled', + continue: 'Nadaljuj' + }, + table: { + emptyText: 'Ni podatkov', + confirmFilter: 'Potrdi', + resetFilter: 'Ponastavi', + clearFilter: 'Vse', + sumText: 'Skupno' + }, + tree: { + emptyText: 'Ni podatkov' + }, + transfer: { + noMatch: 'Ni ustreznih podatkov', + noData: 'Ni podatkov', + titles: ['Seznam 1', 'Seznam 2'], + filterPlaceholder: 'Vnesi ključno besedo', + noCheckedFormat: '{total} elementov', + hasCheckedFormat: '{checked}/{total} izbranih' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/sr.js b/src/locale/lang/sr.js new file mode 100644 index 0000000..a64b8aa --- /dev/null +++ b/src/locale/lang/sr.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Поништи' + }, + datepicker: { + now: 'Сад', + today: 'Данас', + cancel: 'Откажи', + clear: 'Бриши', + confirm: 'OK', + 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: 'Изабери', + noData: 'Нема података' + }, + pagination: { + goto: 'Иди на', + pagesize: '/страни', + total: 'Укупно {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Порука', + confirm: 'OK', + cancel: 'Откажи', + error: 'Неисправан унос' + }, + upload: { + deleteTip: 'притисни БРИШИ да обришеш', + delete: 'Бриши', + preview: 'Види', + continue: 'Настави' + }, + table: { + emptyText: 'Нема података', + confirmFilter: 'Потврди', + resetFilter: 'Ресетуј', + clearFilter: 'Све', + sumText: 'Збир' + }, + tree: { + emptyText: 'Нема података' + }, + transfer: { + noMatch: 'Нема резултата', + noData: 'Нема података', + titles: ['Листа 1', 'Листа 2'], // to be translated + filterPlaceholder: 'Унеси кључну реч', // to be translated + noCheckedFormat: '{total} ставки', // to be translated + hasCheckedFormat: '{checked}/{total} обележених' // to be translated + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/sv-SE.js b/src/locale/lang/sv-SE.js new file mode 100644 index 0000000..2f0ae4e --- /dev/null +++ b/src/locale/lang/sv-SE.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Töm' + }, + datepicker: { + now: 'Nu', + today: 'Idag', + cancel: 'Avbryt', + clear: 'Töm', + confirm: 'OK', + selectDate: 'Välj datum', + selectTime: 'Välj tid', + startDate: 'Startdatum', + startTime: 'Starttid', + endDate: 'Slutdatum', + endTime: 'Sluttid', + prevYear: 'Föregående år', + nextYear: 'Nästa år', + prevMonth: 'Föregående månad', + nextMonth: 'Nästa månad', + year: '', + month1: 'Januari', + month2: 'Februari', + month3: 'Mars', + month4: 'April', + month5: 'Maj', + month6: 'Juni', + month7: 'Juli', + month8: 'Augusti', + month9: 'September', + month10: 'Oktober', + month11: 'November', + month12: 'December', + // week: 'week', + weeks: { + sun: 'Sön', + mon: 'Mån', + tue: 'Tis', + wed: 'Ons', + thu: 'Tor', + fri: 'Fre', + sat: 'Lör' + }, + months: { + jan: 'Jan', + feb: 'Feb', + mar: 'Mar', + apr: 'Apr', + may: 'Maj', + jun: 'Jun', + jul: 'Jul', + aug: 'Aug', + sep: 'Sep', + oct: 'Okt', + nov: 'Nov', + dec: 'Dec' + } + }, + select: { + loading: 'Laddar', + noMatch: 'Hittade inget', + noData: 'Ingen data', + placeholder: 'Välj' + }, + cascader: { + noMatch: 'Hittade inget', + loading: 'Laddar', + placeholder: 'Välj', + noData: 'Ingen data' + }, + pagination: { + goto: 'Gå till', + pagesize: '/sida', + total: 'Totalt {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Meddelande', + confirm: 'OK', + cancel: 'Avbryt', + error: 'Felaktig inmatning' + }, + upload: { + deleteTip: 'press delete to remove', // to be translated + delete: 'Radera', + preview: 'Förhandsvisa', + continue: 'Fortsätt' + }, + table: { + emptyText: 'Inga Data', + confirmFilter: 'Bekräfta', + resetFilter: 'Återställ', + clearFilter: 'Alla', + sumText: 'Summa' + }, + tree: { + emptyText: 'Ingen data' + }, + transfer: { + noMatch: 'Hittade inget', + noData: 'Ingen 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 + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Bakåt' // to be translated + }, + popconfirm: { + confirmButtonText: 'Ja', + cancelButtonText: 'Nej' + } + } +}; diff --git a/src/locale/lang/ta.js b/src/locale/lang/ta.js new file mode 100644 index 0000000..2f28929 --- /dev/null +++ b/src/locale/lang/ta.js @@ -0,0 +1,119 @@ +export default { + el: { + colorpicker: { + confirm: 'உறுதி செய்', + clear: 'தெளிவாக்கு' + }, + datepicker: { + now: 'தற்போது', + today: 'இன்று', + cancel: 'ரத்து செய்', + 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 + year: 'வருடம்', + month1: 'ஜனவரி', + month2: 'பிப்ரவரி', + month3: 'மார்ச்', + month4: 'ஏப்ரல்', + month5: 'மே', + month6: 'ஜூன்', + month7: 'ஜூலை', + month8: 'ஆகஸ்ட்', + month9: 'செப்டம்பர்', + month10: 'அக்டோபர்', + month11: 'நவம்பர்', + month12: 'டிசம்பர்', + 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: 'தேர்வு செய்', + noData: 'தரவு இல்லை' + }, + pagination: { + goto: 'தேவையான் பகுதிக்கு செல்', + pagesize: '/page', + total: 'மொத்தம் {total}', + pageClassifier: '' + }, + messagebox: { + title: 'செய்தி', + confirm: 'உறுதி செய்', + cancel: 'ரத்து செய்', + error: 'பொருத்தாமில்லாத உள்ளீடு' + }, + upload: { + deleteTip: 'press delete to remove', // to be translated + delete: 'நீக்கு', + preview: 'முன்னோட்டம் பார்', + continue: 'தொடரு' + }, + table: { + emptyText: 'தரவு இல்லை', + confirmFilter: 'உறுதி செய்', + resetFilter: 'புதுமாற்றம் செய்', + clearFilter: 'அனைத்தும்', + sumText: 'கூட்டு' + }, + tree: { + emptyText: 'தரவு இல்லை' + }, + transfer: { + noMatch: 'பொருத்தமான தரவு கிடைக்கவில்லை', + noData: 'தரவு இல்லை', + titles: ['பட்டியல் 1', 'பட்டியல் 2'], + filterPlaceholder: 'சொல்லை உள்ளீடு செய்', + noCheckedFormat: '{total} items', // to be translated + hasCheckedFormat: '{checked}/{total} தேர்வு செய்யப்பட்டவைகள்' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/th.js b/src/locale/lang/th.js new file mode 100644 index 0000000..a175e7a --- /dev/null +++ b/src/locale/lang/th.js @@ -0,0 +1,120 @@ +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: '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: 'เลือก', + noData: 'ไม่พบข้อมูล' + }, + 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: ['List 1', 'List 2'], // to be translated + filterPlaceholder: 'กรอกคีย์เวิร์ด', + noCheckedFormat: '{total} items', // to be translated + hasCheckedFormat: '{checked}/{total} checked' // to be translated + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'ย้อนกลับ' + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/tk.js b/src/locale/lang/tk.js new file mode 100644 index 0000000..86dc9a6 --- /dev/null +++ b/src/locale/lang/tk.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Arassala' + }, + datepicker: { + now: 'Şuwagt', + today: 'Şügün', + cancel: 'Bes et', + clear: 'Arassala', + confirm: 'OK', + selectDate: 'Güni saýlaň', + selectTime: 'Wagty saýlaň', + startDate: 'Başlaýan güni', + startTime: 'Başlaýan wagty', + endDate: 'Gutarýan güni', + endTime: 'Gutarýan wagty', + prevYear: 'Previous Year', // to be translated + nextYear: 'Next Year', // to be translated + prevMonth: 'Previous Month', // to be translated + nextMonth: 'Next Month', // to be translated + year: '', + month1: 'Ýan', + month2: 'Few', + month3: 'Mar', + month4: 'Apr', + month5: 'Maý', + month6: 'Iýn', + month7: 'Iýl', + month8: 'Awg', + month9: 'Sen', + month10: 'Okt', + month11: 'Noý', + month12: 'Dek', + // week: 'week', + weeks: { + sun: 'Ýek', + mon: 'Duş', + tue: 'Siş', + wed: 'Çar', + thu: 'Pen', + fri: 'Ann', + sat: 'Şen' + }, + months: { + jan: 'Ýan', + feb: 'Few', + mar: 'Mar', + apr: 'Apr', + may: 'Maý', + jun: 'Iýn', + jul: 'Iýl', + aug: 'Awg', + sep: 'Sep', + oct: 'Okt', + nov: 'Noý', + dec: 'Dek' + } + }, + select: { + loading: 'Indirilýär', + noMatch: 'Hiçzat tapylmady', + noData: 'Hiçzat ýok', + placeholder: 'Saýla' + }, + cascader: { + noMatch: 'Hiçzat tapylmady', + loading: 'Indirilýär', + placeholder: 'Saýlaň', + noData: 'Hiçzat ýok' + }, + pagination: { + goto: 'Git', + pagesize: '/sahypa', + total: 'Umumy {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Hat', + confirm: 'OK', + cancel: 'Bes et', + error: 'Ýalňyş girizme' + }, + upload: { + deleteTip: 'Pozmak üçin "poz" düwmä basyň', + delete: 'Poz', + preview: 'Gör', + continue: 'Dowam et' + }, + table: { + emptyText: 'Maglumat ýok', + confirmFilter: 'Tassykla', + resetFilter: 'Arassala', + clearFilter: 'Hemmesi', + sumText: 'Jemi' + }, + tree: { + emptyText: 'Maglumat ýok' + }, + transfer: { + noMatch: 'Hiçzat tapylmady', + noData: 'Hiçzat ýok', + titles: ['Sanaw 1', 'Sanaw 2'], + filterPlaceholder: 'Gözleg sözlerini giriziň', + noCheckedFormat: '{total} sany', + hasCheckedFormat: '{checked}/{total} saýlanan' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/tr-TR.js b/src/locale/lang/tr-TR.js new file mode 100644 index 0000000..1984dbc --- /dev/null +++ b/src/locale/lang/tr-TR.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Onayla', + clear: 'Temizle' + }, + datepicker: { + now: 'Şimdi', + today: 'Bugün', + cancel: 'İptal', + clear: 'Temizle', + confirm: 'Onayla', + selectDate: 'Tarih seç', + selectTime: 'Saat seç', + startDate: 'Başlangıç Tarihi', + startTime: 'Başlangıç Saati', + endDate: 'Bitiş Tarihi', + endTime: 'Bitiş Saati', + prevYear: 'Önceki Yıl', + nextYear: 'Sonraki Yıl', + prevMonth: 'Önceki Ay', + nextMonth: 'Sonraki Ay', + year: '', + month1: 'Ocak', + month2: 'Şubat', + month3: 'Mart', + month4: 'Nisan', + month5: 'Mayıs', + month6: 'Haziran', + month7: 'Temmuz', + month8: 'Ağustos', + month9: 'Eylül', + month10: 'Ekim', + month11: 'Kasım', + month12: 'Aralık', + // week: 'week', + weeks: { + sun: 'Paz', + mon: 'Pzt', + tue: 'Sal', + wed: 'Çar', + thu: 'Per', + fri: 'Cum', + sat: 'Cmt' + }, + months: { + jan: 'Oca', + feb: 'Şub', + mar: 'Mar', + apr: 'Nis', + may: 'May', + jun: 'Haz', + jul: 'Tem', + aug: 'Ağu', + sep: 'Eyl', + oct: 'Eki', + nov: 'Kas', + dec: 'Ara' + } + }, + select: { + loading: 'Yükleniyor', + noMatch: 'Eşleşen veri bulunamadı', + noData: 'Veri yok', + placeholder: 'Seç' + }, + cascader: { + noMatch: 'Eşleşen veri bulunamadı', + loading: 'Yükleniyor', + placeholder: 'Seç', + noData: 'Veri yok' + }, + pagination: { + goto: 'Git', + pagesize: '/sayfa', + total: 'Toplam {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Mesaj', + confirm: 'Onayla', + cancel: 'İptal', + error: 'İllegal giriş' + }, + upload: { + deleteTip: 'kaldırmak için delete tuşuna bas', + delete: 'Sil', + preview: 'Görüntüle', + continue: 'Devam' + }, + table: { + emptyText: 'Veri yok', + confirmFilter: 'Onayla', + resetFilter: 'Sıfırla', + clearFilter: 'Hepsi', + sumText: 'Sum' + }, + tree: { + emptyText: 'Veri yok' + }, + transfer: { + noMatch: 'Eşleşen veri bulunamadı', + noData: 'Veri yok', + titles: ['Liste 1', 'Liste 2'], + filterPlaceholder: 'Anahtar kelimeleri gir', + noCheckedFormat: '{total} adet', + hasCheckedFormat: '{checked}/{total} seçildi' + }, + image: { + error: 'FAILED' // to be translated + }, + pageHeader: { + title: 'Back' // to be translated + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/ua.js b/src/locale/lang/ua.js new file mode 100644 index 0000000..9740665 --- /dev/null +++ b/src/locale/lang/ua.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Обрати', + clear: 'Очистити' + }, + datepicker: { + now: 'Зараз', + today: 'Сьогодні', + cancel: 'Відміна', + clear: 'Очистити', + confirm: 'OK', + 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: 'Обрати', + noData: 'Немає даних' + }, + pagination: { + goto: 'Перейти', + pagesize: 'на сторінці', + total: 'Всього {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Повідомлення', + confirm: 'OK', + 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} вибрано' + }, + image: { + error: 'ПОМИЛКА' + }, + pageHeader: { + title: 'Назад' + }, + popconfirm: { + confirmButtonText: 'Так', + cancelButtonText: 'Ні' + } + } +}; diff --git a/src/locale/lang/ug-CN.js b/src/locale/lang/ug-CN.js new file mode 100644 index 0000000..e12f181 --- /dev/null +++ b/src/locale/lang/ug-CN.js @@ -0,0 +1,120 @@ +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: 'تاللاڭ', + noData: 'ئۇچۇر يوق' + }, + pagination: { + goto: 'كىيىنكى بەت', + pagesize: 'تال/بەت', + total: 'جەمئىي {total} تال', + pageClassifier: 'بەت' + }, + messagebox: { + title: 'ئەسكەرتىش', + confirm: 'جەزملەش', + cancel: 'بىكار قىلىش', + error: 'كىرگۈزگەن ئۇچۇرىڭىزدا خاتالىق بار!' + }, + upload: { + deleteTip: 'delete كۇنپكىسىنى بېسىپ ئۆچۈرەلەيسىز', + delete: 'ئۆچۈرۈش', + preview: 'رەسىمنى كۆرۈش', + continue: 'رەسىم يوللاش' + }, + table: { + emptyText: 'ئۇچۇر يوق', + confirmFilter: 'سۈزگۈچ', + resetFilter: 'قايتا تولدۇرۇش', + clearFilter: 'ھەممە', + sumText: 'جەمئىي' + }, + tree: { + emptyText: 'ئۇچۇر يوق' + }, + transfer: { + noMatch: 'ئۇچۇر تېپىلمىدى', + noData: 'ئۇچۇر يوق', + titles: ['جەدۋەل 1', 'جەدۋەل 2'], + filterPlaceholder: 'ئىزدىمەكچى بولغان مەزمۇننى كىرگۈزۈڭ', + noCheckedFormat: 'جەمئىي {total} تۈر', + hasCheckedFormat: 'تاللانغىنى {checked}/{total} تۈر' + }, + image: { + error: 'مەغلۇب بولدى' + }, + pageHeader: { + title: 'قايتىش' + }, + popconfirm: { + confirmButtonText: 'ھەئە', + cancelButtonText: 'ياق' + } + } +}; diff --git a/src/locale/lang/uz-UZ.js b/src/locale/lang/uz-UZ.js new file mode 100644 index 0000000..39ac99f --- /dev/null +++ b/src/locale/lang/uz-UZ.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'Qabul qilish', + clear: 'Tozalash' + }, + datepicker: { + now: 'Hozir', + today: 'Bugun', + cancel: 'Bekor qilish', + clear: 'Tozalash', + confirm: 'Qabul qilish', + selectDate: 'Kunni tanlash', + selectTime: 'Soatni tanlash', + startDate: 'Boshlanish sanasi', + startTime: 'Boshlanish vaqti', + endDate: 'Tugash sanasi', + endTime: 'Tugash vaqti', + prevYear: 'Oʻtgan yil', + nextYear: 'Kelgusi yil', + prevMonth: 'Oʻtgan oy', + nextMonth: 'Kelgusi oy', + year: 'Yil', + month1: 'Yanvar', + month2: 'Fevral', + month3: 'Mart', + month4: 'Aprel', + month5: 'May', + month6: 'Iyun', + month7: 'Iyul', + month8: 'Avgust', + month9: 'Sentabr', + month10: 'Oktabr', + month11: 'Noyabr', + month12: 'Dekabr', + week: 'Hafta', + weeks: { + sun: 'Yak', + mon: 'Dush', + tue: 'Sesh', + wed: 'Chor', + thu: 'Pay', + fri: 'Jum', + sat: 'Shan' + }, + months: { + jan: 'Yan', + feb: 'Fev', + mar: 'Mar', + apr: 'Apr', + may: 'May', + jun: 'Iyun', + jul: 'Iyul', + aug: 'Avg', + sep: 'Sen', + oct: 'Okt', + nov: 'Noy', + dec: 'Dek' + } + }, + select: { + loading: 'Yuklanmoqda', + noMatch: 'Mos maʼlumot yoʻq', + noData: 'Maʼlumot yoʻq', + placeholder: 'Tanladizngiz' + }, + cascader: { + noMatch: 'Mos maʼlumot topilmadi', + loading: 'Yuklanmoqda', + placeholder: 'Tanlash', + noData: 'Maʼlumot yoʻq' + }, + pagination: { + goto: 'Oʻtish', + pagesize: '/sahifa', + total: 'Barchasi {total} ta', + pageClassifier: '' + }, + messagebox: { + title: 'Xabar', + confirm: 'Qabul qilish', + cancel: 'Bekor qilish', + error: 'Xatolik' + }, + upload: { + deleteTip: 'Oʻchirish tugmasini bosib oʻchiring', + delete: 'Oʻchirish', + preview: 'Oldin koʻrish', + continue: 'Davom qilish' + }, + table: { + emptyText: 'Boʻsh', + confirmFilter: 'Qabul qilish', + resetFilter: 'Oldingi holatga qaytarish', + clearFilter: 'Jami', + sumText: 'Summasi' + }, + tree: { + emptyText: 'Maʼlumot yoʻq' + }, + transfer: { + noMatch: 'Mos maʼlumot topilmadi', + noData: 'Maʼlumot yoʻq', + titles: ['1-jadval', '2-jadval'], + filterPlaceholder: 'Kalit soʻzni kiriting', + noCheckedFormat: '{total} ta element', + hasCheckedFormat: '{checked}/{total} ta belgilandi' + }, + image: { + error: 'Xatolik' + }, + pageHeader: { + title: 'Orqaga' + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/locale/lang/vi.js b/src/locale/lang/vi.js new file mode 100644 index 0000000..3378164 --- /dev/null +++ b/src/locale/lang/vi.js @@ -0,0 +1,120 @@ +export default { + el: { + colorpicker: { + confirm: 'OK', + clear: 'Xóa' + }, + datepicker: { + now: 'Hiện tại', + today: 'Hôm nay', + cancel: 'Hủy', + clear: 'Xóa', + confirm: 'OK', + selectDate: 'Chọn ngày', + selectTime: 'Chọn giờ', + startDate: 'Ngày bắt đầu', + startTime: 'Thời gian bắt đầu', + endDate: 'Ngày kết thúc', + endTime: 'Thời gian kết thúc', + prevYear: 'Năm trước', + nextYear: 'Năm tới', + prevMonth: 'Tháng trước', + nextMonth: 'Tháng tới', + year: 'Năm', + month1: 'Tháng 1', + month2: 'Tháng 2', + month3: 'Tháng 3', + month4: 'Tháng 4', + month5: 'Tháng 5', + month6: 'Tháng 6', + month7: 'Tháng 7', + month8: 'Tháng 8', + month9: 'Tháng 9', + month10: 'Tháng 10', + month11: 'Tháng 11', + month12: 'Tháng 12', + // week: 'week', + weeks: { + sun: 'CN', + mon: 'T2', + tue: 'T3', + wed: 'T4', + thu: 'T5', + fri: 'T6', + sat: 'T7' + }, + months: { + jan: 'Th.1', + feb: 'Th.2', + mar: 'Th.3', + apr: 'Th.4', + may: 'Th.5', + jun: 'Th.6', + jul: 'Th.7', + aug: 'Th.8', + sep: 'Th.9', + oct: 'Th.10', + nov: 'Th.11', + dec: 'Th.12' + } + }, + select: { + loading: 'Đang tải', + noMatch: 'Dữ liệu không phù hợp', + noData: 'Không tìm thấy dữ liệu', + placeholder: 'Chọn' + }, + cascader: { + noMatch: 'Dữ liệu không phù hợp', + loading: 'Đang tải', + placeholder: 'Chọn', + noData: 'Không tìm thấy dữ liệu' + }, + pagination: { + goto: 'Nhảy tới', + pagesize: '/trang', + total: 'Tổng {total}', + pageClassifier: '' + }, + messagebox: { + title: 'Thông báo', + confirm: 'OK', + cancel: 'Hủy', + error: 'Dữ liệu không hợp lệ' + }, + upload: { + deleteTip: 'Nhấn xoá để xoá', + delete: 'Xóa', + preview: 'Xem trước', + continue: 'Tiếp tục' + }, + table: { + emptyText: 'Không có dữ liệu', + confirmFilter: 'Xác nhận', + resetFilter: 'Làm mới', + clearFilter: 'Xóa hết', + sumText: 'Tổng' + }, + tree: { + emptyText: 'Không có dữ liệu' + }, + transfer: { + noMatch: 'Dữ liệu không phù hợp', + noData: 'Không tìm thấy dữ liệu', + titles: ['Danh sách 1', 'Danh sách 2'], + filterPlaceholder: 'Nhập từ khóa', + noCheckedFormat: '{total} mục', + hasCheckedFormat: '{checked}/{total} đã chọn ' + }, + image: { + error: 'LỖI' + }, + pageHeader: { + title: 'Quay lại' + }, + popconfirm: { + confirmButtonText: 'Ok', + cancelButtonText: 'Huỷ' + } + } +}; diff --git a/src/locale/lang/zh-CN.js b/src/locale/lang/zh-CN.js new file mode 100644 index 0000000..b19a1d7 --- /dev/null +++ b/src/locale/lang/zh-CN.js @@ -0,0 +1,123 @@ +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: '一月', + feb: '二月', + mar: '三月', + apr: '四月', + may: '五月', + jun: '六月', + jul: '七月', + aug: '八月', + sep: '九月', + oct: '十月', + nov: '十一月', + dec: '十二月' + } + }, + select: { + loading: '加载中', + noMatch: '无匹配数据', + noData: '无数据', + placeholder: '请选择' + }, + cascader: { + noMatch: '无匹配数据', + loading: '加载中', + placeholder: '请选择', + noData: '暂无数据' + }, + pagination: { + goto: '前往', + pagesize: '条/页', + total: '共 {total} 条', + pageClassifier: '页' + }, + messagebox: { + title: '提示', + confirm: '确定', + cancel: '取消', + gotIt: '知道了', + yes: '是', + no: '否', + error: '输入的数据不合法!' + }, + upload: { + deleteTip: '按 delete 键可删除', + delete: '删除', + preview: '查看图片', + continue: '继续上传' + }, + table: { + emptyText: '暂无数据', + confirmFilter: '筛选', + resetFilter: '重置', + clearFilter: '全部', + sumText: '合计' + }, + tree: { + emptyText: '暂无数据' + }, + transfer: { + noMatch: '无匹配数据', + noData: '无数据', + titles: ['列表 1', '列表 2'], + filterPlaceholder: '请输入搜索内容', + noCheckedFormat: '共 {total} 项', + hasCheckedFormat: '已选 {checked}/{total} 项' + }, + image: { + error: '加载失败' + }, + pageHeader: { + title: '返回' + }, + popconfirm: { + confirmButtonText: '确定', + cancelButtonText: '取消' + } + } +}; diff --git a/src/locale/lang/zh-TW.js b/src/locale/lang/zh-TW.js new file mode 100644 index 0000000..43312be --- /dev/null +++ b/src/locale/lang/zh-TW.js @@ -0,0 +1,120 @@ +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: '一月', + feb: '二月', + mar: '三月', + apr: '四月', + may: '五月', + jun: '六月', + jul: '七月', + aug: '八月', + sep: '九月', + oct: '十月', + nov: '十一月', + dec: '十二月' + } + }, + select: { + loading: '加載中', + noMatch: '無匹配資料', + noData: '無資料', + placeholder: '請選擇' + }, + cascader: { + noMatch: '無匹配資料', + loading: '加載中', + placeholder: '請選擇', + noData: '無資料' + }, + pagination: { + goto: '前往', + pagesize: '項/頁', + total: '共 {total} 項', + pageClassifier: '頁' + }, + messagebox: { + title: '提示', + confirm: '確定', + cancel: '取消', + error: '輸入的資料不符規定!' + }, + upload: { + deleteTip: '按 delete 鍵可刪除', + delete: '刪除', + preview: '查看圖片', + continue: '繼續上傳' + }, + table: { + emptyText: '暫無資料', + confirmFilter: '篩選', + resetFilter: '重置', + clearFilter: '全部', + sumText: 'Sum' // to be translated + }, + tree: { + emptyText: '暫無資料' + }, + transfer: { + noMatch: '無匹配資料', + noData: '無資料', + titles: ['List 1', 'List 2'], // to be translated + filterPlaceholder: 'Enter keyword', // to be translated + noCheckedFormat: '{total} items', // to be translated + hasCheckedFormat: '{checked}/{total} checked' // to be translated + }, + image: { + error: '加載失敗' + }, + pageHeader: { + title: '返回' + }, + popconfirm: { + confirmButtonText: 'Yes', // to be translated + cancelButtonText: 'No' // to be translated + } + } +}; diff --git a/src/mixins/emitter.js b/src/mixins/emitter.js new file mode 100644 index 0000000..c12d167 --- /dev/null +++ b/src/mixins/emitter.js @@ -0,0 +1,33 @@ +function broadcast(componentName, eventName, params) { + this.$children.forEach(child => { + var name = child.$options.componentName; + + if (name === componentName) { + child.$emit.apply(child, [eventName].concat(params)); + } else { + broadcast.apply(child, [componentName, eventName].concat([params])); + } + }); +} +export default { + methods: { + dispatch(componentName, eventName, params) { + var parent = this.$parent || this.$root; + var name = parent.$options.componentName; + + while (parent && (!name || name !== componentName)) { + parent = parent.$parent; + + if (parent) { + name = parent.$options.componentName; + } + } + if (parent) { + parent.$emit.apply(parent, [eventName].concat(params)); + } + }, + broadcast(componentName, eventName, params) { + broadcast.call(this, componentName, eventName, params); + } + } +}; diff --git a/src/mixins/focus.js b/src/mixins/focus.js new file mode 100644 index 0000000..768ba50 --- /dev/null +++ b/src/mixins/focus.js @@ -0,0 +1,9 @@ +export default function(ref) { + return { + methods: { + focus() { + this.$refs[ref].focus(); + } + } + }; +}; diff --git a/src/mixins/locale.js b/src/mixins/locale.js new file mode 100644 index 0000000..f41173f --- /dev/null +++ b/src/mixins/locale.js @@ -0,0 +1,9 @@ +import { t } from 'element-ui/src/locale'; + +export default { + methods: { + t(...args) { + return t.apply(this, args); + } + } +}; diff --git a/src/mixins/migrating.js b/src/mixins/migrating.js new file mode 100644 index 0000000..cf7400b --- /dev/null +++ b/src/mixins/migrating.js @@ -0,0 +1,54 @@ +import { kebabCase } from 'element-ui/src/utils/util'; +/** + * Show migrating guide in browser console. + * + * Usage: + * import Migrating from 'element-ui/src/mixins/migrating'; + * + * mixins: [Migrating] + * + * add getMigratingConfig method for your component. + * getMigratingConfig() { + * return { + * props: { + * 'allow-no-selection': 'allow-no-selection is removed.', + * 'selection-mode': 'selection-mode is removed.' + * }, + * events: { + * selectionchange: 'selectionchange is renamed to selection-change.' + * } + * }; + * }, + */ +export default { + mounted() { + if (process.env.NODE_ENV === 'production') return; + if (!this.$vnode) return; + const { props = {}, events = {} } = this.getMigratingConfig(); + const { data, componentOptions } = this.$vnode; + const definedProps = data.attrs || {}; + const definedEvents = componentOptions.listeners || {}; + + for (let propName in definedProps) { + propName = kebabCase(propName); // compatible with camel case + if (props[propName]) { + console.warn(`[Element Migrating][${this.$options.name}][Attribute]: ${props[propName]}`); + } + } + + for (let eventName in definedEvents) { + eventName = kebabCase(eventName); // compatible with camel case + if (events[eventName]) { + console.warn(`[Element Migrating][${this.$options.name}][Event]: ${events[eventName]}`); + } + } + }, + methods: { + getMigratingConfig() { + return { + props: {}, + events: {} + }; + } + } +}; diff --git a/src/transitions/collapse-transition.js b/src/transitions/collapse-transition.js new file mode 100644 index 0000000..5e25d52 --- /dev/null +++ b/src/transitions/collapse-transition.js @@ -0,0 +1,77 @@ +import { addClass, removeClass } from 'element-ui/src/utils/dom'; + +class Transition { + beforeEnter(el) { + addClass(el, 'collapse-transition'); + if (!el.dataset) el.dataset = {}; + + el.dataset.oldPaddingTop = el.style.paddingTop; + el.dataset.oldPaddingBottom = el.style.paddingBottom; + + el.style.height = '0'; + el.style.paddingTop = 0; + el.style.paddingBottom = 0; + } + + enter(el) { + el.dataset.oldOverflow = el.style.overflow; + if (el.scrollHeight !== 0) { + el.style.height = el.scrollHeight + 'px'; + el.style.paddingTop = el.dataset.oldPaddingTop; + el.style.paddingBottom = el.dataset.oldPaddingBottom; + } else { + el.style.height = ''; + el.style.paddingTop = el.dataset.oldPaddingTop; + el.style.paddingBottom = el.dataset.oldPaddingBottom; + } + + el.style.overflow = 'hidden'; + } + + afterEnter(el) { + // for safari: remove class then reset height is necessary + removeClass(el, 'collapse-transition'); + el.style.height = ''; + el.style.overflow = el.dataset.oldOverflow; + } + + beforeLeave(el) { + if (!el.dataset) el.dataset = {}; + el.dataset.oldPaddingTop = el.style.paddingTop; + el.dataset.oldPaddingBottom = el.style.paddingBottom; + el.dataset.oldOverflow = el.style.overflow; + + el.style.height = el.scrollHeight + 'px'; + el.style.overflow = 'hidden'; + } + + leave(el) { + if (el.scrollHeight !== 0) { + // for safari: add class after set height, or it will jump to zero height suddenly, weired + addClass(el, 'collapse-transition'); + el.style.height = 0; + el.style.paddingTop = 0; + el.style.paddingBottom = 0; + } + } + + afterLeave(el) { + removeClass(el, 'collapse-transition'); + el.style.height = ''; + el.style.overflow = el.dataset.oldOverflow; + el.style.paddingTop = el.dataset.oldPaddingTop; + el.style.paddingBottom = el.dataset.oldPaddingBottom; + } +} + +export default { + name: 'ElCollapseTransition', + functional: true, + render(h, { children }) { + const data = { + on: new Transition() + }; + + return h('transition', data, children); + } +}; diff --git a/src/utils/after-leave.js b/src/utils/after-leave.js new file mode 100644 index 0000000..dd6cf2a --- /dev/null +++ b/src/utils/after-leave.js @@ -0,0 +1,27 @@ +/** + * Bind after-leave event for vue instance. Make sure after-leave is called in any browsers. + * + * @param {Vue} instance Vue instance. + * @param {Function} callback callback of after-leave event + * @param {Number} speed the speed of transition, default value is 300ms + * @param {Boolean} once weather bind after-leave once. default value is false. + */ +export default function(instance, callback, speed = 300, once = false) { + if (!instance || !callback) throw new Error('instance & callback is required'); + let called = false; + const afterLeaveCallback = function() { + if (called) return; + called = true; + if (callback) { + callback.apply(null, arguments); + } + }; + if (once) { + instance.$once('after-leave', afterLeaveCallback); + } else { + instance.$on('after-leave', afterLeaveCallback); + } + setTimeout(() => { + afterLeaveCallback(); + }, speed + 100); +}; diff --git a/src/utils/aria-dialog.js b/src/utils/aria-dialog.js new file mode 100644 index 0000000..c56ae42 --- /dev/null +++ b/src/utils/aria-dialog.js @@ -0,0 +1,90 @@ +import Utils from './aria-utils'; + +/** + * @constructor + * @desc Dialog object providing modal focus management. + * + * Assumptions: The element serving as the dialog container is present in the + * DOM and hidden. The dialog container has role='dialog'. + * + * @param dialogId + * The ID of the element serving as the dialog container. + * @param focusAfterClosed + * Either the DOM node or the ID of the DOM node to focus when the + * dialog closes. + * @param focusFirst + * Optional parameter containing either the DOM node or the ID of the + * DOM node to focus when the dialog opens. If not specified, the + * first focusable element in the dialog will receive focus. + */ +var aria = aria || {}; +var tabEvent; + +aria.Dialog = function(dialog, focusAfterClosed, focusFirst) { + this.dialogNode = dialog; + if (this.dialogNode === null || this.dialogNode.getAttribute('role') !== 'dialog') { + throw new Error('Dialog() requires a DOM element with ARIA role of dialog.'); + } + + if (typeof focusAfterClosed === 'string') { + this.focusAfterClosed = document.getElementById(focusAfterClosed); + } else if (typeof focusAfterClosed === 'object') { + this.focusAfterClosed = focusAfterClosed; + } else { + this.focusAfterClosed = null; + } + + if (typeof focusFirst === 'string') { + this.focusFirst = document.getElementById(focusFirst); + } else if (typeof focusFirst === 'object') { + this.focusFirst = focusFirst; + } else { + this.focusFirst = null; + } + + if (this.focusFirst) { + this.focusFirst.focus(); + } else { + Utils.focusFirstDescendant(this.dialogNode); + } + + this.lastFocus = document.activeElement; + tabEvent = (e) => { + this.trapFocus(e); + }; + this.addListeners(); +}; + +aria.Dialog.prototype.addListeners = function() { + document.addEventListener('focus', tabEvent, true); +}; + +aria.Dialog.prototype.removeListeners = function() { + document.removeEventListener('focus', tabEvent, true); +}; + +aria.Dialog.prototype.closeDialog = function() { + this.removeListeners(); + if (this.focusAfterClosed) { + setTimeout(() => { + this.focusAfterClosed.focus(); + }); + } +}; + +aria.Dialog.prototype.trapFocus = function(event) { + if (Utils.IgnoreUtilFocusChanges) { + return; + } + if (this.dialogNode.contains(event.target)) { + this.lastFocus = event.target; + } else { + Utils.focusFirstDescendant(this.dialogNode); + if (this.lastFocus === document.activeElement) { + Utils.focusLastDescendant(this.dialogNode); + } + this.lastFocus = document.activeElement; + } +}; + +export default aria.Dialog; diff --git a/src/utils/aria-utils.js b/src/utils/aria-utils.js new file mode 100644 index 0000000..5bccfab --- /dev/null +++ b/src/utils/aria-utils.js @@ -0,0 +1,122 @@ +var aria = aria || {}; + +aria.Utils = aria.Utils || {}; + +/** + * @desc Set focus on descendant nodes until the first focusable element is + * found. + * @param element + * DOM node for which to find the first focusable descendant. + * @returns + * true if a focusable element is found and focus is set. + */ +aria.Utils.focusFirstDescendant = function(element) { + for (var i = 0; i < element.childNodes.length; i++) { + var child = element.childNodes[i]; + if (aria.Utils.attemptFocus(child) || aria.Utils.focusFirstDescendant(child)) { + return true; + } + } + return false; +}; + +/** + * @desc Find the last descendant node that is focusable. + * @param element + * DOM node for which to find the last focusable descendant. + * @returns + * true if a focusable element is found and focus is set. + */ + +aria.Utils.focusLastDescendant = function(element) { + for (var i = element.childNodes.length - 1; i >= 0; i--) { + var child = element.childNodes[i]; + if (aria.Utils.attemptFocus(child) || aria.Utils.focusLastDescendant(child)) { + return true; + } + } + return false; +}; + +/** + * @desc Set Attempt to set focus on the current node. + * @param element + * The node to attempt to focus on. + * @returns + * true if element is focused. + */ +aria.Utils.attemptFocus = function(element) { + if (!aria.Utils.isFocusable(element)) { + return false; + } + aria.Utils.IgnoreUtilFocusChanges = true; + try { + element.focus(); + } catch (e) { + } + aria.Utils.IgnoreUtilFocusChanges = false; + return (document.activeElement === element); +}; + +aria.Utils.isFocusable = function(element) { + if (element.tabIndex > 0 || (element.tabIndex === 0 && element.getAttribute('tabIndex') !== null)) { + return true; + } + + if (element.disabled) { + return false; + } + + switch (element.nodeName) { + case 'A': + return !!element.href && element.rel !== 'ignore'; + case 'INPUT': + return element.type !== 'hidden' && element.type !== 'file'; + case 'BUTTON': + case 'SELECT': + case 'TEXTAREA': + return true; + default: + return false; + } +}; + +/** + * 触发一个事件 + * mouseenter, mouseleave, mouseover, keyup, change, click 等 + * @param {Element} elm + * @param {String} name + * @param {*} opts + */ +aria.Utils.triggerEvent = function(elm, name, ...opts) { + let eventName; + + if (/^mouse|click/.test(name)) { + eventName = 'MouseEvents'; + } else if (/^key/.test(name)) { + eventName = 'KeyboardEvent'; + } else { + eventName = 'HTMLEvents'; + } + const evt = document.createEvent(eventName); + + evt.initEvent(name, ...opts); + elm.dispatchEvent + ? elm.dispatchEvent(evt) + : elm.fireEvent('on' + name, evt); + + return elm; +}; + +aria.Utils.keys = { + tab: 9, + enter: 13, + space: 32, + left: 37, + up: 38, + right: 39, + down: 40, + esc: 27 +}; + +export default aria.Utils; diff --git a/src/utils/clickoutside.js b/src/utils/clickoutside.js new file mode 100644 index 0000000..e002548 --- /dev/null +++ b/src/utils/clickoutside.js @@ -0,0 +1,76 @@ +import Vue from 'vue'; +import { on } from 'element-ui/src/utils/dom'; + +const nodeList = []; +const ctx = '@@clickoutsideContext'; + +let startClick; +let seed = 0; + +!Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e)); + +!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 点击元素外面才会触发的事件 + * @example + * ```vue + *
+ * ``` + */ +export default { + bind(el, binding, vnode) { + nodeList.push(el); + const id = seed++; + el[ctx] = { + id, + documentHandler: createDocumentHandler(el, binding, vnode), + methodName: binding.expression, + bindingFn: binding.value + }; + }, + + update(el, binding, vnode) { + el[ctx].documentHandler = createDocumentHandler(el, binding, vnode); + el[ctx].methodName = binding.expression; + el[ctx].bindingFn = binding.value; + }, + + unbind(el) { + let len = nodeList.length; + + for (let i = 0; i < len; i++) { + if (nodeList[i][ctx].id === el[ctx].id) { + nodeList.splice(i, 1); + break; + } + } + delete el[ctx]; + } +}; diff --git a/src/utils/date-util.js b/src/utils/date-util.js new file mode 100644 index 0000000..96f254e --- /dev/null +++ b/src/utils/date-util.js @@ -0,0 +1,292 @@ +import fecha from 'element-ui/src/utils/date'; +import { t } from 'element-ui/src/locale'; + +const weeks = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; +const months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']; + +const newArray = function(start, end) { + let result = []; + for (let i = start; i <= end; i++) { + result.push(i); + } + return result; +}; + +export const getI18nSettings = () => { + return { + dayNamesShort: weeks.map(week => t(`el.datepicker.weeks.${ week }`)), + dayNames: weeks.map(week => t(`el.datepicker.weeks.${ week }`)), + monthNamesShort: months.map(month => t(`el.datepicker.months.${ month }`)), + monthNames: months.map((month, index) => t(`el.datepicker.month${ index + 1 }`)), + amPm: ['am', 'pm'] + }; +}; + +export const toDate = function(date) { + return isDate(date) ? new Date(date) : null; +}; + +export const isDate = function(date) { + if (date === null || date === undefined) return false; + if (isNaN(new Date(date).getTime())) return false; + if (Array.isArray(date)) return false; // deal with `new Date([ new Date() ]) -> new Date()` + return true; +}; + +export const isDateObject = function(val) { + return val instanceof Date; +}; + +export const formatDate = function(date, format) { + date = toDate(date); + if (!date) return ''; + return fecha.format(date, format || 'yyyy-MM-dd', getI18nSettings()); +}; + +export const parseDate = function(string, format) { + return fecha.parse(string, format || 'yyyy-MM-dd', getI18nSettings()); +}; + +export const getDayCountOfMonth = function(year, month) { + if (month === 3 || month === 5 || month === 8 || month === 10) { + return 30; + } + + if (month === 1) { + if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) { + return 29; + } else { + return 28; + } + } + + return 31; +}; + +export const getDayCountOfYear = function(year) { + const isLeapYear = year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0); + return isLeapYear ? 366 : 365; +}; + +export const getFirstDayOfMonth = function(date) { + const temp = new Date(date.getTime()); + temp.setDate(1); + return temp.getDay(); +}; + +// see: https://stackoverflow.com/questions/3674539/incrementing-a-date-in-javascript +// {prev, next} Date should work for Daylight Saving Time +// Adding 24 * 60 * 60 * 1000 does not work in the above scenario +export const prevDate = function(date, amount = 1) { + return new Date(date.getFullYear(), date.getMonth(), date.getDate() - amount); +}; + +export const nextDate = function(date, amount = 1) { + return new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount); +}; + +export const getStartDateOfMonth = function(year, month) { + const result = new Date(year, month, 1); + const day = result.getDay(); + + if (day === 0) { + return prevDate(result, 7); + } else { + return prevDate(result, day); + } +}; + +export const getWeekNumber = function(src) { + if (!isDate(src)) return null; + const date = new Date(src.getTime()); + date.setHours(0, 0, 0, 0); + // Thursday in current week decides the year. + date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7); + // January 4 is always in week 1. + const week1 = new Date(date.getFullYear(), 0, 4); + // Adjust to Thursday in week 1 and count number of weeks from date to week 1. + // Rounding should be fine for Daylight Saving Time. Its shift should never be more than 12 hours. + return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7); +}; + +export const getRangeHours = function(ranges) { + const hours = []; + let disabledHours = []; + + (ranges || []).forEach(range => { + const value = range.map(date => date.getHours()); + + disabledHours = disabledHours.concat(newArray(value[0], value[1])); + }); + + if (disabledHours.length) { + for (let i = 0; i < 24; i++) { + hours[i] = disabledHours.indexOf(i) === -1; + } + } else { + for (let i = 0; i < 24; i++) { + hours[i] = false; + } + } + + return hours; +}; + +export const getPrevMonthLastDays = (date, amount) => { + if (amount <= 0) return []; + const temp = new Date(date.getTime()); + temp.setDate(0); + const lastDay = temp.getDate(); + return range(amount).map((_, index) => lastDay - (amount - index - 1)); +}; + +export const getMonthDays = (date) => { + const temp = new Date(date.getFullYear(), date.getMonth() + 1, 0); + const days = temp.getDate(); + return range(days).map((_, index) => index + 1); +}; + +function setRangeData(arr, start, end, value) { + for (let i = start; i < end; i++) { + arr[i] = value; + } +} + +export const getRangeMinutes = function(ranges, hour) { + const minutes = new Array(60); + + if (ranges.length > 0) { + ranges.forEach(range => { + const start = range[0]; + const end = range[1]; + const startHour = start.getHours(); + const startMinute = start.getMinutes(); + const endHour = end.getHours(); + const endMinute = end.getMinutes(); + if (startHour === hour && endHour !== hour) { + setRangeData(minutes, startMinute, 60, true); + } else if (startHour === hour && endHour === hour) { + setRangeData(minutes, startMinute, endMinute + 1, true); + } else if (startHour !== hour && endHour === hour) { + setRangeData(minutes, 0, endMinute + 1, true); + } else if (startHour < hour && endHour > hour) { + setRangeData(minutes, 0, 60, true); + } + }); + } else { + setRangeData(minutes, 0, 60, true); + } + return minutes; +}; + +export const range = function(n) { + // see https://stackoverflow.com/questions/3746725/create-a-javascript-array-containing-1-n + return Array.apply(null, {length: n}).map((_, n) => n); +}; + +export const modifyDate = function(date, y, m, d) { + return new Date(y, m, d, date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); +}; + +export const modifyTime = function(date, h, m, s, ms) { + return new Date(date.getFullYear(), date.getMonth(), date.getDate(), h, m, s, ms === undefined ? date.getMilliseconds() : ms); +}; + +export const modifyWithTimeString = (date, time) => { + if (date == null || !time) { + return date; + } + time = parseDate(time, 'HH:mm:ss.SSS'); + return modifyTime(date, time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds()); +}; + +export const clearTime = function(date) { + return new Date(date.getFullYear(), date.getMonth(), date.getDate()); +}; + +export const clearMilliseconds = function(date) { + return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0); +}; + +export const limitTimeRange = function(date, ranges, format = 'HH:mm:ss') { + // TODO: refactory a more elegant solution + if (ranges.length === 0) return date; + const normalizeDate = date => fecha.parse(fecha.format(date, format), format); + const ndate = normalizeDate(date); + const nranges = ranges.map(range => range.map(normalizeDate)); + if (nranges.some(nrange => ndate >= nrange[0] && ndate <= nrange[1])) return date; + + let minDate = nranges[0][0]; + let maxDate = nranges[0][0]; + + nranges.forEach(nrange => { + minDate = new Date(Math.min(nrange[0], minDate)); + maxDate = new Date(Math.max(nrange[1], minDate)); + }); + + const ret = ndate < minDate ? minDate : maxDate; + // preserve Year/Month/Date + return modifyDate( + ret, + date.getFullYear(), + date.getMonth(), + date.getDate() + ); +}; + +export const timeWithinRange = function(date, selectableRange, format) { + const limitedDate = limitTimeRange(date, selectableRange, format); + return limitedDate.getTime() === date.getTime(); +}; + +export const changeYearMonthAndClampDate = function(date, year, month) { + // clamp date to the number of days in `year`, `month` + // eg: (2010-1-31, 2010, 2) => 2010-2-28 + const monthDate = Math.min(date.getDate(), getDayCountOfMonth(year, month)); + return modifyDate(date, year, month, monthDate); +}; + +export const prevMonth = function(date) { + const year = date.getFullYear(); + const month = date.getMonth(); + return month === 0 + ? changeYearMonthAndClampDate(date, year - 1, 11) + : changeYearMonthAndClampDate(date, year, month - 1); +}; + +export const nextMonth = function(date) { + const year = date.getFullYear(); + const month = date.getMonth(); + return month === 11 + ? changeYearMonthAndClampDate(date, year + 1, 0) + : changeYearMonthAndClampDate(date, year, month + 1); +}; + +export const prevYear = function(date, amount = 1) { + const year = date.getFullYear(); + const month = date.getMonth(); + return changeYearMonthAndClampDate(date, year - amount, month); +}; + +export const nextYear = function(date, amount = 1) { + const year = date.getFullYear(); + const month = date.getMonth(); + return changeYearMonthAndClampDate(date, year + amount, month); +}; + +export const extractDateFormat = function(format) { + return format + .replace(/\W?m{1,2}|\W?ZZ/g, '') + .replace(/\W?h{1,2}|\W?s{1,3}|\W?a/gi, '') + .trim(); +}; + +export const extractTimeFormat = function(format) { + return format + .replace(/\W?D{1,2}|\W?Do|\W?d{1,4}|\W?M{1,4}|\W?y{2,4}/g, '') + .trim(); +}; + +export const validateRangeInOneMonth = function(start, end) { + return (start.getMonth() === end.getMonth()) && (start.getFullYear() === end.getFullYear()); +}; diff --git a/src/utils/date.js b/src/utils/date.js new file mode 100644 index 0000000..001692c --- /dev/null +++ b/src/utils/date.js @@ -0,0 +1,368 @@ +/* Modified from https://github.com/taylorhakes/fecha + * + * The MIT License (MIT) + * + * Copyright (c) 2015 Taylor Hakes + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/*eslint-disable*/ +// 把 YYYY-MM-DD 改成了 yyyy-MM-dd +(function (main) { + 'use strict'; + + /** + * Parse or format dates + * @class fecha + */ + var fecha = {}; + var token = /d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g; + var twoDigits = '\\d\\d?'; + var threeDigits = '\\d{3}'; + var fourDigits = '\\d{4}'; + var word = '[^\\s]+'; + var literal = /\[([^]*?)\]/gm; + var noop = function () { + }; + + function regexEscape(str) { + return str.replace( /[|\\{()[^$+*?.-]/g, '\\$&'); + } + + function shorten(arr, sLen) { + var newArr = []; + for (var i = 0, len = arr.length; i < len; i++) { + newArr.push(arr[i].substr(0, sLen)); + } + return newArr; + } + + function monthUpdate(arrName) { + return function (d, v, i18n) { + var index = i18n[arrName].indexOf(v.charAt(0).toUpperCase() + v.substr(1).toLowerCase()); + if (~index) { + d.month = index; + } + }; + } + + function pad(val, len) { + val = String(val); + len = len || 2; + while (val.length < len) { + val = '0' + val; + } + return val; + } + + var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; + var monthNamesShort = shorten(monthNames, 3); + var dayNamesShort = shorten(dayNames, 3); + fecha.i18n = { + dayNamesShort: dayNamesShort, + dayNames: dayNames, + monthNamesShort: monthNamesShort, + monthNames: monthNames, + amPm: ['am', 'pm'], + DoFn: function DoFn(D) { + return D + ['th', 'st', 'nd', 'rd'][D % 10 > 3 ? 0 : (D - D % 10 !== 10) * D % 10]; + } + }; + + var formatFlags = { + D: function(dateObj) { + return dateObj.getDay(); + }, + DD: function(dateObj) { + return pad(dateObj.getDay()); + }, + Do: function(dateObj, i18n) { + return i18n.DoFn(dateObj.getDate()); + }, + d: function(dateObj) { + return dateObj.getDate(); + }, + dd: function(dateObj) { + return pad(dateObj.getDate()); + }, + ddd: function(dateObj, i18n) { + return i18n.dayNamesShort[dateObj.getDay()]; + }, + dddd: function(dateObj, i18n) { + return i18n.dayNames[dateObj.getDay()]; + }, + M: function(dateObj) { + return dateObj.getMonth() + 1; + }, + MM: function(dateObj) { + return pad(dateObj.getMonth() + 1); + }, + MMM: function(dateObj, i18n) { + return i18n.monthNamesShort[dateObj.getMonth()]; + }, + MMMM: function(dateObj, i18n) { + return i18n.monthNames[dateObj.getMonth()]; + }, + yy: function(dateObj) { + return pad(String(dateObj.getFullYear()), 4).substr(2); + }, + yyyy: function(dateObj) { + return pad(dateObj.getFullYear(), 4); + }, + h: function(dateObj) { + return dateObj.getHours() % 12 || 12; + }, + hh: function(dateObj) { + return pad(dateObj.getHours() % 12 || 12); + }, + H: function(dateObj) { + return dateObj.getHours(); + }, + HH: function(dateObj) { + return pad(dateObj.getHours()); + }, + m: function(dateObj) { + return dateObj.getMinutes(); + }, + mm: function(dateObj) { + return pad(dateObj.getMinutes()); + }, + s: function(dateObj) { + return dateObj.getSeconds(); + }, + ss: function(dateObj) { + return pad(dateObj.getSeconds()); + }, + S: function(dateObj) { + return Math.round(dateObj.getMilliseconds() / 100); + }, + SS: function(dateObj) { + return pad(Math.round(dateObj.getMilliseconds() / 10), 2); + }, + SSS: function(dateObj) { + return pad(dateObj.getMilliseconds(), 3); + }, + a: function(dateObj, i18n) { + return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1]; + }, + A: function(dateObj, i18n) { + return dateObj.getHours() < 12 ? i18n.amPm[0].toUpperCase() : i18n.amPm[1].toUpperCase(); + }, + ZZ: function(dateObj) { + var o = dateObj.getTimezoneOffset(); + return (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4); + } + }; + + var parseFlags = { + d: [twoDigits, function (d, v) { + d.day = v; + }], + Do: [twoDigits + word, function (d, v) { + d.day = parseInt(v, 10); + }], + M: [twoDigits, function (d, v) { + d.month = v - 1; + }], + yy: [twoDigits, function (d, v) { + var da = new Date(), cent = +('' + da.getFullYear()).substr(0, 2); + d.year = '' + (v > 68 ? cent - 1 : cent) + v; + }], + h: [twoDigits, function (d, v) { + d.hour = v; + }], + m: [twoDigits, function (d, v) { + d.minute = v; + }], + s: [twoDigits, function (d, v) { + d.second = v; + }], + yyyy: [fourDigits, function (d, v) { + d.year = v; + }], + S: ['\\d', function (d, v) { + d.millisecond = v * 100; + }], + SS: ['\\d{2}', function (d, v) { + d.millisecond = v * 10; + }], + SSS: [threeDigits, function (d, v) { + d.millisecond = v; + }], + D: [twoDigits, noop], + ddd: [word, noop], + MMM: [word, monthUpdate('monthNamesShort')], + MMMM: [word, monthUpdate('monthNames')], + a: [word, function (d, v, i18n) { + var val = v.toLowerCase(); + if (val === i18n.amPm[0]) { + d.isPm = false; + } else if (val === i18n.amPm[1]) { + d.isPm = true; + } + }], + ZZ: ['[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z', function (d, v) { + var parts = (v + '').match(/([+-]|\d\d)/gi), minutes; + + if (parts) { + minutes = +(parts[1] * 60) + parseInt(parts[2], 10); + d.timezoneOffset = parts[0] === '+' ? minutes : -minutes; + } + }] + }; + parseFlags.dd = parseFlags.d; + parseFlags.dddd = parseFlags.ddd; + parseFlags.DD = parseFlags.D; + parseFlags.mm = parseFlags.m; + parseFlags.hh = parseFlags.H = parseFlags.HH = parseFlags.h; + parseFlags.MM = parseFlags.M; + parseFlags.ss = parseFlags.s; + parseFlags.A = parseFlags.a; + + + // Some common format strings + fecha.masks = { + default: 'ddd MMM dd yyyy HH:mm:ss', + shortDate: 'M/D/yy', + mediumDate: 'MMM d, yyyy', + longDate: 'MMMM d, yyyy', + fullDate: 'dddd, MMMM d, yyyy', + shortTime: 'HH:mm', + mediumTime: 'HH:mm:ss', + longTime: 'HH:mm:ss.SSS' + }; + + /*** + * Format a date + * @method format + * @param {Date|number} dateObj + * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate' + */ + fecha.format = function (dateObj, mask, i18nSettings) { + var i18n = i18nSettings || fecha.i18n; + + if (typeof dateObj === 'number') { + dateObj = new Date(dateObj); + } + + if (Object.prototype.toString.call(dateObj) !== '[object Date]' || isNaN(dateObj.getTime())) { + throw new Error('Invalid Date in fecha.format'); + } + + mask = fecha.masks[mask] || mask || fecha.masks['default']; + + var literals = []; + + // Make literals inactive by replacing them with ?? + mask = mask.replace(literal, function($0, $1) { + literals.push($1); + return '@@@'; + }); + // Apply formatting rules + mask = mask.replace(token, function ($0) { + return $0 in formatFlags ? formatFlags[$0](dateObj, i18n) : $0.slice(1, $0.length - 1); + }); + // Inline literal values back into the formatted value + return mask.replace(/@@@/g, function() { + return literals.shift(); + }); + }; + + /** + * Parse a date string into an object, changes - into / + * @method parse + * @param {string} dateStr Date string + * @param {string} format Date parse format + * @returns {Date|boolean} + */ + fecha.parse = function (dateStr, format, i18nSettings) { + var i18n = i18nSettings || fecha.i18n; + + if (typeof format !== 'string') { + throw new Error('Invalid format in fecha.parse'); + } + + format = fecha.masks[format] || format; + + // Avoid regular expression denial of service, fail early for really long strings + // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS + if (dateStr.length > 1000) { + return null; + } + + var dateInfo = {}; + var parseInfo = []; + var literals = []; + format = format.replace(literal, function($0, $1) { + literals.push($1); + return '@@@'; + }); + var newFormat = regexEscape(format).replace(token, function ($0) { + if (parseFlags[$0]) { + var info = parseFlags[$0]; + parseInfo.push(info[1]); + return '(' + info[0] + ')'; + } + + return $0; + }); + newFormat = newFormat.replace(/@@@/g, function() { + return literals.shift(); + }); + var matches = dateStr.match(new RegExp(newFormat, 'i')); + if (!matches) { + return null; + } + + for (var i = 1; i < matches.length; i++) { + parseInfo[i - 1](dateInfo, matches[i], i18n); + } + + var today = new Date(); + if (dateInfo.isPm === true && dateInfo.hour != null && +dateInfo.hour !== 12) { + dateInfo.hour = +dateInfo.hour + 12; + } else if (dateInfo.isPm === false && +dateInfo.hour === 12) { + dateInfo.hour = 0; + } + + var date; + if (dateInfo.timezoneOffset != null) { + dateInfo.minute = +(dateInfo.minute || 0) - +dateInfo.timezoneOffset; + date = new Date(Date.UTC(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, + dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0)); + } else { + date = new Date(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, + dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0); + } + return date; + }; + + /* istanbul ignore next */ + if (typeof module !== 'undefined' && module.exports) { + module.exports = fecha; + } else if (typeof define === 'function' && define.amd) { + define(function () { + return fecha; + }); + } else { + main.fecha = fecha; + } +})(this); diff --git a/src/utils/dom.js b/src/utils/dom.js new file mode 100644 index 0000000..8d2c668 --- /dev/null +++ b/src/utils/dom.js @@ -0,0 +1,227 @@ +/* istanbul ignore next */ + +import Vue from 'vue'; + +const isServer = Vue.prototype.$isServer; +const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g; +const MOZ_HACK_REGEXP = /^moz([A-Z])/; +const ieVersion = isServer ? 0 : Number(document.documentMode); + +/* istanbul ignore next */ +const trim = function(string) { + return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, ''); +}; +/* istanbul ignore next */ +const camelCase = function(name) { + return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) { + return offset ? letter.toUpperCase() : letter; + }).replace(MOZ_HACK_REGEXP, 'Moz$1'); +}; + +/* istanbul ignore next */ +export const on = (function() { + if (!isServer && document.addEventListener) { + return function(element, event, handler) { + if (element && event && handler) { + element.addEventListener(event, handler, false); + } + }; + } else { + return function(element, event, handler) { + if (element && event && handler) { + element.attachEvent('on' + event, handler); + } + }; + } +})(); + +/* istanbul ignore next */ +export const off = (function() { + if (!isServer && document.removeEventListener) { + return function(element, event, handler) { + if (element && event) { + element.removeEventListener(event, handler, false); + } + }; + } else { + return function(element, event, handler) { + if (element && event) { + element.detachEvent('on' + event, handler); + } + }; + } +})(); + +/* istanbul ignore next */ +export const once = function(el, event, fn) { + var listener = function() { + if (fn) { + fn.apply(this, arguments); + } + off(el, event, listener); + }; + on(el, event, listener); +}; + +/* istanbul ignore next */ +export function hasClass(el, cls) { + if (!el || !cls) return false; + if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.'); + if (el.classList) { + return el.classList.contains(cls); + } else { + return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1; + } +}; + +/* istanbul ignore next */ +export function addClass(el, cls) { + if (!el) return; + var curClass = el.className; + var classes = (cls || '').split(' '); + + for (var i = 0, j = classes.length; i < j; i++) { + var clsName = classes[i]; + if (!clsName) continue; + + if (el.classList) { + el.classList.add(clsName); + } else if (!hasClass(el, clsName)) { + curClass += ' ' + clsName; + } + } + if (!el.classList) { + el.className = curClass; + } +}; + +/* istanbul ignore next */ +export function removeClass(el, cls) { + if (!el || !cls) return; + var classes = cls.split(' '); + var curClass = ' ' + el.className + ' '; + + for (var i = 0, j = classes.length; i < j; i++) { + var clsName = classes[i]; + if (!clsName) continue; + + if (el.classList) { + el.classList.remove(clsName); + } else if (hasClass(el, clsName)) { + curClass = curClass.replace(' ' + clsName + ' ', ' '); + } + } + if (!el.classList) { + el.className = trim(curClass); + } +}; + +/* istanbul ignore next */ +export const getStyle = ieVersion < 9 ? function(element, styleName) { + if (isServer) return; + if (!element || !styleName) return null; + styleName = camelCase(styleName); + if (styleName === 'float') { + styleName = 'styleFloat'; + } + try { + switch (styleName) { + case 'opacity': + try { + return element.filters.item('alpha').opacity / 100; + } catch (e) { + return 1.0; + } + default: + return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null); + } + } catch (e) { + return element.style[styleName]; + } +} : function(element, styleName) { + if (isServer) return; + if (!element || !styleName) return null; + styleName = camelCase(styleName); + if (styleName === 'float') { + styleName = 'cssFloat'; + } + try { + var computed = document.defaultView.getComputedStyle(element, ''); + return element.style[styleName] || computed ? computed[styleName] : null; + } catch (e) { + return element.style[styleName]; + } +}; + +/* istanbul ignore next */ +export function setStyle(element, styleName, value) { + if (!element || !styleName) return; + + if (typeof styleName === 'object') { + for (var prop in styleName) { + if (styleName.hasOwnProperty(prop)) { + setStyle(element, prop, styleName[prop]); + } + } + } else { + styleName = camelCase(styleName); + if (styleName === 'opacity' && ieVersion < 9) { + element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')'; + } else { + element.style[styleName] = value; + } + } +}; + +export const isScroll = (el, vertical) => { + if (isServer) return; + + const determinedDirection = vertical !== null || vertical !== undefined; + const overflow = determinedDirection + ? vertical + ? getStyle(el, 'overflow-y') + : getStyle(el, 'overflow-x') + : getStyle(el, 'overflow'); + + return overflow.match(/(scroll|auto)/); +}; + +export const getScrollContainer = (el, vertical) => { + if (isServer) return; + + let parent = el; + while (parent) { + if ([window, document, document.documentElement].includes(parent)) { + return window; + } + if (isScroll(parent, vertical)) { + return parent; + } + parent = parent.parentNode; + } + + return parent; +}; + +export const isInContainer = (el, container) => { + if (isServer || !el || !container) return false; + + const elRect = el.getBoundingClientRect(); + let containerRect; + + if ([window, document, document.documentElement, null, undefined].includes(container)) { + containerRect = { + top: 0, + right: window.innerWidth, + bottom: window.innerHeight, + left: 0 + }; + } else { + containerRect = container.getBoundingClientRect(); + } + + return elRect.top < containerRect.bottom && + elRect.bottom > containerRect.top && + elRect.right > containerRect.left && + elRect.left < containerRect.right; +}; diff --git a/src/utils/menu/aria-menubar.js b/src/utils/menu/aria-menubar.js new file mode 100644 index 0000000..a5edc50 --- /dev/null +++ b/src/utils/menu/aria-menubar.js @@ -0,0 +1,14 @@ +import MenuItem from './aria-menuitem'; + +const Menu = function(domNode) { + this.domNode = domNode; + this.init(); +}; + +Menu.prototype.init = function() { + let menuChildren = this.domNode.childNodes; + [].filter.call(menuChildren, child => child.nodeType === 1).forEach(child => { + new MenuItem(child); // eslint-disable-line + }); +}; +export default Menu; diff --git a/src/utils/menu/aria-menuitem.js b/src/utils/menu/aria-menuitem.js new file mode 100644 index 0000000..3431ac0 --- /dev/null +++ b/src/utils/menu/aria-menuitem.js @@ -0,0 +1,49 @@ +import Utils from '../aria-utils'; +import SubMenu from './aria-submenu'; + +const MenuItem = function(domNode) { + this.domNode = domNode; + this.submenu = null; + this.init(); +}; + +MenuItem.prototype.init = function() { + this.domNode.setAttribute('tabindex', '0'); + let menuChild = this.domNode.querySelector('.el-menu'); + if (menuChild) { + this.submenu = new SubMenu(this, menuChild); + } + this.addListeners(); +}; + +MenuItem.prototype.addListeners = function() { + const keys = Utils.keys; + this.domNode.addEventListener('keydown', event => { + let prevDef = false; + switch (event.keyCode) { + case keys.down: + Utils.triggerEvent(event.currentTarget, 'mouseenter'); + this.submenu && this.submenu.gotoSubIndex(0); + prevDef = true; + break; + case keys.up: + Utils.triggerEvent(event.currentTarget, 'mouseenter'); + this.submenu && this.submenu.gotoSubIndex(this.submenu.subMenuItems.length - 1); + prevDef = true; + break; + case keys.tab: + Utils.triggerEvent(event.currentTarget, 'mouseleave'); + break; + case keys.enter: + case keys.space: + prevDef = true; + event.currentTarget.click(); + break; + } + if (prevDef) { + event.preventDefault(); + } + }); +}; + +export default MenuItem; diff --git a/src/utils/menu/aria-submenu.js b/src/utils/menu/aria-submenu.js new file mode 100644 index 0000000..06a77bb --- /dev/null +++ b/src/utils/menu/aria-submenu.js @@ -0,0 +1,59 @@ +import Utils from '../aria-utils'; + +const SubMenu = function(parent, domNode) { + this.domNode = domNode; + this.parent = parent; + this.subMenuItems = []; + this.subIndex = 0; + this.init(); +}; + +SubMenu.prototype.init = function() { + this.subMenuItems = this.domNode.querySelectorAll('li'); + this.addListeners(); +}; + +SubMenu.prototype.gotoSubIndex = function(idx) { + if (idx === this.subMenuItems.length) { + idx = 0; + } else if (idx < 0) { + idx = this.subMenuItems.length - 1; + } + this.subMenuItems[idx].focus(); + this.subIndex = idx; +}; + +SubMenu.prototype.addListeners = function() { + const keys = Utils.keys; + const parentNode = this.parent.domNode; + Array.prototype.forEach.call(this.subMenuItems, el => { + el.addEventListener('keydown', event => { + let prevDef = false; + switch (event.keyCode) { + case keys.down: + this.gotoSubIndex(this.subIndex + 1); + prevDef = true; + break; + case keys.up: + this.gotoSubIndex(this.subIndex - 1); + prevDef = true; + break; + case keys.tab: + Utils.triggerEvent(parentNode, 'mouseleave'); + break; + case keys.enter: + case keys.space: + prevDef = true; + event.currentTarget.click(); + break; + } + if (prevDef) { + event.preventDefault(); + event.stopPropagation(); + } + return false; + }); + }); +}; + +export default SubMenu; diff --git a/src/utils/merge.js b/src/utils/merge.js new file mode 100644 index 0000000..4ad7f91 --- /dev/null +++ b/src/utils/merge.js @@ -0,0 +1,15 @@ +export default function(target) { + for (let i = 1, j = arguments.length; i < j; i++) { + let source = arguments[i] || {}; + for (let prop in source) { + if (source.hasOwnProperty(prop)) { + let value = source[prop]; + if (value !== undefined) { + target[prop] = value; + } + } + } + } + + return target; +}; diff --git a/src/utils/popper.js b/src/utils/popper.js new file mode 100644 index 0000000..cb3b6d9 --- /dev/null +++ b/src/utils/popper.js @@ -0,0 +1,1276 @@ +/** + * @fileOverview Kickass library to create and place poppers near their reference elements. + * @version {{version}} + * @license + * Copyright (c) 2016 Federico Zivolo and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// +// Cross module loader +// Supported: Node, AMD, Browser globals +// +;(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory); + } else if (typeof module === 'object' && module.exports) { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.Popper = factory(); + } +}(this, function () { + + 'use strict'; + + var root = window; + + // default options + var DEFAULTS = { + // placement of the popper + placement: 'bottom', + + gpuAcceleration: true, + + // shift popper from its origin by the given amount of pixels (can be negative) + offset: 0, + + // the element which will act as boundary of the popper + boundariesElement: 'viewport', + + // amount of pixel used to define a minimum distance between the boundaries and the popper + boundariesPadding: 5, + + // popper will try to prevent overflow following this order, + // by default, then, it could overflow on the left and on top of the boundariesElement + preventOverflowOrder: ['left', 'right', 'top', 'bottom'], + + // the behavior used by flip to change the placement of the popper + flipBehavior: 'flip', + + arrowElement: '[x-arrow]', + + arrowOffset: 0, + + // list of functions used to modify the offsets before they are applied to the popper + modifiers: [ 'shift', 'offset', 'preventOverflow', 'keepTogether', 'arrow', 'flip', 'applyStyle'], + + modifiersIgnored: [], + + forceAbsolute: false + }; + + /** + * Create a new Popper.js instance + * @constructor Popper + * @param {HTMLElement} reference - The reference element used to position the popper + * @param {HTMLElement|Object} popper + * The HTML element used as popper, or a configuration used to generate the popper. + * @param {String} [popper.tagName='div'] The tag name of the generated popper. + * @param {Array} [popper.classNames=['popper']] Array of classes to apply to the generated popper. + * @param {Array} [popper.attributes] Array of attributes to apply, specify `attr:value` to assign a value to it. + * @param {HTMLElement|String} [popper.parent=window.document.body] The parent element, given as HTMLElement or as query string. + * @param {String} [popper.content=''] The content of the popper, it can be text, html, or node; if it is not text, set `contentType` to `html` or `node`. + * @param {String} [popper.contentType='text'] If `html`, the `content` will be parsed as HTML. If `node`, it will be appended as-is. + * @param {String} [popper.arrowTagName='div'] Same as `popper.tagName` but for the arrow element. + * @param {Array} [popper.arrowClassNames='popper__arrow'] Same as `popper.classNames` but for the arrow element. + * @param {String} [popper.arrowAttributes=['x-arrow']] Same as `popper.attributes` but for the arrow element. + * @param {Object} options + * @param {String} [options.placement=bottom] + * Placement of the popper accepted values: `top(-start, -end), right(-start, -end), bottom(-start, -right), + * left(-start, -end)` + * + * @param {HTMLElement|String} [options.arrowElement='[x-arrow]'] + * The DOM Node used as arrow for the popper, or a CSS selector used to get the DOM node. It must be child of + * its parent Popper. Popper.js will apply to the given element the style required to align the arrow with its + * reference element. + * By default, it will look for a child node of the popper with the `x-arrow` attribute. + * + * @param {Boolean} [options.gpuAcceleration=true] + * When this property is set to true, the popper position will be applied using CSS3 translate3d, allowing the + * browser to use the GPU to accelerate the rendering. + * If set to false, the popper will be placed using `top` and `left` properties, not using the GPU. + * + * @param {Number} [options.offset=0] + * Amount of pixels the popper will be shifted (can be negative). + * + * @param {String|Element} [options.boundariesElement='viewport'] + * The element which will define the boundaries of the popper position, the popper will never be placed outside + * of the defined boundaries (except if `keepTogether` is enabled) + * + * @param {Number} [options.boundariesPadding=5] + * Additional padding for the boundaries + * + * @param {Array} [options.preventOverflowOrder=['left', 'right', 'top', 'bottom']] + * Order used when Popper.js tries to avoid overflows from the boundaries, they will be checked in order, + * this means that the last ones will never overflow + * + * @param {String|Array} [options.flipBehavior='flip'] + * The behavior used by the `flip` modifier to change the placement of the popper when the latter is trying to + * overlap its reference element. Defining `flip` as value, the placement will be flipped on + * its axis (`right - left`, `top - bottom`). + * You can even pass an array of placements (eg: `['right', 'left', 'top']` ) to manually specify + * how alter the placement when a flip is needed. (eg. in the above example, it would first flip from right to left, + * then, if even in its new placement, the popper is overlapping its reference element, it will be moved to top) + * + * @param {Array} [options.modifiers=[ 'shift', 'offset', 'preventOverflow', 'keepTogether', 'arrow', 'flip', 'applyStyle']] + * List of functions used to modify the data before they are applied to the popper, add your custom functions + * to this array to edit the offsets and placement. + * The function should reflect the @params and @returns of preventOverflow + * + * @param {Array} [options.modifiersIgnored=[]] + * Put here any built-in modifier name you want to exclude from the modifiers list + * The function should reflect the @params and @returns of preventOverflow + * + * @param {Boolean} [options.removeOnDestroy=false] + * Set to true if you want to automatically remove the popper when you call the `destroy` method. + */ + function Popper(reference, popper, options) { + this._reference = reference.jquery ? reference[0] : reference; + this.state = {}; + + // if the popper variable is a configuration object, parse it to generate an HTMLElement + // generate a default popper if is not defined + var isNotDefined = typeof popper === 'undefined' || popper === null; + var isConfig = popper && Object.prototype.toString.call(popper) === '[object Object]'; + if (isNotDefined || isConfig) { + this._popper = this.parse(isConfig ? popper : {}); + } + // otherwise, use the given HTMLElement as popper + else { + this._popper = popper.jquery ? popper[0] : popper; + } + + // with {} we create a new object with the options inside it + this._options = Object.assign({}, DEFAULTS, options); + + // refactoring modifiers' list + this._options.modifiers = this._options.modifiers.map(function(modifier){ + // remove ignored modifiers + if (this._options.modifiersIgnored.indexOf(modifier) !== -1) return; + + // set the x-placement attribute before everything else because it could be used to add margins to the popper + // margins needs to be calculated to get the correct popper offsets + if (modifier === 'applyStyle') { + this._popper.setAttribute('x-placement', this._options.placement); + } + + // return predefined modifier identified by string or keep the custom one + return this.modifiers[modifier] || modifier; + }.bind(this)); + + // make sure to apply the popper position before any computation + this.state.position = this._getPosition(this._popper, this._reference); + setStyle(this._popper, { position: this.state.position, top: 0 }); + + // fire the first update to position the popper in the right place + this.update(); + + // setup event listeners, they will take care of update the position in specific situations + this._setupEventListeners(); + return this; + } + + + // + // Methods + // + /** + * Destroy the popper + * @method + * @memberof Popper + */ + Popper.prototype.destroy = function() { + this._popper.removeAttribute('x-placement'); + this._popper.style.left = ''; + this._popper.style.position = ''; + this._popper.style.top = ''; + this._popper.style[getSupportedPropertyName('transform')] = ''; + this._removeEventListeners(); + + // remove the popper if user explicity asked for the deletion on destroy + if (this._options.removeOnDestroy) { + this._popper.remove(); + } + return this; + }; + + /** + * Updates the position of the popper, computing the new offsets and applying the new style + * @method + * @memberof Popper + */ + Popper.prototype.update = function() { + var data = { instance: this, styles: {} }; + + // store placement inside the data object, modifiers will be able to edit `placement` if needed + // and refer to _originalPlacement to know the original value + data.placement = this._options.placement; + data._originalPlacement = this._options.placement; + + // compute the popper and reference offsets and put them inside data.offsets + data.offsets = this._getOffsets(this._popper, this._reference, data.placement); + + // get boundaries + data.boundaries = this._getBoundaries(data, this._options.boundariesPadding, this._options.boundariesElement); + + data = this.runModifiers(data, this._options.modifiers); + + if (typeof this.state.updateCallback === 'function') { + this.state.updateCallback(data); + } + }; + + /** + * If a function is passed, it will be executed after the initialization of popper with as first argument the Popper instance. + * @method + * @memberof Popper + * @param {Function} callback + */ + Popper.prototype.onCreate = function(callback) { + // the createCallbacks return as first argument the popper instance + callback(this); + return this; + }; + + /** + * If a function is passed, it will be executed after each update of popper with as first argument the set of coordinates and informations + * used to style popper and its arrow. + * NOTE: it doesn't get fired on the first call of the `Popper.update()` method inside the `Popper` constructor! + * @method + * @memberof Popper + * @param {Function} callback + */ + Popper.prototype.onUpdate = function(callback) { + this.state.updateCallback = callback; + return this; + }; + + /** + * Helper used to generate poppers from a configuration file + * @method + * @memberof Popper + * @param config {Object} configuration + * @returns {HTMLElement} popper + */ + Popper.prototype.parse = function(config) { + var defaultConfig = { + tagName: 'div', + classNames: [ 'popper' ], + attributes: [], + parent: root.document.body, + content: '', + contentType: 'text', + arrowTagName: 'div', + arrowClassNames: [ 'popper__arrow' ], + arrowAttributes: [ 'x-arrow'] + }; + config = Object.assign({}, defaultConfig, config); + + var d = root.document; + + var popper = d.createElement(config.tagName); + addClassNames(popper, config.classNames); + addAttributes(popper, config.attributes); + if (config.contentType === 'node') { + popper.appendChild(config.content.jquery ? config.content[0] : config.content); + }else if (config.contentType === 'html') { + popper.innerHTML = config.content; + } else { + popper.textContent = config.content; + } + + if (config.arrowTagName) { + var arrow = d.createElement(config.arrowTagName); + addClassNames(arrow, config.arrowClassNames); + addAttributes(arrow, config.arrowAttributes); + popper.appendChild(arrow); + } + + var parent = config.parent.jquery ? config.parent[0] : config.parent; + + // if the given parent is a string, use it to match an element + // if more than one element is matched, the first one will be used as parent + // if no elements are matched, the script will throw an error + if (typeof parent === 'string') { + parent = d.querySelectorAll(config.parent); + if (parent.length > 1) { + console.warn('WARNING: the given `parent` query(' + config.parent + ') matched more than one element, the first one will be used'); + } + if (parent.length === 0) { + throw 'ERROR: the given `parent` doesn\'t exists!'; + } + parent = parent[0]; + } + // if the given parent is a DOM nodes list or an array of nodes with more than one element, + // the first one will be used as parent + if (parent.length > 1 && parent instanceof Element === false) { + console.warn('WARNING: you have passed as parent a list of elements, the first one will be used'); + parent = parent[0]; + } + + // append the generated popper to its parent + parent.appendChild(popper); + + return popper; + + /** + * Adds class names to the given element + * @function + * @ignore + * @param {HTMLElement} target + * @param {Array} classes + */ + function addClassNames(element, classNames) { + classNames.forEach(function(className) { + element.classList.add(className); + }); + } + + /** + * Adds attributes to the given element + * @function + * @ignore + * @param {HTMLElement} target + * @param {Array} attributes + * @example + * addAttributes(element, [ 'data-info:foobar' ]); + */ + function addAttributes(element, attributes) { + attributes.forEach(function(attribute) { + element.setAttribute(attribute.split(':')[0], attribute.split(':')[1] || ''); + }); + } + + }; + + /** + * Helper used to get the position which will be applied to the popper + * @method + * @memberof Popper + * @param config {HTMLElement} popper element + * @param reference {HTMLElement} reference element + * @returns {String} position + */ + Popper.prototype._getPosition = function(popper, reference) { + var container = getOffsetParent(reference); + + if (this._options.forceAbsolute) { + return 'absolute'; + } + + // Decide if the popper will be fixed + // If the reference element is inside a fixed context, the popper will be fixed as well to allow them to scroll together + var isParentFixed = isFixed(reference, container); + return isParentFixed ? 'fixed' : 'absolute'; + }; + + /** + * Get offsets to the popper + * @method + * @memberof Popper + * @access private + * @param {Element} popper - the popper element + * @param {Element} reference - the reference element (the popper will be relative to this) + * @returns {Object} An object containing the offsets which will be applied to the popper + */ + Popper.prototype._getOffsets = function(popper, reference, placement) { + placement = placement.split('-')[0]; + var popperOffsets = {}; + + popperOffsets.position = this.state.position; + var isParentFixed = popperOffsets.position === 'fixed'; + + // + // Get reference element position + // + var referenceOffsets = getOffsetRectRelativeToCustomParent(reference, getOffsetParent(popper), isParentFixed); + + // + // Get popper sizes + // + var popperRect = getOuterSizes(popper); + + // + // Compute offsets of popper + // + + // depending by the popper placement we have to compute its offsets slightly differently + if (['right', 'left'].indexOf(placement) !== -1) { + popperOffsets.top = referenceOffsets.top + referenceOffsets.height / 2 - popperRect.height / 2; + if (placement === 'left') { + popperOffsets.left = referenceOffsets.left - popperRect.width; + } else { + popperOffsets.left = referenceOffsets.right; + } + } else { + popperOffsets.left = referenceOffsets.left + referenceOffsets.width / 2 - popperRect.width / 2; + if (placement === 'top') { + popperOffsets.top = referenceOffsets.top - popperRect.height; + } else { + popperOffsets.top = referenceOffsets.bottom; + } + } + + // Add width and height to our offsets object + popperOffsets.width = popperRect.width; + popperOffsets.height = popperRect.height; + + return { + popper: popperOffsets, + reference: referenceOffsets + }; + }; + + + /** + * Setup needed event listeners used to update the popper position + * @method + * @memberof Popper + * @access private + */ + Popper.prototype._setupEventListeners = function() { + // NOTE: 1 DOM access here + this.state.updateBound = this.update.bind(this); + root.addEventListener('resize', this.state.updateBound); + // if the boundariesElement is window we don't need to listen for the scroll event + if (this._options.boundariesElement !== 'window') { + var target = getScrollParent(this._reference); + // here it could be both `body` or `documentElement` thanks to Firefox, we then check both + if (target === root.document.body || target === root.document.documentElement) { + target = root; + } + target.addEventListener('scroll', this.state.updateBound); + this.state.scrollTarget = target; + } + }; + + /** + * Remove event listeners used to update the popper position + * @method + * @memberof Popper + * @access private + */ + Popper.prototype._removeEventListeners = function() { + // NOTE: 1 DOM access here + root.removeEventListener('resize', this.state.updateBound); + if (this._options.boundariesElement !== 'window' && this.state.scrollTarget) { + this.state.scrollTarget.removeEventListener('scroll', this.state.updateBound); + this.state.scrollTarget = null; + } + this.state.updateBound = null; + }; + + /** + * Computed the boundaries limits and return them + * @method + * @memberof Popper + * @access private + * @param {Object} data - Object containing the property "offsets" generated by `_getOffsets` + * @param {Number} padding - Boundaries padding + * @param {Element} boundariesElement - Element used to define the boundaries + * @returns {Object} Coordinates of the boundaries + */ + Popper.prototype._getBoundaries = function(data, padding, boundariesElement) { + // NOTE: 1 DOM access here + var boundaries = {}; + var width, height; + if (boundariesElement === 'window') { + var body = root.document.body, + html = root.document.documentElement; + + height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); + width = Math.max( body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth ); + + boundaries = { + top: 0, + right: width, + bottom: height, + left: 0 + }; + } else if (boundariesElement === 'viewport') { + var offsetParent = getOffsetParent(this._popper); + var scrollParent = getScrollParent(this._popper); + var offsetParentRect = getOffsetRect(offsetParent); + + // Thanks the fucking native API, `document.body.scrollTop` & `document.documentElement.scrollTop` + var getScrollTopValue = function (element) { + return element == document.body ? Math.max(document.documentElement.scrollTop, document.body.scrollTop) : element.scrollTop; + } + var getScrollLeftValue = function (element) { + return element == document.body ? Math.max(document.documentElement.scrollLeft, document.body.scrollLeft) : element.scrollLeft; + } + + // if the popper is fixed we don't have to substract scrolling from the boundaries + var scrollTop = data.offsets.popper.position === 'fixed' ? 0 : getScrollTopValue(scrollParent); + var scrollLeft = data.offsets.popper.position === 'fixed' ? 0 : getScrollLeftValue(scrollParent); + + boundaries = { + top: 0 - (offsetParentRect.top - scrollTop), + right: root.document.documentElement.clientWidth - (offsetParentRect.left - scrollLeft), + bottom: root.document.documentElement.clientHeight - (offsetParentRect.top - scrollTop), + left: 0 - (offsetParentRect.left - scrollLeft) + }; + } else { + if (getOffsetParent(this._popper) === boundariesElement) { + boundaries = { + top: 0, + left: 0, + right: boundariesElement.clientWidth, + bottom: boundariesElement.clientHeight + }; + } else { + boundaries = getOffsetRect(boundariesElement); + } + } + boundaries.left += padding; + boundaries.right -= padding; + boundaries.top = boundaries.top + padding; + boundaries.bottom = boundaries.bottom - padding; + return boundaries; + }; + + + /** + * Loop trough the list of modifiers and run them in order, each of them will then edit the data object + * @method + * @memberof Popper + * @access public + * @param {Object} data + * @param {Array} modifiers + * @param {Function} ends + */ + Popper.prototype.runModifiers = function(data, modifiers, ends) { + var modifiersToRun = modifiers.slice(); + if (ends !== undefined) { + modifiersToRun = this._options.modifiers.slice(0, getArrayKeyIndex(this._options.modifiers, ends)); + } + + modifiersToRun.forEach(function(modifier) { + if (isFunction(modifier)) { + data = modifier.call(this, data); + } + }.bind(this)); + + return data; + }; + + /** + * Helper used to know if the given modifier depends from another one. + * @method + * @memberof Popper + * @param {String} requesting - name of requesting modifier + * @param {String} requested - name of requested modifier + * @returns {Boolean} + */ + Popper.prototype.isModifierRequired = function(requesting, requested) { + var index = getArrayKeyIndex(this._options.modifiers, requesting); + return !!this._options.modifiers.slice(0, index).filter(function(modifier) { + return modifier === requested; + }).length; + }; + + // + // Modifiers + // + + /** + * Modifiers list + * @namespace Popper.modifiers + * @memberof Popper + * @type {Object} + */ + Popper.prototype.modifiers = {}; + + /** + * Apply the computed styles to the popper element + * @method + * @memberof Popper.modifiers + * @argument {Object} data - The data object generated by `update` method + * @returns {Object} The same data object + */ + Popper.prototype.modifiers.applyStyle = function(data) { + // apply the final offsets to the popper + // NOTE: 1 DOM access here + var styles = { + position: data.offsets.popper.position + }; + + // round top and left to avoid blurry text + var left = Math.round(data.offsets.popper.left); + var top = Math.round(data.offsets.popper.top); + + // if gpuAcceleration is set to true and transform is supported, we use `translate3d` to apply the position to the popper + // we automatically use the supported prefixed version if needed + var prefixedProperty; + if (this._options.gpuAcceleration && (prefixedProperty = getSupportedPropertyName('transform'))) { + styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; + styles.top = 0; + styles.left = 0; + } + // othwerise, we use the standard `left` and `top` properties + else { + styles.left =left; + styles.top = top; + } + + // any property present in `data.styles` will be applied to the popper, + // in this way we can make the 3rd party modifiers add custom styles to it + // Be aware, modifiers could override the properties defined in the previous + // lines of this modifier! + Object.assign(styles, data.styles); + + setStyle(this._popper, styles); + + // set an attribute which will be useful to style the tooltip (use it to properly position its arrow) + // NOTE: 1 DOM access here + this._popper.setAttribute('x-placement', data.placement); + + // if the arrow modifier is required and the arrow style has been computed, apply the arrow style + if (this.isModifierRequired(this.modifiers.applyStyle, this.modifiers.arrow) && data.offsets.arrow) { + setStyle(data.arrowElement, data.offsets.arrow); + } + + return data; + }; + + /** + * Modifier used to shift the popper on the start or end of its reference element side + * @method + * @memberof Popper.modifiers + * @argument {Object} data - The data object generated by `update` method + * @returns {Object} The data object, properly modified + */ + Popper.prototype.modifiers.shift = function(data) { + var placement = data.placement; + var basePlacement = placement.split('-')[0]; + var shiftVariation = placement.split('-')[1]; + + // if shift shiftVariation is specified, run the modifier + if (shiftVariation) { + var reference = data.offsets.reference; + var popper = getPopperClientRect(data.offsets.popper); + + var shiftOffsets = { + y: { + start: { top: reference.top }, + end: { top: reference.top + reference.height - popper.height } + }, + x: { + start: { left: reference.left }, + end: { left: reference.left + reference.width - popper.width } + } + }; + + var axis = ['bottom', 'top'].indexOf(basePlacement) !== -1 ? 'x' : 'y'; + + data.offsets.popper = Object.assign(popper, shiftOffsets[axis][shiftVariation]); + } + + return data; + }; + + + /** + * Modifier used to make sure the popper does not overflows from it's boundaries + * @method + * @memberof Popper.modifiers + * @argument {Object} data - The data object generated by `update` method + * @returns {Object} The data object, properly modified + */ + Popper.prototype.modifiers.preventOverflow = function(data) { + var order = this._options.preventOverflowOrder; + var popper = getPopperClientRect(data.offsets.popper); + + var check = { + left: function() { + var left = popper.left; + if (popper.left < data.boundaries.left) { + left = Math.max(popper.left, data.boundaries.left); + } + return { left: left }; + }, + right: function() { + var left = popper.left; + if (popper.right > data.boundaries.right) { + left = Math.min(popper.left, data.boundaries.right - popper.width); + } + return { left: left }; + }, + top: function() { + var top = popper.top; + if (popper.top < data.boundaries.top) { + top = Math.max(popper.top, data.boundaries.top); + } + return { top: top }; + }, + bottom: function() { + var top = popper.top; + if (popper.bottom > data.boundaries.bottom) { + top = Math.min(popper.top, data.boundaries.bottom - popper.height); + } + return { top: top }; + } + }; + + order.forEach(function(direction) { + data.offsets.popper = Object.assign(popper, check[direction]()); + }); + + return data; + }; + + /** + * Modifier used to make sure the popper is always near its reference + * @method + * @memberof Popper.modifiers + * @argument {Object} data - The data object generated by _update method + * @returns {Object} The data object, properly modified + */ + Popper.prototype.modifiers.keepTogether = function(data) { + var popper = getPopperClientRect(data.offsets.popper); + var reference = data.offsets.reference; + var f = Math.floor; + + if (popper.right < f(reference.left)) { + data.offsets.popper.left = f(reference.left) - popper.width; + } + if (popper.left > f(reference.right)) { + data.offsets.popper.left = f(reference.right); + } + if (popper.bottom < f(reference.top)) { + data.offsets.popper.top = f(reference.top) - popper.height; + } + if (popper.top > f(reference.bottom)) { + data.offsets.popper.top = f(reference.bottom); + } + + return data; + }; + + /** + * Modifier used to flip the placement of the popper when the latter is starting overlapping its reference element. + * Requires the `preventOverflow` modifier before it in order to work. + * **NOTE:** This modifier will run all its previous modifiers everytime it tries to flip the popper! + * @method + * @memberof Popper.modifiers + * @argument {Object} data - The data object generated by _update method + * @returns {Object} The data object, properly modified + */ + Popper.prototype.modifiers.flip = function(data) { + // check if preventOverflow is in the list of modifiers before the flip modifier. + // otherwise flip would not work as expected. + if (!this.isModifierRequired(this.modifiers.flip, this.modifiers.preventOverflow)) { + console.warn('WARNING: preventOverflow modifier is required by flip modifier in order to work, be sure to include it before flip!'); + return data; + } + + if (data.flipped && data.placement === data._originalPlacement) { + // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides + return data; + } + + var placement = data.placement.split('-')[0]; + var placementOpposite = getOppositePlacement(placement); + var variation = data.placement.split('-')[1] || ''; + + var flipOrder = []; + if(this._options.flipBehavior === 'flip') { + flipOrder = [ + placement, + placementOpposite + ]; + } else { + flipOrder = this._options.flipBehavior; + } + + flipOrder.forEach(function(step, index) { + if (placement !== step || flipOrder.length === index + 1) { + return; + } + + placement = data.placement.split('-')[0]; + placementOpposite = getOppositePlacement(placement); + + var popperOffsets = getPopperClientRect(data.offsets.popper); + + // this boolean is used to distinguish right and bottom from top and left + // they need different computations to get flipped + var a = ['right', 'bottom'].indexOf(placement) !== -1; + + // using Math.floor because the reference offsets may contain decimals we are not going to consider here + if ( + a && Math.floor(data.offsets.reference[placement]) > Math.floor(popperOffsets[placementOpposite]) || + !a && Math.floor(data.offsets.reference[placement]) < Math.floor(popperOffsets[placementOpposite]) + ) { + // we'll use this boolean to detect any flip loop + data.flipped = true; + data.placement = flipOrder[index + 1]; + if (variation) { + data.placement += '-' + variation; + } + data.offsets.popper = this._getOffsets(this._popper, this._reference, data.placement).popper; + + data = this.runModifiers(data, this._options.modifiers, this._flip); + } + }.bind(this)); + return data; + }; + + /** + * Modifier used to add an offset to the popper, useful if you more granularity positioning your popper. + * The offsets will shift the popper on the side of its reference element. + * @method + * @memberof Popper.modifiers + * @argument {Object} data - The data object generated by _update method + * @returns {Object} The data object, properly modified + */ + Popper.prototype.modifiers.offset = function(data) { + var offset = this._options.offset; + var popper = data.offsets.popper; + + if (data.placement.indexOf('left') !== -1) { + popper.top -= offset; + } + else if (data.placement.indexOf('right') !== -1) { + popper.top += offset; + } + else if (data.placement.indexOf('top') !== -1) { + popper.left -= offset; + } + else if (data.placement.indexOf('bottom') !== -1) { + popper.left += offset; + } + return data; + }; + + /** + * Modifier used to move the arrows on the edge of the popper to make sure them are always between the popper and the reference element + * It will use the CSS outer size of the arrow element to know how many pixels of conjuction are needed + * @method + * @memberof Popper.modifiers + * @argument {Object} data - The data object generated by _update method + * @returns {Object} The data object, properly modified + */ + Popper.prototype.modifiers.arrow = function(data) { + var arrow = this._options.arrowElement; + var arrowOffset = this._options.arrowOffset; + + // if the arrowElement is a string, suppose it's a CSS selector + if (typeof arrow === 'string') { + arrow = this._popper.querySelector(arrow); + } + + // if arrow element is not found, don't run the modifier + if (!arrow) { + return data; + } + + // the arrow element must be child of its popper + if (!this._popper.contains(arrow)) { + console.warn('WARNING: `arrowElement` must be child of its popper element!'); + return data; + } + + // arrow depends on keepTogether in order to work + if (!this.isModifierRequired(this.modifiers.arrow, this.modifiers.keepTogether)) { + console.warn('WARNING: keepTogether modifier is required by arrow modifier in order to work, be sure to include it before arrow!'); + return data; + } + + var arrowStyle = {}; + var placement = data.placement.split('-')[0]; + var popper = getPopperClientRect(data.offsets.popper); + var reference = data.offsets.reference; + var isVertical = ['left', 'right'].indexOf(placement) !== -1; + + 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]; + + // + // extends keepTogether behavior making sure the popper and its reference have enough pixels in conjuction + // + + // top/left side + if (reference[opSide] - arrowSize < popper[side]) { + data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowSize); + } + // bottom/right side + if (reference[side] + arrowSize > popper[opSide]) { + data.offsets.popper[side] += (reference[side] + arrowSize) - popper[opSide]; + } + + // compute center of the popper + var center = reference[side] + (arrowOffset || (reference[len] / 2) - (arrowSize / 2)); + + var sideValue = center - popper[side]; + + // prevent arrow from being placed not contiguously to its popper + 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 + + data.offsets.arrow = arrowStyle; + data.arrowElement = arrow; + + return data; + }; + + + // + // Helpers + // + + /** + * Get the outer sizes of the given element (offset size + margins) + * @function + * @ignore + * @argument {Element} element + * @returns {Object} object containing width and height properties + */ + function getOuterSizes(element) { + // NOTE: 1 DOM access here + var _display = element.style.display, _visibility = element.style.visibility; + element.style.display = 'block'; element.style.visibility = 'hidden'; + var calcWidthToForceRepaint = element.offsetWidth; + + // original method + var styles = root.getComputedStyle(element); + var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom); + var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight); + var result = { width: element.offsetWidth + y, height: element.offsetHeight + x }; + + // reset element styles + element.style.display = _display; element.style.visibility = _visibility; + return result; + } + + /** + * Get the opposite placement of the given one/ + * @function + * @ignore + * @argument {String} placement + * @returns {String} flipped placement + */ + function getOppositePlacement(placement) { + var hash = {left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; + return placement.replace(/left|right|bottom|top/g, function(matched){ + return hash[matched]; + }); + } + + /** + * Given the popper offsets, generate an output similar to getBoundingClientRect + * @function + * @ignore + * @argument {Object} popperOffsets + * @returns {Object} ClientRect like output + */ + function getPopperClientRect(popperOffsets) { + var offsets = Object.assign({}, popperOffsets); + offsets.right = offsets.left + offsets.width; + offsets.bottom = offsets.top + offsets.height; + return offsets; + } + + /** + * Given an array and the key to find, returns its index + * @function + * @ignore + * @argument {Array} arr + * @argument keyToFind + * @returns index or null + */ + function getArrayKeyIndex(arr, keyToFind) { + var i = 0, key; + for (key in arr) { + if (arr[key] === keyToFind) { + return i; + } + i++; + } + return null; + } + + /** + * Get CSS computed property of the given element + * @function + * @ignore + * @argument {Eement} element + * @argument {String} property + */ + function getStyleComputedProperty(element, property) { + // NOTE: 1 DOM access here + var css = root.getComputedStyle(element, null); + return css[property]; + } + + /** + * Returns the offset parent of the given element + * @function + * @ignore + * @argument {Element} element + * @returns {Element} offset parent + */ + function getOffsetParent(element) { + // NOTE: 1 DOM access here + var offsetParent = element.offsetParent; + return offsetParent === root.document.body || !offsetParent ? root.document.documentElement : offsetParent; + } + + /** + * Returns the scrolling parent of the given element + * @function + * @ignore + * @argument {Element} element + * @returns {Element} offset parent + */ + function getScrollParent(element) { + var parent = element.parentNode; + + if (!parent) { + return element; + } + + if (parent === root.document) { + // Firefox puts the scrollTOp value on `documentElement` instead of `body`, we then check which of them is + // greater than 0 and return the proper element + if (root.document.body.scrollTop || root.document.body.scrollLeft) { + return root.document.body; + } else { + return root.document.documentElement; + } + } + + // Firefox want us to check `-x` and `-y` variations as well + if ( + ['scroll', 'auto'].indexOf(getStyleComputedProperty(parent, 'overflow')) !== -1 || + ['scroll', 'auto'].indexOf(getStyleComputedProperty(parent, 'overflow-x')) !== -1 || + ['scroll', 'auto'].indexOf(getStyleComputedProperty(parent, 'overflow-y')) !== -1 + ) { + // If the detected scrollParent is body, we perform an additional check on its parentNode + // in this way we'll get body if the browser is Chrome-ish, or documentElement otherwise + // fixes issue #65 + return parent; + } + return getScrollParent(element.parentNode); + } + + /** + * Check if the given element is fixed or is inside a fixed parent + * @function + * @ignore + * @argument {Element} element + * @argument {Element} customContainer + * @returns {Boolean} answer to "isFixed?" + */ + function isFixed(element) { + if (element === root.document.body) { + return false; + } + if (getStyleComputedProperty(element, 'position') === 'fixed') { + return true; + } + return element.parentNode ? isFixed(element.parentNode) : element; + } + + /** + * Set the style to the given popper + * @function + * @ignore + * @argument {Element} element - Element to apply the style to + * @argument {Object} styles - Object with a list of properties and values which will be applied to the element + */ + function setStyle(element, styles) { + function is_numeric(n) { + return (n !== '' && !isNaN(parseFloat(n)) && isFinite(n)); + } + Object.keys(styles).forEach(function(prop) { + var unit = ''; + // add unit if the value is numeric and is one of the following + if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && is_numeric(styles[prop])) { + unit = 'px'; + } + element.style[prop] = styles[prop] + unit; + }); + } + + /** + * Check if the given variable is a function + * @function + * @ignore + * @argument {*} functionToCheck - variable to check + * @returns {Boolean} answer to: is a function? + */ + function isFunction(functionToCheck) { + var getType = {}; + return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; + } + + /** + * Get the position of the given element, relative to its offset parent + * @function + * @ignore + * @param {Element} element + * @return {Object} position - Coordinates of the element and its `scrollTop` + */ + function getOffsetRect(element) { + var elementRect = { + width: element.offsetWidth, + height: element.offsetHeight, + left: element.offsetLeft, + top: element.offsetTop + }; + + elementRect.right = elementRect.left + elementRect.width; + elementRect.bottom = elementRect.top + elementRect.height; + + // position + return elementRect; + } + + /** + * Get bounding client rect of given element + * @function + * @ignore + * @param {HTMLElement} element + * @return {Object} client rect + */ + function getBoundingClientRect(element) { + var rect = element.getBoundingClientRect(); + + // whether the IE version is lower than 11 + var isIE = navigator.userAgent.indexOf("MSIE") != -1; + + // fix ie document bounding top always 0 bug + var rectTop = isIE && element.tagName === 'HTML' + ? -element.scrollTop + : rect.top; + + return { + left: rect.left, + top: rectTop, + right: rect.right, + bottom: rect.bottom, + width: rect.right - rect.left, + height: rect.bottom - rectTop + }; + } + + /** + * Given an element and one of its parents, return the offset + * @function + * @ignore + * @param {HTMLElement} element + * @param {HTMLElement} parent + * @return {Object} rect + */ + function getOffsetRectRelativeToCustomParent(element, parent, fixed) { + var elementRect = getBoundingClientRect(element); + var parentRect = getBoundingClientRect(parent); + + if (fixed) { + var scrollParent = getScrollParent(parent); + parentRect.top += scrollParent.scrollTop; + parentRect.bottom += scrollParent.scrollTop; + parentRect.left += scrollParent.scrollLeft; + parentRect.right += scrollParent.scrollLeft; + } + + var rect = { + top: elementRect.top - parentRect.top , + left: elementRect.left - parentRect.left , + bottom: (elementRect.top - parentRect.top) + elementRect.height, + right: (elementRect.left - parentRect.left) + elementRect.width, + width: elementRect.width, + height: elementRect.height + }; + return rect; + } + + /** + * Get the prefixed supported property name + * @function + * @ignore + * @argument {String} property (camelCase) + * @returns {String} prefixed property (camelCase) + */ + function getSupportedPropertyName(property) { + var prefixes = ['', 'ms', 'webkit', 'moz', 'o']; + + for (var i = 0; i < prefixes.length; i++) { + var toCheck = prefixes[i] ? prefixes[i] + property.charAt(0).toUpperCase() + property.slice(1) : property; + if (typeof root.document.body.style[toCheck] !== 'undefined') { + return toCheck; + } + } + return null; + } + + /** + * The Object.assign() method is used to copy the values of all enumerable own properties from one or more source + * objects to a target object. It will return the target object. + * This polyfill doesn't support symbol properties, since ES5 doesn't have symbols anyway + * Source: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + * @function + * @ignore + */ + if (!Object.assign) { + Object.defineProperty(Object, 'assign', { + enumerable: false, + configurable: true, + writable: true, + value: function(target) { + if (target === undefined || target === null) { + throw new TypeError('Cannot convert first argument to object'); + } + + var to = Object(target); + for (var i = 1; i < arguments.length; i++) { + var nextSource = arguments[i]; + if (nextSource === undefined || nextSource === null) { + continue; + } + nextSource = Object(nextSource); + + var keysArray = Object.keys(nextSource); + for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) { + var nextKey = keysArray[nextIndex]; + var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); + if (desc !== undefined && desc.enumerable) { + to[nextKey] = nextSource[nextKey]; + } + } + } + return to; + } + }); + } + + return Popper; +})); diff --git a/src/utils/popup/index.js b/src/utils/popup/index.js new file mode 100644 index 0000000..0fc1bbd --- /dev/null +++ b/src/utils/popup/index.js @@ -0,0 +1,218 @@ +import Vue from 'vue'; +import merge from 'element-ui/src/utils/merge'; +import PopupManager from 'element-ui/src/utils/popup/popup-manager'; +import getScrollBarWidth from '../scrollbar-width'; +import { getStyle, addClass, removeClass, hasClass } from '../dom'; + +let idSeed = 1; + +let scrollBarWidth; + +export default { + props: { + visible: { + type: Boolean, + default: false + }, + openDelay: {}, + closeDelay: {}, + zIndex: {}, + modal: { + type: Boolean, + default: false + }, + modalFade: { + type: Boolean, + default: true + }, + modalClass: {}, + modalAppendToBody: { + type: Boolean, + default: false + }, + lockScroll: { + type: Boolean, + default: true + }, + closeOnPressEscape: { + type: Boolean, + default: false + }, + closeOnClickModal: { + type: Boolean, + default: false + } + }, + + beforeMount() { + this._popupId = 'popup-' + idSeed++; + PopupManager.register(this._popupId, this); + }, + + beforeDestroy() { + PopupManager.deregister(this._popupId); + PopupManager.closeModal(this._popupId); + + this.restoreBodyStyle(); + }, + + data() { + return { + opened: false, + bodyPaddingRight: null, + computedBodyPaddingRight: 0, + withoutHiddenClass: true, + rendered: false + }; + }, + + watch: { + visible(val) { + if (val) { + if (this._opening) return; + if (!this.rendered) { + this.rendered = true; + Vue.nextTick(() => { + this.open(); + }); + } else { + this.open(); + } + } else { + this.close(); + } + } + }, + + methods: { + open(options) { + if (!this.rendered) { + this.rendered = true; + } + + const props = merge({}, this.$props || this, options); + + if (this._closeTimer) { + clearTimeout(this._closeTimer); + this._closeTimer = null; + } + clearTimeout(this._openTimer); + + const openDelay = Number(props.openDelay); + if (openDelay > 0) { + this._openTimer = setTimeout(() => { + this._openTimer = null; + this.doOpen(props); + }, openDelay); + } else { + this.doOpen(props); + } + }, + + doOpen(props) { + if (this.$isServer) return; + if (this.willOpen && !this.willOpen()) return; + if (this.opened) return; + + this._opening = true; + + const dom = this.$el; + + const modal = props.modal; + + const zIndex = props.zIndex; + if (zIndex) { + PopupManager.zIndex = zIndex; + } + + if (modal) { + if (this._closing) { + PopupManager.closeModal(this._popupId); + this._closing = false; + } + PopupManager.openModal(this._popupId, PopupManager.nextZIndex(), this.modalAppendToBody ? undefined : dom, props.modalClass, props.modalFade); + if (props.lockScroll) { + this.withoutHiddenClass = !hasClass(document.body, 'el-popup-parent--hidden'); + if (this.withoutHiddenClass) { + this.bodyPaddingRight = document.body.style.paddingRight; + this.computedBodyPaddingRight = parseInt(getStyle(document.body, 'paddingRight'), 10); + } + scrollBarWidth = getScrollBarWidth(); + let bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight; + let bodyOverflowY = getStyle(document.body, 'overflowY'); + if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll') && this.withoutHiddenClass) { + document.body.style.paddingRight = this.computedBodyPaddingRight + scrollBarWidth + 'px'; + } + addClass(document.body, 'el-popup-parent--hidden'); + } + } + + if (getComputedStyle(dom).position === 'static') { + dom.style.position = 'absolute'; + } + + dom.style.zIndex = PopupManager.nextZIndex(); + this.opened = true; + + this.onOpen && this.onOpen(); + + this.doAfterOpen(); + }, + + doAfterOpen() { + this._opening = false; + }, + + close() { + if (this.willClose && !this.willClose()) return; + + if (this._openTimer !== null) { + clearTimeout(this._openTimer); + this._openTimer = null; + } + clearTimeout(this._closeTimer); + + const closeDelay = Number(this.closeDelay); + + if (closeDelay > 0) { + this._closeTimer = setTimeout(() => { + this._closeTimer = null; + this.doClose(); + }, closeDelay); + } else { + this.doClose(); + } + }, + + doClose() { + this._closing = true; + + this.onClose && this.onClose(); + + if (this.lockScroll) { + setTimeout(this.restoreBodyStyle, 200); + } + + this.opened = false; + + this.doAfterClose(); + }, + + doAfterClose() { + PopupManager.closeModal(this._popupId); + this._closing = false; + }, + + restoreBodyStyle() { + if (this.modal && this.withoutHiddenClass) { + document.body.style.paddingRight = this.bodyPaddingRight; + removeClass(document.body, 'el-popup-parent--hidden'); + } + this.withoutHiddenClass = true; + } + } +}; + +export { + PopupManager +}; diff --git a/src/utils/popup/popup-manager.js b/src/utils/popup/popup-manager.js new file mode 100644 index 0000000..598f8b8 --- /dev/null +++ b/src/utils/popup/popup-manager.js @@ -0,0 +1,194 @@ +import Vue from 'vue'; +import { addClass, removeClass } from 'element-ui/src/utils/dom'; + +let hasModal = false; +let hasInitZIndex = false; +let zIndex; + +const getModal = function() { + if (Vue.prototype.$isServer) return; + let modalDom = PopupManager.modalDom; + if (modalDom) { + hasModal = true; + } else { + hasModal = false; + modalDom = document.createElement('div'); + PopupManager.modalDom = modalDom; + + modalDom.addEventListener('touchmove', function(event) { + event.preventDefault(); + event.stopPropagation(); + }); + + modalDom.addEventListener('click', function() { + PopupManager.doOnModalClick && PopupManager.doOnModalClick(); + }); + } + + return modalDom; +}; + +const instances = {}; + +const PopupManager = { + modalFade: true, + + getInstance: function(id) { + return instances[id]; + }, + + register: function(id, instance) { + if (id && instance) { + instances[id] = instance; + } + }, + + deregister: function(id) { + if (id) { + instances[id] = null; + delete instances[id]; + } + }, + + nextZIndex: function() { + return PopupManager.zIndex++; + }, + + modalStack: [], + + doOnModalClick: function() { + const topItem = PopupManager.modalStack[PopupManager.modalStack.length - 1]; + if (!topItem) return; + + const instance = PopupManager.getInstance(topItem.id); + if (instance && instance.closeOnClickModal) { + instance.close(); + } + }, + + openModal: function(id, zIndex, dom, modalClass, modalFade) { + if (Vue.prototype.$isServer) return; + if (!id || zIndex === undefined) return; + this.modalFade = modalFade; + + const modalStack = this.modalStack; + + for (let i = 0, j = modalStack.length; i < j; i++) { + const item = modalStack[i]; + if (item.id === id) { + return; + } + } + + const modalDom = getModal(); + + addClass(modalDom, 'v-modal'); + if (this.modalFade && !hasModal) { + addClass(modalDom, 'v-modal-enter'); + } + if (modalClass) { + let classArr = modalClass.trim().split(/\s+/); + classArr.forEach(item => addClass(modalDom, item)); + } + setTimeout(() => { + removeClass(modalDom, 'v-modal-enter'); + }, 200); + + if (dom && dom.parentNode && dom.parentNode.nodeType !== 11) { + dom.parentNode.appendChild(modalDom); + } else { + document.body.appendChild(modalDom); + } + + if (zIndex) { + modalDom.style.zIndex = zIndex; + } + modalDom.tabIndex = 0; + modalDom.style.display = ''; + + this.modalStack.push({ id: id, zIndex: zIndex, modalClass: modalClass }); + }, + + closeModal: function(id) { + const modalStack = this.modalStack; + const modalDom = getModal(); + + if (modalStack.length > 0) { + const topItem = modalStack[modalStack.length - 1]; + if (topItem.id === id) { + if (topItem.modalClass) { + let classArr = topItem.modalClass.trim().split(/\s+/); + classArr.forEach(item => removeClass(modalDom, item)); + } + + modalStack.pop(); + if (modalStack.length > 0) { + modalDom.style.zIndex = modalStack[modalStack.length - 1].zIndex; + } + } else { + for (let i = modalStack.length - 1; i >= 0; i--) { + if (modalStack[i].id === id) { + modalStack.splice(i, 1); + break; + } + } + } + } + + if (modalStack.length === 0) { + if (this.modalFade) { + addClass(modalDom, 'v-modal-leave'); + } + setTimeout(() => { + if (modalStack.length === 0) { + if (modalDom.parentNode) modalDom.parentNode.removeChild(modalDom); + modalDom.style.display = 'none'; + PopupManager.modalDom = undefined; + } + removeClass(modalDom, 'v-modal-leave'); + }, 200); + } + } +}; + +Object.defineProperty(PopupManager, 'zIndex', { + configurable: true, + get() { + if (!hasInitZIndex) { + zIndex = zIndex || (Vue.prototype.$ELEMENT || {}).zIndex || 2000; + hasInitZIndex = true; + } + return zIndex; + }, + set(value) { + zIndex = value; + } +}); + +const getTopPopup = function() { + if (Vue.prototype.$isServer) return; + if (PopupManager.modalStack.length > 0) { + const topPopup = PopupManager.modalStack[PopupManager.modalStack.length - 1]; + if (!topPopup) return; + const instance = PopupManager.getInstance(topPopup.id); + + return instance; + } +}; + +if (!Vue.prototype.$isServer) { + // handle `esc` key when the popup is shown + window.addEventListener('keydown', function(event) { + if (event.keyCode === 27) { + const topPopup = getTopPopup(); + + if (topPopup && topPopup.closeOnPressEscape) { + topPopup.handleClose + ? topPopup.handleClose() + : (topPopup.handleAction ? topPopup.handleAction('cancel') : topPopup.close()); + } + } + }); +} + +export default PopupManager; diff --git a/src/utils/resize-event.js b/src/utils/resize-event.js new file mode 100644 index 0000000..cd130ba --- /dev/null +++ b/src/utils/resize-event.js @@ -0,0 +1,35 @@ +import ResizeObserver from 'resize-observer-polyfill'; + +const isServer = typeof window === 'undefined'; + +/* istanbul ignore next */ +const resizeHandler = function(entries) { + for (let entry of entries) { + const listeners = entry.target.__resizeListeners__ || []; + if (listeners.length) { + listeners.forEach(fn => { + fn(); + }); + } + } +}; + +/* istanbul ignore next */ +export const addResizeListener = function(element, fn) { + if (isServer) return; + if (!element.__resizeListeners__) { + element.__resizeListeners__ = []; + element.__ro__ = new ResizeObserver(resizeHandler); + element.__ro__.observe(element); + } + element.__resizeListeners__.push(fn); +}; + +/* istanbul ignore next */ +export const removeResizeListener = function(element, fn) { + if (!element || !element.__resizeListeners__) return; + element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); + if (!element.__resizeListeners__.length) { + element.__ro__.disconnect(); + } +}; diff --git a/src/utils/scroll-into-view.js b/src/utils/scroll-into-view.js new file mode 100644 index 0000000..6d5b692 --- /dev/null +++ b/src/utils/scroll-into-view.js @@ -0,0 +1,27 @@ +import Vue from 'vue'; + +export default function scrollIntoView(container, selected) { + if (Vue.prototype.$isServer) return; + + if (!selected) { + container.scrollTop = 0; + return; + } + + const offsetParents = []; + let pointer = selected.offsetParent; + while (pointer && container !== pointer && container.contains(pointer)) { + offsetParents.push(pointer); + pointer = pointer.offsetParent; + } + const top = selected.offsetTop + offsetParents.reduce((prev, curr) => (prev + curr.offsetTop), 0); + const bottom = top + selected.offsetHeight; + const viewRectTop = container.scrollTop; + const viewRectBottom = viewRectTop + container.clientHeight; + + if (top < viewRectTop) { + container.scrollTop = top; + } else if (bottom > viewRectBottom) { + container.scrollTop = bottom - container.clientHeight; + } +} diff --git a/src/utils/scrollbar-width.js b/src/utils/scrollbar-width.js new file mode 100644 index 0000000..bbaa925 --- /dev/null +++ b/src/utils/scrollbar-width.js @@ -0,0 +1,29 @@ +import Vue from 'vue'; + +let scrollBarWidth; + +export default function() { + if (Vue.prototype.$isServer) return 0; + if (scrollBarWidth !== undefined) return scrollBarWidth; + + const outer = document.createElement('div'); + outer.className = 'el-scrollbar__wrap'; + outer.style.visibility = 'hidden'; + outer.style.width = '100px'; + outer.style.position = 'absolute'; + outer.style.top = '-9999px'; + document.body.appendChild(outer); + + const widthNoScroll = outer.offsetWidth; + outer.style.overflow = 'scroll'; + + const inner = document.createElement('div'); + inner.style.width = '100%'; + outer.appendChild(inner); + + const widthWithScroll = inner.offsetWidth; + outer.parentNode.removeChild(outer); + scrollBarWidth = widthNoScroll - widthWithScroll; + + return scrollBarWidth; +}; diff --git a/src/utils/shared.js b/src/utils/shared.js new file mode 100644 index 0000000..3b1ea11 --- /dev/null +++ b/src/utils/shared.js @@ -0,0 +1,7 @@ +export function isDef(val) { + return val !== undefined && val !== null; +} +export function isKorean(text) { + const reg = /([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi; + return reg.test(text); +} diff --git a/src/utils/types.js b/src/utils/types.js new file mode 100644 index 0000000..bfcceed --- /dev/null +++ b/src/utils/types.js @@ -0,0 +1,24 @@ +export function isString(obj) { + return Object.prototype.toString.call(obj) === '[object String]'; +} + +export function isObject(obj) { + return Object.prototype.toString.call(obj) === '[object Object]'; +} + +export function isHtmlElement(node) { + return node && node.nodeType === Node.ELEMENT_NODE; +} + +export const isFunction = (functionToCheck) => { + var getType = {}; + return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; +}; + +export const isUndefined = (val)=> { + return val === void 0; +}; + +export const isDefined = (val) => { + return val !== undefined && val !== null; +}; diff --git a/src/utils/util.js b/src/utils/util.js new file mode 100644 index 0000000..eab9581 --- /dev/null +++ b/src/utils/util.js @@ -0,0 +1,241 @@ +import Vue from 'vue'; +import { isString, isObject } from 'element-ui/src/utils/types'; + +const hasOwnProperty = Object.prototype.hasOwnProperty; + +export function noop() {}; + +export function hasOwn(obj, key) { + return hasOwnProperty.call(obj, key); +}; + +function extend(to, _from) { + for (let key in _from) { + to[key] = _from[key]; + } + return to; +}; + +export function toObject(arr) { + var res = {}; + for (let i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res; +}; + +export const getValueByPath = function(object, prop) { + prop = prop || ''; + const paths = prop.split('.'); + let current = object; + let result = null; + for (let i = 0, j = paths.length; i < j; i++) { + const path = paths[i]; + if (!current) break; + + if (i === j - 1) { + result = current[path]; + break; + } + current = current[path]; + } + return result; +}; + +export function getPropByPath(obj, path, strict) { + let tempObj = obj; + path = path.replace(/\[(\w+)\]/g, '.$1'); + path = path.replace(/^\./, ''); + + let keyArr = path.split('.'); + let i = 0; + for (let len = keyArr.length; i < len - 1; ++i) { + if (!tempObj && !strict) break; + let key = keyArr[i]; + if (key in tempObj) { + tempObj = tempObj[key]; + } else { + if (strict) { + throw new Error('please transfer a valid prop path to form item!'); + } + break; + } + } + return { + o: tempObj, + k: keyArr[i], + v: tempObj ? tempObj[keyArr[i]] : null + }; +}; + +export const generateId = function() { + return Math.floor(Math.random() * 10000); +}; + +export const valueEquals = (a, b) => { + // see: https://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript + if (a === b) return true; + if (!(a instanceof Array)) return false; + if (!(b instanceof Array)) return false; + if (a.length !== b.length) return false; + for (let i = 0; i !== a.length; ++i) { + if (a[i] !== b[i]) return false; + } + return true; +}; + +export const escapeRegexpString = (value = '') => String(value).replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'); + +// TODO: use native Array.find, Array.findIndex when IE support is dropped +export const arrayFindIndex = function(arr, pred) { + for (let i = 0; i !== arr.length; ++i) { + if (pred(arr[i])) { + return i; + } + } + return -1; +}; + +export const arrayFind = function(arr, pred) { + const idx = arrayFindIndex(arr, pred); + return idx !== -1 ? arr[idx] : undefined; +}; + +// coerce truthy value to array +export const coerceTruthyValueToArray = function(val) { + if (Array.isArray(val)) { + return val; + } else if (val) { + return [val]; + } else { + return []; + } +}; + +export const isIE = function() { + return !Vue.prototype.$isServer && !isNaN(Number(document.documentMode)); +}; + +export const isEdge = function() { + return !Vue.prototype.$isServer && navigator.userAgent.indexOf('Edge') > -1; +}; + +export const isFirefox = function() { + return !Vue.prototype.$isServer && !!window.navigator.userAgent.match(/firefox/i); +}; + +export const autoprefixer = function(style) { + if (typeof style !== 'object') return style; + const rules = ['transform', 'transition', 'animation']; + const prefixes = ['ms-', 'webkit-']; + rules.forEach(rule => { + const value = style[rule]; + if (rule && value) { + prefixes.forEach(prefix => { + style[prefix + rule] = value; + }); + } + }); + return style; +}; + +export const kebabCase = function(str) { + const hyphenateRE = /([^-])([A-Z])/g; + return str + .replace(hyphenateRE, '$1-$2') + .replace(hyphenateRE, '$1-$2') + .toLowerCase(); +}; + +export const capitalize = function(str) { + if (!isString(str)) return str; + return str.charAt(0).toUpperCase() + str.slice(1); +}; + +export const looseEqual = function(a, b) { + const isObjectA = isObject(a); + const isObjectB = isObject(b); + if (isObjectA && isObjectB) { + return JSON.stringify(a) === JSON.stringify(b); + } else if (!isObjectA && !isObjectB) { + return String(a) === String(b); + } else { + return false; + } +}; + +export const arrayEquals = function(arrayA, arrayB) { + arrayA = arrayA || []; + arrayB = arrayB || []; + + if (arrayA.length !== arrayB.length) { + return false; + } + + for (let i = 0; i < arrayA.length; i++) { + if (!looseEqual(arrayA[i], arrayB[i])) { + return false; + } + } + + return true; +}; + +export const isEqual = function(value1, value2) { + if (Array.isArray(value1) && Array.isArray(value2)) { + return arrayEquals(value1, value2); + } + return looseEqual(value1, value2); +}; + +export const isEmpty = function(val) { + // null or undefined + if (val == null) return true; + + if (typeof val === 'boolean') return false; + + if (typeof val === 'number') return !val; + + if (val instanceof Error) return val.message === ''; + + switch (Object.prototype.toString.call(val)) { + // String or Array + case '[object String]': + case '[object Array]': + return !val.length; + + // Map or Set or File + case '[object File]': + case '[object Map]': + case '[object Set]': { + return !val.size; + } + // Plain Object + case '[object Object]': { + return !Object.keys(val).length; + } + } + + return false; +}; + +export function rafThrottle(fn) { + let locked = false; + return function(...args) { + if (locked) return; + locked = true; + window.requestAnimationFrame(_ => { + fn.apply(this, args); + locked = false; + }); + }; +} + +export function objToArray(obj) { + if (Array.isArray(obj)) { + return obj; + } + return isEmpty(obj) ? [] : [obj]; +} diff --git a/src/utils/vdom.js b/src/utils/vdom.js new file mode 100644 index 0000000..6bf7028 --- /dev/null +++ b/src/utils/vdom.js @@ -0,0 +1,5 @@ +import { hasOwn } from 'element-ui/src/utils/util'; + +export function isVNode(node) { + return node !== null && typeof node === 'object' && hasOwn(node, 'componentOptions'); +}; diff --git a/src/utils/vue-popper.js b/src/utils/vue-popper.js new file mode 100644 index 0000000..ca35df9 --- /dev/null +++ b/src/utils/vue-popper.js @@ -0,0 +1,198 @@ +import Vue from 'vue'; +import { + PopupManager +} from 'element-ui/src/utils/popup'; + +const PopperJS = Vue.prototype.$isServer ? function() {} : require('./popper'); +const stop = e => e.stopPropagation(); + +/** + * @param {HTMLElement} [reference=$refs.reference] - The reference element used to position the popper. + * @param {HTMLElement} [popper=$refs.popper] - The HTML element used as popper, or a configuration used to generate the popper. + * @param {String} [placement=button] - Placement of the popper accepted values: top(-start, -end), right(-start, -end), bottom(-start, -end), left(-start, -end) + * @param {Number} [offset=0] - Amount of pixels the popper will be shifted (can be negative). + * @param {Boolean} [visible=false] Visibility of the popup element. + * @param {Boolean} [visible-arrow=false] Visibility of the arrow, no style. + */ +export default { + props: { + transformOrigin: { + type: [Boolean, String], + default: true + }, + placement: { + type: String, + default: 'bottom' + }, + boundariesPadding: { + type: Number, + default: 5 + }, + reference: {}, + popper: {}, + offset: { + default: 0 + }, + value: Boolean, + visibleArrow: Boolean, + arrowOffset: { + type: Number, + default: 35 + }, + appendToBody: { + type: Boolean, + default: true + }, + popperOptions: { + type: Object, + default() { + return { + gpuAcceleration: false + }; + } + } + }, + + data() { + return { + showPopper: false, + currentPlacement: '' + }; + }, + + watch: { + value: { + immediate: true, + handler(val) { + this.showPopper = val; + this.$emit('input', val); + } + }, + + showPopper(val) { + if (this.disabled) return; + val ? this.updatePopper() : this.destroyPopper(); + this.$emit('input', val); + } + }, + + methods: { + createPopper() { + if (this.$isServer) return; + this.currentPlacement = this.currentPlacement || this.placement; + if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.currentPlacement)) { + return; + } + + const options = this.popperOptions; + const popper = this.popperElm = this.popperElm || this.popper || this.$refs.popper; + let reference = this.referenceElm = this.referenceElm || this.reference || this.$refs.reference; + + if (!reference && + this.$slots.reference && + this.$slots.reference[0]) { + reference = this.referenceElm = this.$slots.reference[0].elm; + } + + if (!popper || !reference) return; + if (this.visibleArrow) this.appendArrow(popper); + if (this.appendToBody) document.body.appendChild(this.popperElm); + if (this.popperJS && this.popperJS.destroy) { + this.popperJS.destroy(); + } + + options.placement = this.currentPlacement; + options.offset = this.offset; + options.arrowOffset = this.arrowOffset; + this.popperJS = new PopperJS(reference, popper, options); + this.popperJS.onCreate(_ => { + this.$emit('created', this); + this.resetTransformOrigin(); + this.$nextTick(this.updatePopper); + }); + if (typeof options.onUpdate === 'function') { + this.popperJS.onUpdate(options.onUpdate); + } + this.popperJS._popper.style.zIndex = PopupManager.nextZIndex(); + this.popperElm.addEventListener('click', stop); + }, + + updatePopper() { + const popperJS = this.popperJS; + if (popperJS) { + popperJS.update(); + if (popperJS._popper) { + popperJS._popper.style.zIndex = PopupManager.nextZIndex(); + } + } else { + this.createPopper(); + } + }, + + doDestroy(forceDestroy) { + /* istanbul ignore if */ + if (!this.popperJS || (this.showPopper && !forceDestroy)) return; + this.popperJS.destroy(); + this.popperJS = null; + }, + + destroyPopper() { + if (this.popperJS) { + this.resetTransformOrigin(); + } + }, + + resetTransformOrigin() { + if (!this.transformOrigin) return; + let placementMap = { + top: 'bottom', + bottom: 'top', + left: 'right', + right: 'left' + }; + let placement = this.popperJS._popper.getAttribute('x-placement').split('-')[0]; + let origin = placementMap[placement]; + this.popperJS._popper.style.transformOrigin = typeof this.transformOrigin === 'string' + ? this.transformOrigin + : ['top', 'bottom'].indexOf(placement) > -1 ? `center ${ origin }` : `${ origin } center`; + }, + + appendArrow(element) { + let hash; + if (this.appended) { + return; + } + + this.appended = true; + + for (let item in element.attributes) { + if (/^_v-/.test(element.attributes[item].name)) { + hash = element.attributes[item].name; + break; + } + } + + const arrow = document.createElement('div'); + + if (hash) { + arrow.setAttribute(hash, ''); + } + arrow.setAttribute('x-arrow', ''); + arrow.className = 'popper__arrow'; + element.appendChild(arrow); + } + }, + + beforeDestroy() { + this.doDestroy(true); + if (this.popperElm && this.popperElm.parentNode === document.body) { + this.popperElm.removeEventListener('click', stop); + document.body.removeChild(this.popperElm); + } + }, + + // call destroy in keep-alive mode + deactivated() { + this.$options.beforeDestroy[0].call(this); + } +}; diff --git a/test/.eslintrc b/test/.eslintrc new file mode 100644 index 0000000..32ff361 --- /dev/null +++ b/test/.eslintrc @@ -0,0 +1,13 @@ +{ + "env": { + "mocha": true, + "es6": true + }, + "globals": { + "expect": true, + "sinon": true + }, + "parserOptions": { + "ecmaVersion": 2017 + } +} diff --git a/test/ssr/require.test.js b/test/ssr/require.test.js new file mode 100644 index 0000000..3584239 --- /dev/null +++ b/test/ssr/require.test.js @@ -0,0 +1,10 @@ +const path = require('path'); + +try { + process.env.VUE_ENV = 'server'; + require(path.join(process.env.PWD, './lib/index')); + console.log('SSR require test PASS'); +} catch (e) { + console.error('SSR require test error'); + throw Error(e); +} diff --git a/test/unit/index.js b/test/unit/index.js new file mode 100644 index 0000000..fe3fcef --- /dev/null +++ b/test/unit/index.js @@ -0,0 +1,12 @@ +require('babel-regenerator-runtime'); // add regenerator support for async await +require('packages/theme-chalk/lib/index.css'); + +// require all test files (files that ends with .spec.js) +const testsContext = require.context('./specs', true, /\.spec$/); +testsContext.keys().forEach(testsContext); + +// require all src files except main.js for coverage. +// you can also change this to match only the subset of files that +// you want coverage for. +const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/); +srcContext.keys().forEach(srcContext); diff --git a/test/unit/karma.conf.js b/test/unit/karma.conf.js new file mode 100644 index 0000000..73374ca --- /dev/null +++ b/test/unit/karma.conf.js @@ -0,0 +1,31 @@ +const webpackConfig = require('../../build/webpack.test'); + +module.exports = function(config) { + const configuration = { + browsers: ['ChromeHeadless'], + frameworks: ['mocha', 'sinon-chai'], + reporters: ['spec', 'coverage'], + files: ['./index.js'], + preprocessors: { + './index.js': ['webpack', 'sourcemap'] + }, + webpack: webpackConfig, + webpackMiddleware: { + noInfo: true + }, + coverageReporter: { + dir: './coverage', + reporters: [ + { type: 'lcov', subdir: '.' }, + { type: 'text-summary' } + ] + }, + client: { + mocha: { + timeout: 4000 + } + } + }; + + config.set(configuration); +}; diff --git a/test/unit/mocks/uri.js b/test/unit/mocks/uri.js new file mode 100644 index 0000000..ba9a4d3 --- /dev/null +++ b/test/unit/mocks/uri.js @@ -0,0 +1,3 @@ +export const IMAGE_SUCCESS = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAFmklEQVR4Xu2ba2wUVRTH/2cWtlaooFQwKpr4CkESTQBNUAkodGeaKFGD2u6WGPyAmmAEEZmpj1VhBghE/KKGBIztDIXAByWBnQ1oQREfARNiDDHiF1+ooBiksVt295hFiqSdxx3KdmcH5uv+z+3//O65c19TwgX+0AWePy4CuFgBISCQ3J6+DFLuVQKmg2k4gK3xuvwr6+9e+Xe57YViCCRttY1ALX2S/asIPLRB1jvLCSEUAFK2egKgYf0T5a6TxdhtmxqXfl8uCBUHMHfP4rqeE0OOeyS4w5T1hsgCmLNTvaWYp299EpxoyvpX5YBQ8QpotlvvkMBfeCbHvMpUjOejCSCjPSYROrySY/B+SzYmRRJA0tZWEfCcJwBGz81yvDZN6eL5hlDxIZCyta8BTPBLjIv5sVbjyp/8dEF/ryiAlL3kJkD6TsQ0STS5vWHZPhFtEE1FAYiUf28yBaZ7OpRle4IkJ6KtGIDZexfU1hyv/QXASBGjBeYpHYrxmYg2iKZiAFIZdSGIVouaLVJx0obE8v2ielFdRQA83pkemc/lDgE0StRopF6CSVuzCGgWTb6ku7T+aHztpLUng8SIaAe9ApJ265MEflvE3P8a/t2UjTHBYsTUgwqgKauOk4p0gAhxMXunVcwfmYpxX6AYQfGgAWjqTNdL3bndRDRe0NsZGYPXWLKxIGiciH5QAJye8r4UWfE5mWbCE1ZCXy+SUFBN2QEo2+fXjKK6zSDcH9Rcr55i0vj2mUsPnmu8V1xZAZxKXhq+G6A7z9U8Mx+zFOOKc433iysbgNKYj3XnNoHoXj8T3r/z+6ZsPDiwNtyjHQE07dTGSAU8QkX4LlSY6Ndh9UfWnT1Ht2QXjeZifC8INw7UOAMfE2MgB6NdhaFo65ih/+bkxRFAMqPuIaK7xM3zu6ZszO3Vt2S1CcwobXPD8TAfoZjU6LSb7AdgWmd6yLW5nqArrm5T1mtDC+A/Y3tNWe/XqY4VkLK1fwBcItp9DGZLNqQwA2DmgiUbQ0Hgs/NyBpBRD4PoqigBKOWSGxuv2XxruscXQNJWDxJoXJQAMPCnJev9XuouQ0D9PMjcXQ1DAIx9pqJP7tupLrOAZhMhEaUKAGOjqehNYgBsdSOBHo0UAOBlU9ZfFwOQUd8honmRAsA8y1SMrWIAbHUFgRZHCUCe6LqNiWU/igHIaCoR9KgAYMZRS9GvFF4Kp7LqU2B6KzoAeKulGLOEASRtrZkAK0IAVEsxlgsDaM6ojRLRtqgAIImntTcYu4UBpLKtU8D8aRQAMJD/uSZeu2t6Oi8MILldHU8SfRMFAG67wN7cHFeCcz5svaZ4koWvosO9FGbdlI1Wt850BNCSXTSMOX4iEhVAaDAT+o5AAEriVEYrgHBmj+8FI7QVwJzLjei+fPOUN0rnG46P66FoMqMdIUK9SBWEGIDvjZIrgFRGOyR6qBlWAMzQLEU3vDrRvQJsdR+BJlZzBYh8VuM1BHYSQehCMpwVwF1mwqjrewYotBk69RK0tS0AHq7eChC7UPEYAto6As6c9VfdLED8tJkwfL9DcH8J2upqgBZWbwXgalPWD/v59wCgvQTgNb8GSr+H7x3AB0zZuF3EuyuA5oz6jET0pkgjYQPAzEstxSh1oO/jVQFzALzn20IIK0CKFa5vm7niBxHvHgsh9QEQfSDSSP8KWDSaOe54GyvS3sA0vMuUjemibbgPgWzrVInZ8RChb+N9AQSdRkXNiul4qikbn4hp4f5/g7N3vDAiXpCOEcj/IwpG0VT02Nl/9NSOshjvGMinMaJJ9OqYeYulGLODxHkml7TVZ8GYT0Q3uDfKXQxaY8n6i06aZnvJDGKaB8JMAo0IYk5UW7r5BbAtNhRz22YYf4jGlXT+vRuktSrUXgRQhZ12Xi1f8BXwL38cy1+mrtJNAAAAAElFTkSuQmCC'; + +export const IMAGE_FAIL = 'data:image/png;base64,fail'; diff --git a/test/unit/specs/alert.spec.js b/test/unit/specs/alert.spec.js new file mode 100644 index 0000000..5c17d73 --- /dev/null +++ b/test/unit/specs/alert.spec.js @@ -0,0 +1,69 @@ +import { createTest, createVue, destroyVM } from '../util'; +import Alert from 'packages/alert'; + +describe('Alert', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Alert, { + title: 'test', + showIcon: true + }, true); + expect(vm.$el.querySelector('.el-alert__title').textContent).to.equal('test'); + expect(vm.$el.classList.contains('el-alert--info')).to.true; + }); + + it('type', () => { + vm = createTest(Alert, { + title: 'test', + type: 'success', + showIcon: true + }, true); + expect(vm.$el.classList.contains('el-alert--success')).to.true; + }); + + it('description', () => { + vm = createTest(Alert, { + title: 'Dorne', + description: 'Unbowed, Unbent, Unbroken', + showIcon: true + }, true); + expect(vm.$el.querySelector('.el-alert__description').textContent) + .to.equal('Unbowed, Unbent, Unbroken'); + }); + + it('theme', () => { + vm = createTest(Alert, { + title: 'test', + effect: 'dark' + }, true); + expect(vm.$el.classList.contains('is-dark')).to.true; + }); + + it('title slot', () => { + vm = createVue(` + + foo + + `); + + expect(vm.$el.querySelector('.el-alert__title').textContent).to.equal('foo'); + }); + + it('close', () => { + vm = createVue({ + template: ` +
+ +
+ ` + }, true); + vm.$el.querySelector('.el-alert__closebtn').click(); + expect(vm.$children[0].visible).to.false; + }); +}); diff --git a/test/unit/specs/autocomplete.spec.js b/test/unit/specs/autocomplete.spec.js new file mode 100644 index 0000000..1136c1a --- /dev/null +++ b/test/unit/specs/autocomplete.spec.js @@ -0,0 +1,623 @@ +import { createVue, triggerClick, destroyVM, triggerKeyDown } from '../util'; + +describe('Autocomplete', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + it('create', done => { + vm = createVue({ + template: ` +
+ + +
+ `, + data() { + return { + restaurants: [], + state: '' + }; + }, + methods: { + querySearch(queryString, cb) { + var restaurants = this.restaurants; + var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; + cb(results); + }, + createFilter(queryString) { + return (restaurant) => { + return (restaurant.value.indexOf(queryString.toLowerCase()) === 0); + }; + }, + loadAll() { + return [ + { 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' }, + { 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' }, + { 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' }, + { 'value': '泷千家(天山西路店)', 'address': '天山西路438号' } + ]; + } + }, + mounted() { + this.restaurants = this.loadAll(); + } + }, true); + let elm = vm.$el; + let inputElm = elm.querySelector('input'); + inputElm.focus(); + + expect(inputElm.getAttribute('placeholder')).to.be.equal('请输入内容autocomplete1'); + + setTimeout(_ => { + const suggestions = vm.$refs.autocomplete.$refs.suggestions.$el; + expect(suggestions.style.display).to.not.equal('none'); + expect(suggestions.querySelectorAll('.el-autocomplete-suggestion__list li').length).to.be.equal(4); + + triggerClick(document); + setTimeout(_ => { + expect(suggestions.style.display).to.be.equal('none'); + done(); + }, 500); + }, 500); + }); + it('select', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + restaurants: [], + state: '' + }; + }, + methods: { + querySearch(queryString, cb) { + var restaurants = this.restaurants; + var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; + cb(results); + }, + createFilter(queryString) { + return (restaurant) => { + return (restaurant.value.indexOf(queryString.toLowerCase()) === 0); + }; + }, + loadAll() { + return [ + { 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' }, + { 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' }, + { 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' }, + { 'value': '泷千家(天山西路店)', 'address': '天山西路438号' } + ]; + } + }, + mounted() { + this.restaurants = this.loadAll(); + } + }, true); + const autocomplete = vm.$refs.autocomplete; + const elm = vm.$el; + const inputElm = elm.querySelector('input'); + const spy = sinon.spy(); + + autocomplete.$on('select', spy); + inputElm.focus(); + + setTimeout(_ => { + const suggestions = autocomplete.$refs.suggestions.$el; + const suggestionList = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li'); + suggestionList[1].click(); + setTimeout(_ => { + expect(inputElm.value).to.be.equal('Hot honey 首尔炸鸡(仙霞路)'); + expect(vm.state).to.be.equal('Hot honey 首尔炸鸡(仙霞路)'); + expect(spy.withArgs().calledOnce).to.be.true; + expect(suggestions.style.display).to.be.equal('none'); + done(); + }, 500); + }, 500); + }); + it('input', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + restaurants: [], + state: '' + }; + }, + methods: { + querySearch(queryString, cb) { + var restaurants = this.restaurants; + var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; + cb(results); + }, + createFilter(queryString) { + return (restaurant) => { + return (restaurant.value.indexOf(queryString.toLowerCase()) === 0); + }; + }, + loadAll() { + return [ + { 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' }, + { 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' }, + { 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' }, + { 'value': '泷千家(天山西路店)', 'address': '天山西路438号' } + ]; + } + }, + mounted() { + this.restaurants = this.loadAll(); + } + }, true); + const autocomplete = vm.$refs.autocomplete; + const input = autocomplete.$refs.input; + input.$emit('input', '三'); + setTimeout(() => { + expect(vm.state).to.be.equal('三'); + expect(autocomplete.suggestions[0].value).to.be.equal('三全鲜食(北新泾店)'); + input.$emit('input', ''); + setTimeout(() => { + expect(vm.state).to.be.equal(''); + expect(autocomplete.suggestions.length).to.be.equal(0); + done(); + }, 500); + }, 500); + }); + describe('enter select', () => { + const createVm = (selectWhenUnmatched = false) => { + return createVue({ + template: ` + + `, + data() { + return { + restaurants: [], + state: '', + selectWhenUnmatched: selectWhenUnmatched, + item: {} + }; + }, + methods: { + querySearch(queryString, cb) { + var restaurants = this.restaurants; + var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; + cb(results); + }, + createFilter(queryString) { + return (restaurant) => { + return (restaurant.value.indexOf(queryString.toLowerCase()) === 0); + }; + }, + loadAll() { + return [ + { 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' }, + { 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' }, + { 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' }, + { 'value': '泷千家(天山西路店)', 'address': '天山西路438号' } + ]; + }, + handleSelect(item) { + this.item = item; + } + }, + mounted() { + this.restaurants = this.loadAll(); + } + }, true); + }; + it('select', done => { + vm = createVm(); + const autocomplete = vm.$refs.autocomplete; + const input = autocomplete.$refs.input; + input.$el.querySelector('input').focus(); + input.$emit('input', '三'); + setTimeout(() => { + triggerKeyDown(input.$el, 40); // down + setTimeout(() => { + triggerKeyDown(input.$el, 13); // enter + setTimeout(() => { + expect(vm.item.address).to.be.equal('长宁区新渔路144号'); + done(); + }, 200); + }, 200); + }, 500); + }); + it('select unmatched', done => { + vm = createVm(true); + const autocomplete = vm.$refs.autocomplete; + const input = autocomplete.$refs.input; + input.$emit('input', '关键字'); + setTimeout(() => { + expect(autocomplete.suggestions.length).to.be.equal(0); + triggerKeyDown(input.$el, 13); // enter + setTimeout(() => { + expect(autocomplete.highlightedIndex).to.be.equal(-1); + expect(vm.item.value).to.be.equal('关键字'); + done(); + }, 500); + }, 500); + }); + }); + it('props', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + restaurants: [], + state: '' + }; + }, + methods: { + querySearch(queryString, cb) { + var restaurants = this.restaurants; + var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; + cb(results); + }, + createFilter(queryString) { + return (restaurant) => { + return (restaurant.value.indexOf(queryString.toLowerCase()) === 0); + }; + }, + loadAll() { + return [ + { 'name': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' }, + { 'name': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' }, + { 'name': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' }, + { 'name': '泷千家(天山西路店)', 'address': '天山西路438号' } + ]; + } + }, + mounted() { + this.restaurants = this.loadAll(); + } + }, true); + const autocomplete = vm.$refs.autocomplete; + const elm = vm.$el; + const inputElm = elm.querySelector('input'); + const spy = sinon.spy(); + + autocomplete.$on('select', spy); + inputElm.focus(); + + setTimeout(_ => { + const suggestions = autocomplete.$refs.suggestions.$el; + const suggestionList = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li'); + expect(suggestionList[1].innerHTML === '上海市长宁区淞虹路661号'); + suggestionList[1].click(); + setTimeout(_ => { + expect(inputElm.value).to.be.equal('上海市长宁区淞虹路661号'); + expect(vm.state).to.be.equal('上海市长宁区淞虹路661号'); + expect(spy.withArgs().calledOnce).to.be.true; + expect(suggestions.style.display).to.be.equal('none'); + done(); + }, 500); + }, 500); + }); + it('highlight', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + restaurants: [], + state: '' + }; + }, + methods: { + querySearch(queryString, cb) { + var restaurants = this.restaurants; + var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; + cb(results); + }, + createFilter(queryString) { + return (restaurant) => { + return (restaurant.value.indexOf(queryString.toLowerCase()) === 0); + }; + }, + loadAll() { + return [ + { 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' }, + { 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' }, + { 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' }, + { 'value': '泷千家(天山西路店)', 'address': '天山西路438号' }, + { 'value': '胖仙女纸杯蛋糕(上海凌空店)', 'address': '上海市长宁区金钟路968号1幢18号楼一层商铺18-101' }, + { 'value': '贡茶', 'address': '上海市长宁区金钟路633号' }, + { 'value': '豪大大香鸡排超级奶爸', 'address': '上海市嘉定区曹安公路曹安路1685号' }, + { 'value': '茶芝兰(奶茶,手抓饼)', 'address': '上海市普陀区同普路1435号' }, + { 'value': '十二泷町', 'address': '上海市北翟路1444弄81号B幢-107' }, + { 'value': '星移浓缩咖啡', 'address': '上海市嘉定区新郁路817号' }, + { 'value': '阿姨奶茶/豪大大', 'address': '嘉定区曹安路1611号' }, + { 'value': '新麦甜四季甜品炸鸡', 'address': '嘉定区曹安公路2383弄55号' }, + { 'value': 'Monica摩托主题咖啡店', 'address': '嘉定区江桥镇曹安公路2409号1F,2383弄62号1F' }, + { 'value': '浮生若茶(凌空soho店)', 'address': '上海长宁区金钟路968号9号楼地下一层' }, + { 'value': 'NONO JUICE 鲜榨果汁', 'address': '上海市长宁区天山西路119号' }, + { 'value': 'CoCo都可(北新泾店)', 'address': '上海市长宁区仙霞西路' }, + { 'value': '快乐柠檬(神州智慧店)', 'address': '上海市长宁区天山西路567号1层R117号店铺' }, + { 'value': 'Merci Paul cafe', 'address': '上海市普陀区光复西路丹巴路28弄6号楼819' }, + { 'value': '猫山王(西郊百联店)', 'address': '上海市长宁区仙霞西路88号第一层G05-F01-1-306' }, + { 'value': '枪会山', 'address': '上海市普陀区棕榈路' }, + { 'value': '纵食', 'address': '元丰天山花园(东门) 双流路267号' }, + { 'value': '钱记', 'address': '上海市长宁区天山西路' } + ]; + } + }, + mounted() { + this.restaurants = this.loadAll(); + } + }, true); + const autocomplete = vm.$refs.autocomplete; + const inputElm = autocomplete.$el.querySelector('input'); + + inputElm.focus(); + + setTimeout(_ => { + autocomplete.highlight(8); + vm.$nextTick(_ => { + const suggestions = autocomplete.$refs.suggestions.$el.querySelector('.el-autocomplete-suggestion__wrap'); + let suggestionsList = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li'); + let highlightedItem = suggestionsList[8]; + expect(highlightedItem.classList.contains('highlighted')).to.be.true; + expect(suggestions.scrollTop === highlightedItem.scrollHeight).to.be.true; + done(); + }); + }, 500); + }); + it('highlight out of bounds', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + restaurants: [], + state: '' + }; + }, + methods: { + querySearch(queryString, cb) { + var restaurants = this.restaurants; + var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; + cb(results); + }, + createFilter(queryString) { + return (restaurant) => { + return (restaurant.value.indexOf(queryString.toLowerCase()) === 0); + }; + }, + loadAll() { + return [ + { 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' }, + { 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' }, + { 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' }, + { 'value': '泷千家(天山西路店)', 'address': '天山西路438号' }, + { 'value': '胖仙女纸杯蛋糕(上海凌空店)', 'address': '上海市长宁区金钟路968号1幢18号楼一层商铺18-101' }, + { 'value': '贡茶', 'address': '上海市长宁区金钟路633号' }, + { 'value': '豪大大香鸡排超级奶爸', 'address': '上海市嘉定区曹安公路曹安路1685号' }, + { 'value': '茶芝兰(奶茶,手抓饼)', 'address': '上海市普陀区同普路1435号' }, + { 'value': '十二泷町', 'address': '上海市北翟路1444弄81号B幢-107' }, + { 'value': '星移浓缩咖啡', 'address': '上海市嘉定区新郁路817号' }, + { 'value': '阿姨奶茶/豪大大', 'address': '嘉定区曹安路1611号' }, + { 'value': '新麦甜四季甜品炸鸡', 'address': '嘉定区曹安公路2383弄55号' } + ]; + } + }, + mounted() { + this.restaurants = this.loadAll(); + } + }, true); + const autocomplete = vm.$refs.autocomplete; + let inputElm = vm.$el.querySelector('input'); + inputElm.focus(); + + setTimeout(_ => { + autocomplete.highlight(15); + vm.$nextTick(_ => { + const suggestions = autocomplete.$refs.suggestions.$el; + const suggestionsList = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li'); + let highlightedItem = suggestionsList[11]; + expect(highlightedItem.className).to.be.equal('highlighted'); + done(); + }); + }, 500); + }); + it('triggerOnFocus', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + restaurants: [], + state: '' + }; + }, + methods: { + querySearch(queryString, cb) { + var restaurants = this.restaurants; + var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; + cb(results); + }, + createFilter(queryString) { + return (restaurant) => { + return (restaurant.value.indexOf(queryString.toLowerCase()) === 0); + }; + }, + loadAll() { + return [ + { 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' }, + { 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' }, + { 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' }, + { 'value': '泷千家(天山西路店)', 'address': '天山西路438号' } + ]; + } + }, + mounted() { + this.restaurants = this.loadAll(); + } + }, true); + let inputElm = vm.$el.querySelector('input'); + inputElm.focus(); + + setTimeout(_ => { + let suggestions = vm.$refs.autocomplete.$refs.suggestions.$el; + expect(suggestions.style.display).to.be.equal('none'); + done(); + }, 500); + }); + it('event:focus & blur', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + restaurants: [], + state: '' + }; + }, + methods: { + querySearch(queryString, cb) { + var restaurants = this.restaurants; + var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; + cb(results); + }, + createFilter(queryString) { + return (restaurant) => { + return (restaurant.value.indexOf(queryString.toLowerCase()) === 0); + }; + }, + loadAll() { + return [ + { 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' }, + { 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' }, + { 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' }, + { 'value': '泷千家(天山西路店)', 'address': '天山西路438号' } + ]; + } + }, + mounted() { + this.restaurants = this.loadAll(); + } + }, true); + + const spyFocus = sinon.spy(); + const spyBlur = sinon.spy(); + + vm.$refs.input.$on('focus', spyFocus); + vm.$refs.input.$on('blur', spyBlur); + vm.$el.querySelector('input').focus(); + vm.$el.querySelector('input').blur(); + + vm.$nextTick(_ => { + expect(spyFocus.calledOnce).to.be.true; + expect(spyBlur.calledOnce).to.be.true; + done(); + }); + }); + it('can highlight first item', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + restaurants: [], + state: '' + }; + }, + methods: { + querySearch(queryString, cb) { + const opts = [ + { 'value': '1' }, + { 'value': '11' }, + { 'value': '2' }, + { 'value': '22' } + ]; + cb( + queryString + ? opts.filter(opt => opt.value.indexOf(queryString) >= 0) + : opts + ); + } + } + }, true); + let elm = vm.$el; + let inputElm = elm.querySelector('input'); + inputElm.focus(); + + const autocomplete = vm.$refs.autocomplete; + const input = autocomplete.$refs.input; + input.$emit('input', '1'); + + setTimeout(_ => { + const suggestions = vm.$refs.autocomplete.$refs.suggestions.$el; + const items = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li'); + + expect(items.length).to.equal(2); + expect(items[0].classList.contains('highlighted')).to.be.true; + + done(); + }, 500); + }); +}); diff --git a/test/unit/specs/avatar.spec.js b/test/unit/specs/avatar.spec.js new file mode 100644 index 0000000..bf5d159 --- /dev/null +++ b/test/unit/specs/avatar.spec.js @@ -0,0 +1,119 @@ +import { createTest, createVue, destroyVM, wait } from '../util'; +import Avatar from 'packages/avatar'; +import { IMAGE_SUCCESS, IMAGE_FAIL } from '../mocks/uri'; + +describe('Avatar', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Avatar); + expect(vm.$el).to.exist; + }); + + it('size is number', () => { + vm = createVue({ + template: ` + + + ` + }, true); + const avatarElm = vm.$el; + expect(avatarElm.style.height).to.equal('50px'); + }); + + it('size is string', () => { + vm = createVue({ + template: ` + + user + + ` + }, true); + const avatarElm = vm.$el; + expect(avatarElm.classList.contains('el-avatar--small')).to.be.true; + }); + + it('shape', () => { + vm = createVue({ + template: ` + + user + + ` + }, true); + const avatarElm = vm.$el; + expect(avatarElm.classList.contains('el-avatar--square')).to.be.true; + }); + + it('icon avatar', () => { + vm = createVue({ + template: ` + + + ` + }, true); + const avatarElm = vm.$el; + const iconELm = avatarElm.children[0]; + expect(avatarElm.classList.contains('el-avatar--icon')).to.be.true; + expect(iconELm.classList.contains('el-icon-user-solid')).to.be.true; + }); + + it('image avatar', () => { + vm = createVue({ + template: ` + + ` + }, true); + const imgElm = vm.$el.children[0]; + expect(imgElm.tagName.toUpperCase()).to.equal('IMG'); + expect(imgElm.src).to.equal(IMAGE_SUCCESS); + }); + + it('image fallback', async() => { + vm = createVue({ + template: ` + + fallback + + `, + methods: { + errorHandler() { + return true; + } + } + }, true); + await wait(); + const avatarElm = vm.$el; + expect(avatarElm.textContent.trim()).to.equal('fallback'); + }); + + it('image fit', async() => { + vm = createVue({ + template: ` +
+ + +
+ + `, + data() { + return { + fits: ['fill', 'contain', 'cover', 'none', 'scale-down'], + url: IMAGE_SUCCESS + }; + } + }, true); + await wait(); + const containerElm = vm.$el; + expect(containerElm.children[0].children[0].style.objectFit).to.equal('cover'); + expect(containerElm.children[1].children[0].style.objectFit).to.equal('fill'); + expect(containerElm.children[2].children[0].style.objectFit).to.equal('contain'); + expect(containerElm.children[3].children[0].style.objectFit).to.equal('cover'); + expect(containerElm.children[4].children[0].style.objectFit).to.equal('none'); + expect(containerElm.children[5].children[0].style.objectFit).to.equal('scale-down'); + }); +}); + diff --git a/test/unit/specs/backtop.spec.js b/test/unit/specs/backtop.spec.js new file mode 100644 index 0000000..05de566 --- /dev/null +++ b/test/unit/specs/backtop.spec.js @@ -0,0 +1,28 @@ +import { createVue, destroyVM, wait } from '../util'; + +describe('Backtop', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', async() => { + vm = createVue({ + template: ` +
+
+ + test_up_text + +
+
+ ` + }, true); + expect(vm.$el).to.exist; + expect(vm.$el.innerText).to.be.equal(''); + vm.$refs.scrollTarget.scrollTop = 2000; + await wait(); + expect(vm.$el.innerText).to.be.equal('test_up_text'); + }); +}); + diff --git a/test/unit/specs/badge.spec.js b/test/unit/specs/badge.spec.js new file mode 100644 index 0000000..cfcf122 --- /dev/null +++ b/test/unit/specs/badge.spec.js @@ -0,0 +1,41 @@ +import { createTest, createVue, destroyVM } from '../util'; +import Badge from 'packages/badge'; + +describe('Badge', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('value', () => { + vm = createTest(Badge, { value: 80 }); + expect(vm.content).to.equal(80); + }); + + it('is fixed', () => { + vm = createVue(` + + + + `); + + expect(vm.$el.querySelector('.el-badge__content.is-fixed')).to.exist; + }); + + it('is dot', () => { + vm = createVue(` + + + + `); + + expect(vm.$el.querySelector('.el-badge__content.is-dot')).to.exist; + }); + + it('max', () => { + vm = createTest(Badge, { max: 100, value: 200 }); + expect(vm.content).to.equal('100+'); + vm = createTest(Badge, { max: 100, value: 80 }); + expect(vm.content).to.equal(80); + }); +}); diff --git a/test/unit/specs/breadcrumb.spec.js b/test/unit/specs/breadcrumb.spec.js new file mode 100644 index 0000000..035b0df --- /dev/null +++ b/test/unit/specs/breadcrumb.spec.js @@ -0,0 +1,23 @@ +import { createVue, destroyVM } from '../util'; + +describe('Breadcrumb', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', done => { + vm = createVue(` + + 首页 + 活动管理 + 活动列表 + 活动详情 + + `); + vm.$nextTick(_ => { + expect(vm.$el.querySelector('.el-breadcrumb__separator').innerText).to.equal('>'); + done(); + }); + }); +}); diff --git a/test/unit/specs/button.spec.js b/test/unit/specs/button.spec.js new file mode 100644 index 0000000..7c1e5c0 --- /dev/null +++ b/test/unit/specs/button.spec.js @@ -0,0 +1,133 @@ +import { createTest, createVue, destroyVM } from '../util'; +import Button from 'packages/button'; + +describe('Button', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Button, { + type: 'primary' + }, true); + let buttonElm = vm.$el; + expect(buttonElm.classList.contains('el-button--primary')).to.be.true; + }); + it('icon', () => { + vm = createTest(Button, { + icon: 'el-icon-search' + }, true); + let buttonElm = vm.$el; + expect(buttonElm.querySelector('.el-icon-search')).to.be.ok; + }); + it('nativeType', () => { + vm = createTest(Button, { + nativeType: 'submit' + }, true); + let buttonElm = vm.$el; + expect(buttonElm.getAttribute('type')).to.be.equal('submit'); + }); + it('loading', () => { + vm = createTest(Button, { + loading: true + }, true); + let buttonElm = vm.$el; + expect(buttonElm.classList.contains('is-loading')).to.be.true; + expect(buttonElm.querySelector('.el-icon-loading')).to.be.ok; + }); + it('disabled', () => { + vm = createTest(Button, { + disabled: true + }, true); + let buttonElm = vm.$el; + expect(buttonElm.classList.contains('is-disabled')).to.be.true; + }); + it('size', () => { + vm = createTest(Button, { + size: 'medium' + }, true); + let buttonElm = vm.$el; + expect(buttonElm.classList.contains('el-button--medium')).to.be.true; + }); + it('plain', () => { + vm = createTest(Button, { + plain: true + }, true); + let buttonElm = vm.$el; + expect(buttonElm.classList.contains('is-plain')).to.be.true; + }); + it('round', () => { + vm = createTest(Button, { + round: true + }, true); + let buttonElm = vm.$el; + expect(buttonElm.classList.contains('is-round')).to.be.true; + }); + it('circle', () => { + vm = createTest(Button, { + circle: true + }, true); + let buttonElm = vm.$el; + expect(buttonElm.classList.contains('is-circle')).to.be.true; + }); + it('click', done => { + let result; + vm = createVue({ + template: ` + + `, + methods: { + handleClick(evt) { + result = evt; + } + } + }, true); + vm.$el.click(); + + setTimeout(_ => { + expect(result).to.exist; + done(); + }, 20); + }); + + it('click inside', done => { + let result; + vm = createVue({ + template: ` + + `, + methods: { + handleClick(evt) { + result = evt; + } + } + }, true); + vm.$el.querySelector('.inner-slot').click(); + + setTimeout(_ => { + expect(result).to.exist; + done(); + }, 20); + }); + + it('loading implies disabled', done => { + let result; + vm = createVue({ + template: ` + + `, + methods: { + handleClick(evt) { + result = evt; + } + } + }, true); + vm.$el.querySelector('.inner-slot').click(); + + setTimeout(_ => { + expect(result).to.not.exist; + done(); + }, 20); + }); +}); diff --git a/test/unit/specs/calendar.spec.js b/test/unit/specs/calendar.spec.js new file mode 100644 index 0000000..a393e96 --- /dev/null +++ b/test/unit/specs/calendar.spec.js @@ -0,0 +1,108 @@ +import { createVue, destroyVM, waitImmediate } from '../util'; + +describe('Calendar', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: new Date('2019-04-01') + }; + } + }, true); + const titleEl = vm.$el.querySelector('.el-calendar__title'); + expect(/2019.*4/.test(titleEl.innerText)).to.be.true; + expect(vm.$el.querySelectorAll('thead th').length).to.equal(7); + const rows = vm.$el.querySelectorAll('.el-calendar-table__row'); + expect(rows.length).to.equal(6); + rows[5].firstElementChild.click(); + + await waitImmediate(); + + expect(/2019.*5/.test(titleEl.innerText)).to.be.true; + const value = vm.value; + expect(value.getFullYear()).to.be.equal(2019); + expect(value.getMonth()).to.be.equal(4); + expect(vm.$el.querySelector('.is-selected span').innerText).to.be.equal('6'); + }); + + it('range', () => { + vm = createVue({ + template: ` + + ` + }, true); + const titleEl = vm.$el.querySelector('.el-calendar__title'); + expect(/2019.*3/.test(titleEl.innerText)).to.be.true; + const rows = vm.$el.querySelectorAll('.el-calendar-table__row'); + expect(rows.length).to.equal(3); + expect(vm.$el.querySelector('.el-calendar__button-group')).to.be.a('null'); + }); + + it('range tow monthes', async() => { + vm = createVue({ + template: ` + + ` + }, true); + const titleEl = vm.$el.querySelector('.el-calendar__title'); + expect(/2019.*4/.test(titleEl.innerText)).to.be.true; + const dateTables = vm.$el.querySelectorAll('.el-calendar-table.is-range'); + expect(dateTables.length).to.be.equal(2); + const rows = vm.$el.querySelectorAll('.el-calendar-table__row'); + expect(rows.length).to.equal(5); + const cell = rows[rows.length - 1].firstElementChild; + cell.click(); + + await waitImmediate(); + + expect(/2019.*5/.test(titleEl.innerText)).to.be.true; + expect(cell.classList.contains('is-selected')).to.be.true; + }); + + it('firstDayOfWeek', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: new Date('2019-04-01') + }; + } + }, true); + const head = vm.$el.querySelector('.el-calendar-table thead'); + expect(head.firstElementChild.innerText).to.be.equal('日'); + expect(head.lastElementChild.innerText).to.be.equal('六'); + const firstRow = vm.$el.querySelector('.el-calendar-table__row'); + expect(firstRow.firstElementChild.innerText).to.be.equal('31'); + expect(firstRow.lastElementChild.innerText).to.be.equal('6'); + }); + + it('firstDayOfWeek in range mode', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: new Date('2019-03-04') + }; + } + }, true); + const head = vm.$el.querySelector('.el-calendar-table thead'); + expect(head.firstElementChild.innerText).to.be.equal('日'); + expect(head.lastElementChild.innerText).to.be.equal('六'); + const firstRow = vm.$el.querySelector('.el-calendar-table__row'); + expect(firstRow.firstElementChild.innerText).to.be.equal('3'); + expect(firstRow.lastElementChild.innerText).to.be.equal('9'); + }); +}); + diff --git a/test/unit/specs/card.spec.js b/test/unit/specs/card.spec.js new file mode 100644 index 0000000..f80cfb2 --- /dev/null +++ b/test/unit/specs/card.spec.js @@ -0,0 +1,56 @@ +import { createVue, createTest, destroyVM } from '../util'; +import Card from 'packages/card'; + +describe('Card', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('slot:header', () => { + vm = createVue(` + +
二师兄叫我埋梗 啦啦啦
+
+ `); + + expect(vm.$el.querySelector('.el-card__header')).to.property('textContent').to.include('二师兄叫我埋梗 啦啦啦'); + }); + + it('header', () => { + vm = createTest(Card, { + header: '好烦' + }); + + expect(vm.$el.querySelector('.el-card__header')).to.property('textContent').to.include('好烦'); + }); + + it('bodyStyle', () => { + vm = createTest(Card, { + bodyStyle: { padding: '10px' } + }); + + expect(vm.$el.querySelector('.el-card__body').style.padding).to.equal('10px'); + }); + + it('shadow', () => { + vm = createTest(Card, { + shadow: 'always' + }); + expect(vm.$el.classList.contains('is-always-shadow')).to.be.true; + }); + + it('shadow', () => { + vm = createTest(Card, { + shadow: 'hover' + }); + expect(vm.$el.classList.contains('is-hover-shadow')).to.be.true; + }); + + it('shadow', () => { + vm = createTest(Card, { + shadow: 'never' + }); + expect(vm.$el.classList.contains('is-never-shadow')).to.be.true; + }); +}); diff --git a/test/unit/specs/carousel.spec.js b/test/unit/specs/carousel.spec.js new file mode 100644 index 0000000..635d479 --- /dev/null +++ b/test/unit/specs/carousel.spec.js @@ -0,0 +1,277 @@ +import { createVue, destroyVM } from '../util'; + +describe('Carousel', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + expect(vm.$refs.carousel.direction).to.be.equal('horizontal'); + expect(vm.$el.querySelectorAll('.el-carousel__item').length).to.equal(3); + }); + + it('auto play', done => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + + setTimeout(() => { + const items = vm.$el.querySelectorAll('.el-carousel__item'); + expect(items[0].classList.contains('is-active')).to.true; + setTimeout(() => { + expect(items[1].classList.contains('is-active')).to.true; + done(); + }, 60); + }, 10); + }); + + it('initial index', done => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-carousel__item')[1].classList.contains('is-active')).to.true; + done(); + }, 10); + }); + + it('reset timer', done => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + + setTimeout(() => { + const carousel = vm.$children[0]; + const items = vm.$el.querySelectorAll('.el-carousel__item'); + carousel.handleMouseEnter(); + setTimeout(() => { + expect(items[0].classList.contains('is-active')).to.true; + carousel.handleMouseLeave(); + setTimeout(() => { + expect(items[1].classList.contains('is-active')).to.true; + done(); + }, 30); + }, 20); + }, 10); + }); + + it('change', done => { + vm = createVue({ + template: ` +
+ + + +
+ `, + data() { + return { + val: -1, + oldVal: -1 + }; + }, + methods: { + handleChange(val, oldVal) { + this.val = val; + this.oldVal = oldVal; + } + } + }); + + setTimeout(() => { + expect(vm.val).to.equal(1); + expect(vm.oldVal).to.equal(0); + done(); + }, 60); + }); + + it('label', done => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + setTimeout(_ => { + expect(vm.$el.querySelector('.el-carousel__button').innerText).to.equal('1'); + done(); + }, 10); + }); + + describe('manual control', () => { + it('hover', done => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + + setTimeout(() => { + vm.$children[0].throttledIndicatorHover(1); + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-carousel__item')[1].classList.contains('is-active')).to.true; + done(); + }, 10); + }, 10); + }); + + it('click', done => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + + setTimeout(() => { + const items = vm.$el.querySelectorAll('.el-carousel__item'); + const carousel = vm.$refs.carousel; + vm.$el.querySelectorAll('.el-carousel__indicator')[2].click(); + setTimeout(() => { + expect(items[2].classList.contains('is-active')).to.true; + carousel.handleButtonEnter('right'); + vm.$el.querySelector('.el-carousel__arrow--right').click(); + setTimeout(() => { + expect(items[0].classList.contains('is-active')).to.true; + done(); + }, 10); + }, 10); + }, 10); + }); + }); + + describe('methods', () => { + it('setActiveItem', done => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + + setTimeout(() => { + vm.$children[0].setActiveItem(1); + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-carousel__item')[1].classList.contains('is-active')).to.true; + done(); + }, 10); + }, 10); + }); + + it('slide', done => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + + setTimeout(() => { + vm.$children[0].prev(1); + const items = vm.$el.querySelectorAll('.el-carousel__item'); + setTimeout(() => { + expect(items[2].classList.contains('is-active')).to.true; + vm.$children[0].next(1); + setTimeout(() => { + expect(items[0].classList.contains('is-active')).to.true; + done(); + }, 10); + }, 10); + }, 10); + }); + }); + + it('card', done => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + + setTimeout(() => { + const items = vm.$el.querySelectorAll('.el-carousel__item'); + expect(items[0].classList.contains('is-active')).to.true; + expect(items[1].classList.contains('is-in-stage')).to.true; + expect(items[6].classList.contains('is-in-stage')).to.true; + items[1].click(); + setTimeout(() => { + expect(items[1].classList.contains('is-active')).to.true; + vm.$el.querySelector('.el-carousel__arrow--left').click(); + setTimeout(() => { + expect(items[0].classList.contains('is-active')).to.true; + items[6].click(); + setTimeout(() => { + expect(items[6].classList.contains('is-active')).to.true; + done(); + }, 10); + }, 10); + }, 10); + }, 10); + }); + + it('vertical direction', () => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }); + const items = vm.$el.querySelectorAll('.el-carousel__item'); + + expect(vm.$refs.carousel.direction).to.be.equal('vertical'); + expect(items[0].style.transform.indexOf('translateY') !== -1).to.be.true; + }); +}); + diff --git a/test/unit/specs/cascader-panel.spec.js b/test/unit/specs/cascader-panel.spec.js new file mode 100644 index 0000000..fda7d75 --- /dev/null +++ b/test/unit/specs/cascader-panel.spec.js @@ -0,0 +1,581 @@ +import { + createTest, + createVue, + destroyVM, + waitImmediate, + wait, + triggerEvent +} from '../util'; +import CascaderPanel from 'packages/cascader-panel'; + +const selectedValue = ['zhejiang', 'hangzhou', 'xihu']; + +const options = [{ + value: 'zhejiang', + label: 'Zhejiang', + children: [{ + value: 'hangzhou', + label: 'Hangzhou', + children: [{ + value: 'xihu', + label: 'West Lake' + }, { + value: 'binjiang', + label: 'Bin Jiang' + }] + }, { + value: 'ningbo', + label: 'NingBo', + children: [{ + value: 'jiangbei', + label: 'Jiang Bei' + }, { + value: 'jiangdong', + label: 'Jiang Dong', + disabled: true + }] + }] +}, { + value: 'jiangsu', + label: 'Jiangsu', + disabled: true, + children: [{ + value: 'nanjing', + label: 'Nanjing', + children: [{ + value: 'zhonghuamen', + label: 'Zhong Hua Men' + }] + }] +}]; + +const options2 = [{ + id: 'zhejiang', + name: 'Zhejiang', + areas: [{ + id: 'hangzhou', + name: 'Hangzhou', + areas: [{ + id: 'xihu', + name: 'West Lake' + }, { + id: 'binjiang', + name: 'Bin Jiang' + }] + }, { + id: 'ningbo', + name: 'NingBo', + areas: [{ + id: 'jiangbei', + label: 'Jiang Bei' + }, { + id: 'jiangdong', + name: 'Jiang Dong', + invalid: true + }] + }] +}, { + id: 'jiangsu', + name: 'Jiangsu', + invalid: true, + areas: [{ + id: 'nanjing', + name: 'Nanjing', + areas: [{ + id: 'zhonghuamen', + name: 'Zhong Hua Men' + }] + }] +}]; + +const options3 = [ + { + value: 'shanghai', + label: '上海', + children: [ + { + value: 'baoshan', + label: '宝山' + } + ] + }, + { + value: 'beijing', + label: '北京' + } +]; + +const getMenus = el => el.querySelectorAll('.el-cascader-menu'); +const getOptions = (el, menuIndex) => getMenus(el)[menuIndex].querySelectorAll('.el-cascader-node'); +const getValidOptions = (el, menuIndex) => getMenus(el)[menuIndex].querySelectorAll('.el-cascader-node[tabindex="-1"]'); +const getLabel = el => el.querySelector('.el-cascader-node__label').textContent; + +describe('CascaderPanel', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(CascaderPanel, true); + expect(vm.$el).to.exist; + }); + + it('expand and check', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options + }; + } + }, true); + + const el = vm.$el; + const expandHandler = sinon.spy(); + const changeHandler = sinon.spy(); + vm.$refs.panel.$on('expand-change', expandHandler); + vm.$refs.panel.$on('change', changeHandler); + + expect(getMenus(el).length).to.equal(1); + expect(getOptions(el, 0).length).to.equal(2); + + const firstOption = getOptions(el, 0)[0]; + expect(getLabel(firstOption)).to.equal('Zhejiang'); + firstOption.click(); + await waitImmediate(); + expect(expandHandler.calledOnceWith(['zhejiang'])).to.be.true; + expect(getMenus(el).length).to.equal(2); + + getOptions(el, 1)[0].click(); + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + + getOptions(el, 2)[0].click(); + await waitImmediate(); + expect(changeHandler.calledOnceWith(selectedValue)).to.be.true; + expect(vm.value).to.deep.equal(selectedValue); + }); + + it('with default value', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: selectedValue, + options + }; + } + }, true); + + const el = vm.$el; + + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + expect(getOptions(el, 0)[0].className).to.includes('in-active-path'); + expect(getOptions(el, 2)[0].className).to.includes('is-active'); + expect(getOptions(el, 2)[0].querySelector('.el-icon-check')).to.exist; + }); + + it('disabled options', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options + }; + } + }, true); + + const el = vm.$el; + const expandHandler = sinon.spy(); + vm.$refs.panel.$on('expand-change', expandHandler); + + expect(getOptions(el, 0).length).to.equal(2); + expect(getValidOptions(el, 0).length).to.equal(1); + + const secondOption = getOptions(el, 0)[1]; + expect(secondOption.className).to.includes('is-disabled'); + secondOption.click(); + + await waitImmediate(); + expect(expandHandler.called).to.be.false; + expect(getMenus(el).length).to.equal(1); + }); + + it('expand by hover', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + options, + props: { + expandTrigger: 'hover' + } + }; + } + }, true); + + const el = vm.$el; + triggerEvent(getOptions(el, 0)[1], 'mouseenter'); + await waitImmediate(); + expect(getMenus(el).length).to.equal(1); + triggerEvent(getOptions(el, 0)[0], 'mouseenter'); + await waitImmediate(); + expect(getMenus(el).length).to.equal(2); + triggerEvent(getOptions(el, 1)[0], 'mouseenter'); + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + }); + + it('emit value only', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: 'xihu', + options, + props: { + emitPath: false + } + }; + } + }, true); + + const el = vm.$el; + + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + expect(getOptions(el, 2)[0].querySelector('.el-icon-check')).to.exist; + + getOptions(el, 1)[1].click(); + await waitImmediate(); + getOptions(el, 2)[0].click(); + await waitImmediate(); + expect(vm.value).to.equal('jiangbei'); + }); + + it('multiple mode', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options: options, + props: { + multiple: true + } + }; + } + }, true); + + const el = vm.$el; + const checkbox = getOptions(el, 0)[0].querySelector('.el-checkbox'); + expect(checkbox).to.exist; + expect(checkbox.querySelector('.el-checkbox__input').className).to.not.includes('is-checked'); + checkbox.querySelector('input').click(); + + await waitImmediate(); + expect(checkbox.querySelector('.el-checkbox__input').className).to.includes('is-checked'); + expect(vm.value.length).to.equal(3); + }); + + it('multiple mode with disabled default value', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [['zhejiang', 'ningbo', 'jiangdong']], + options: options, + props: { + multiple: true + } + }; + } + }, true); + + const el = vm.$el; + const checkbox = getOptions(el, 0)[0].querySelector('.el-checkbox'); + + await waitImmediate(); + expect(checkbox).to.exist; + expect(checkbox.querySelector('.el-checkbox__input').className).to.includes('is-indeterminate'); + checkbox.querySelector('input').click(); + + await waitImmediate(); + expect(checkbox.querySelector('.el-checkbox__input').className).to.includes('is-checked'); + expect(vm.value.length).to.equal(4); + + getOptions(el, 1)[1].click(); + await waitImmediate(); + getOptions(el, 2)[1].querySelector('input').click(); + await waitImmediate(); + expect(vm.value.length).to.equal(4); + }); + + it('check strictly in single mode', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: ['zhejiang'], + options: options, + props: { + checkStrictly: true + } + }; + } + }, true); + + const el = vm.$el; + const radio = getOptions(el, 0)[0].querySelector('.el-radio'); + + await waitImmediate(); + expect(radio).to.exist; + expect(radio.className).to.includes('is-checked'); + + getOptions(el, 0)[0].click(); + await waitImmediate(); + getOptions(el, 1)[0].querySelector('input').click(); + await waitImmediate(); + expect(vm.value).to.deep.equal(['zhejiang', 'hangzhou']); + expect(getOptions(el, 0)[1].querySelector('.el-radio').className).to.includes('is-disabled'); + }); + + it('check strictly in multiple mode', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [['zhejiang']], + options: options, + props: { + multiple: true, + checkStrictly: true, + emitPath: false + } + }; + } + }, true); + + const el = vm.$el; + const checkbox = getOptions(el, 0)[0].querySelector('.el-checkbox'); + + await waitImmediate(); + expect(checkbox).to.exist; + expect(checkbox.className).to.includes('is-checked'); + + getOptions(el, 0)[0].click(); + await waitImmediate(); + expect(getOptions(el, 1)[0].querySelector('.el-checkbox').className).to.not.includes('is-checked'); + getOptions(el, 1)[0].querySelector('input').click(); + await waitImmediate(); + expect(vm.value).to.deep.equal(['zhejiang', 'hangzhou']); + expect(getOptions(el, 0)[1].querySelector('.el-checkbox').className).to.includes('is-disabled'); + }); + + it('custom props', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options: options2, + props: { + value: 'id', + label: 'name', + children: 'areas', + disabled: 'invalid' + } + }; + } + }, true); + + const el = vm.$el; + + expect(getMenus(el).length).to.equal(1); + expect(getOptions(el, 0).length).to.equal(2); + expect(getValidOptions(el, 0).length).to.equal(1); + + const firstOption = getOptions(el, 0)[0]; + expect(getLabel(firstOption)).to.equal('Zhejiang'); + firstOption.click(); + await waitImmediate(); + expect(getMenus(el).length).to.equal(2); + + getOptions(el, 1)[0].click(); + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + + getOptions(el, 2)[0].click(); + await waitImmediate(); + expect(vm.value).to.deep.equal(selectedValue); + }); + + it('value key is same as label key', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options, + props: { + label: 'value' + } + }; + } + }, true); + + const el = vm.$el; + + expect(getMenus(el).length).to.equal(1); + expect(getOptions(el, 0).length).to.equal(2); + expect(getValidOptions(el, 0).length).to.equal(1); + + const firstOption = getOptions(el, 0)[0]; + expect(getLabel(firstOption)).to.equal('zhejiang'); + firstOption.click(); + await waitImmediate(); + expect(getMenus(el).length).to.equal(2); + + getOptions(el, 1)[0].click(); + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + + getOptions(el, 2)[0].click(); + await waitImmediate(); + expect(vm.value).to.deep.equal(selectedValue); + }); + + it('dynamic loading', async() => { + vm = createVue({ + template: ` + + `, + data() { + let id = 0; + return { + value: [], + props: { + lazy: true, + lazyLoad(node, resolve) { + const { level } = node; + setTimeout(() => { + const nodes = Array.from({ length: level + 1 }) + .map(() => ({ + value: ++id, + label: `选项${id}`, + leaf: level >= 2 + })); + resolve(nodes); + }, 1000); + } + } + }; + } + }, true); + + const el = vm.$el; + await wait(1000); + const firstOption = getOptions(el, 0)[0]; + firstOption.click(); + await waitImmediate(); + expect(firstOption.querySelector('i').className).to.includes('el-icon-loading'); + await wait(1000); + expect(firstOption.querySelector('i').className).to.includes('el-icon-arrow-right'); + expect(getMenus(el).length).to.equal(2); + getOptions(el, 1)[0].click(); + await wait(1000); + getOptions(el, 2)[0].click(); + await waitImmediate(); + expect(vm.value.length).to.equal(3); + }); + + it('click leaf hidden children', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options: options3 + }; + } + }, true); + + const el = vm.$el; + const elOptions = getOptions(el, 0); + const firstOption = elOptions[0]; + const twoOption = elOptions[1]; + firstOption.click(); + await waitImmediate(); + expect(getMenus(el).length).to.equal(2); + twoOption.click(); + await waitImmediate(); + expect(getMenus(el).length).to.equal(1); + }); +}); + diff --git a/test/unit/specs/cascader.spec.js b/test/unit/specs/cascader.spec.js new file mode 100644 index 0000000..d0d4b7d --- /dev/null +++ b/test/unit/specs/cascader.spec.js @@ -0,0 +1,416 @@ +import { + createTest, + createVue, + destroyVM, + waitImmediate, + wait, + triggerEvent +} from '../util'; +import Cascader from 'packages/cascader'; + +const options = [{ + value: 'zhejiang', + label: 'Zhejiang', + children: [{ + value: 'hangzhou', + label: 'Hangzhou', + children: [{ + value: 'xihu', + label: 'West Lake' + }, { + value: 'binjiang', + label: 'Bin Jiang' + }] + }, { + value: 'ningbo', + label: 'NingBo', + children: [{ + value: 'jiangbei', + label: 'Jiang Bei' + }, { + value: 'jiangdong', + label: 'Jiang Dong', + disabled: true + }] + }] +}, { + value: 'jiangsu', + label: 'Jiangsu', + disabled: true, + children: [{ + value: 'nanjing', + label: 'Nanjing', + children: [{ + value: 'zhonghuamen', + label: 'Zhong Hua Men' + }] + }] +}]; + +const getMenus = el => el.querySelectorAll('.el-cascader-menu'); +const getOptions = (el, menuIndex) => getMenus(el)[menuIndex].querySelectorAll('.el-cascader-node'); +const selectedValue = ['zhejiang', 'hangzhou', 'xihu']; +const getCloseButton = el => el.querySelectorAll('i.el-tag__close'); + +describe('Cascader', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Cascader, true); + expect(vm.$el).to.exist; + }); + + it('toggle dropdown visible', async() => { + vm = createTest(Cascader, true); + expect(vm.$refs.popper.style.display).to.equal('none'); + vm.$el.click(); + await waitImmediate(); + expect(vm.$refs.popper.style.display).to.includes(''); + vm.$el.click(); + await wait(500); + expect(vm.$refs.popper.style.display).to.includes('none'); + }); + + it('expand and check', async() => { + vm = createTest({ + template: ` + + `, + data() { + return { + value: [], + options + }; + } + }, true); + + const { body } = document; + const expandHandler = sinon.spy(); + const changeHandler = sinon.spy(); + + vm.$refs.cascader.$on('expand-change', expandHandler); + vm.$refs.cascader.$on('change', changeHandler); + + getOptions(body, 0)[0].click(); + await waitImmediate(); + expect(expandHandler.calledOnceWith(['zhejiang'])).to.be.true; + getOptions(body, 1)[0].click(); + await waitImmediate(); + const checkedOption = getOptions(body, 2)[0]; + checkedOption.click(); + await waitImmediate(); + expect(changeHandler.calledOnceWith(selectedValue)).to.be.true; + expect(vm.value).to.deep.equal(selectedValue); + expect(checkedOption.querySelector('i.el-icon-check')).to.exist; + expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake'); + }); + + it('disabled', async() => { + vm = createTest(Cascader, { + disabled: true + }, true); + expect(vm.$el.className).to.includes('is-disabled'); + vm.$el.click(); + await waitImmediate(); + expect(vm.$refs.popper.style.display).to.includes('none'); + }); + + it('with default value', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: selectedValue, + options + }; + } + }, true); + + const el = vm.$el; + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check'); + expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake'); + }); + + it('async set selected value', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options + }; + } + }, true); + + const el = vm.$el; + vm.value = selectedValue; + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check'); + expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake'); + }); + + it('default value with async options', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: selectedValue, + options: [] + }; + } + }, true); + + const el = vm.$el; + vm.options = options; + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check'); + expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake'); + }); + + it('clearable', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: selectedValue, + options + }; + } + }, true); + + triggerEvent(vm.$el, 'mouseenter'); + await waitImmediate(); + const closeBtn = vm.$el.querySelector('i.el-input__icon'); + expect(closeBtn).to.exist; + closeBtn.click(); + await waitImmediate(); + expect(vm.value).to.deep.equal([]); + }); + + it('show last level label', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: selectedValue, + options + }; + } + }, true); + + const el = vm.$el; + await waitImmediate(); + expect(getMenus(el).length).to.equal(3); + expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check'); + expect(vm.$el.querySelector('input').value).to.equal('West Lake'); + }); + + it('multiple mode', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options, + disabled: false, + props: { + multiple: true + } + }; + } + }, true); + + getOptions(document.body, 0)[0].querySelector('.el-checkbox input').click(); + await waitImmediate(); + expect(vm.value.length).to.equal(3); + expect(getCloseButton(vm.$el).length).to.equal(3); + + const tags = vm.$el.querySelectorAll('.el-tag'); + const closeBtn = tags[0].querySelector('.el-tag__close'); + expect(tags.length).to.equal(3); + expect(closeBtn).to.exist; + closeBtn.click(); + await waitImmediate(); + expect(vm.value.length).to.equal(2); + expect(vm.$el.querySelectorAll('.el-tag').length).to.equal(2); + + vm.disabled = true; + await waitImmediate(); + expect(getCloseButton(vm.$el).length).to.equal(0); + }); + + it('clearable in multiple mode', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options, + props: { + multiple: true, + emitPath: false + } + }; + } + }, true); + vm.value = ['xihu', 'binjiang', 'jiangbei', 'jiangdong']; + await waitImmediate(); + expect(getOptions(document.body, 0)[0].querySelector('.el-checkbox.is-checked')).to.exist; + triggerEvent(vm.$el, 'mouseenter'); + await waitImmediate(); + const closeBtn = vm.$el.querySelector('i.el-input__icon'); + expect(closeBtn).to.exist; + closeBtn.click(); + await waitImmediate(); + expect(vm.value.length).to.equal(1); + }); + + it('collapse tags', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: ['xihu', 'binjiang', 'jiangbei', 'jiangdong'], + options, + props: { + multiple: true, + emitPath: false + } + }; + } + }, true); + await waitImmediate(); + const tags = vm.$el.querySelectorAll('.el-tag'); + expect(tags.length).to.equal(2); + expect(tags[0].querySelector('.el-tag__close')).to.exist; + expect(tags[1].querySelector('.el-tag__close')).to.be.null; + tags[0].querySelector('.el-tag__close').click(); + expect(tags[1].textContent).to.equal('+ 3'); + await waitImmediate(); + expect(vm.value.length).to.equal(3); + vm.$el.querySelector('.el-tag .el-tag__close').click(); + await waitImmediate(); + vm.$el.querySelector('.el-tag .el-tag__close').click(); + await waitImmediate(); + expect(vm.$el.querySelector('.el-tag')).to.exist; + // disabled tag can not be closed + expect(vm.$el.querySelector('.el-tag .el-tag__close')).to.be.null; + }); + + it('filterable', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options + }; + } + }, true); + const el = vm.$el; + const { body } = document; + const input = el.querySelector('input'); + el.click(); + await waitImmediate(); + input.value = 'Zhejiang'; + triggerEvent(input, 'input'); + await wait(300); + expect(body.querySelector('.el-cascader__suggestion-list')).to.exist; + expect(body.querySelectorAll('.el-cascader__suggestion-item').length).to.equal(3); + body.querySelectorAll('.el-cascader__suggestion-item')[0].click(); + await waitImmediate(); + expect(vm.value).to.deep.equal(selectedValue); + }); + + it('filter method', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: [], + options + }; + }, + methods: { + filterMethod(node, keyword) { + const { text, path } = node; + return text.includes(keyword) || path.includes(keyword); + } + } + }, true); + const el = vm.$el; + const { body } = document; + const input = el.querySelector('input'); + el.click(); + await waitImmediate(); + input.value = 'Zhejiang'; + triggerEvent(input, 'input'); + await wait(300); + expect(body.querySelectorAll('.el-cascader__suggestion-item').length).to.equal(3); + input.value = 'xihu'; + triggerEvent(input, 'input'); + await wait(300); + expect(body.querySelector('.el-cascader__suggestion-item').textContent).to.equal('Zhejiang / Hangzhou / West Lake'); + }); +}); diff --git a/test/unit/specs/checkbox.spec.js b/test/unit/specs/checkbox.spec.js new file mode 100644 index 0000000..eefd49b --- /dev/null +++ b/test/unit/specs/checkbox.spec.js @@ -0,0 +1,507 @@ +import { createVue, destroyVM } from '../util'; + +describe('Checkbox', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + checked: false + }; + } + }, true); + let checkboxElm = vm.$el; + expect(checkboxElm.classList.contains('el-checkbox')).to.be.true; + checkboxElm.click(); + vm.$nextTick(_ => { + expect(checkboxElm.querySelector('.is-checked')).to.be.ok; + done(); + }); + }); + it('disabled', () => { + vm = createVue({ + template: ` + + + `, + data() { + return { + checked: false + }; + } + }, true); + let checkboxElm = vm.$el; + expect(checkboxElm.querySelector('.is-disabled')).to.be.ok; + }); + it('change event', done => { + vm = createVue({ + template: ` + + + `, + methods: { + onChange(val) { + this.data = val; + } + }, + data() { + return { + data: '', + checked: false + }; + } + }, true); + let checkboxElm = vm.$el; + checkboxElm.click(); + setTimeout(_ => { + expect(vm.data).to.true; + vm.checked = false; + setTimeout(_ => { + expect(vm.data).to.true; + done(); + }, 10); + }, 10); + }); + it('checkbox group', done => { + vm = createVue({ + template: ` + + + + + + + `, + data() { + return { + checkList: [] + }; + } + }, true); + expect(vm.checkList.length === 0).to.be.true; + vm.$refs.a.$el.click(); + vm.$nextTick(_ => { + expect(vm.checkList.indexOf('a') !== -1).to.be.true; + done(); + }); + }); + + it('checkbox group change event', done => { + vm = createVue({ + template: ` + + + + + `, + methods: { + onChange(val) { + this.data = val; + } + }, + data() { + return { + data: '', + checkList: [] + }; + } + }, true); + vm.$refs.a.$el.click(); + setTimeout(_ => { + expect(vm.data).to.deep.equal(['a']); + vm.checkList = ['b']; + done(); + }, 10); + }); + + it('checkbox group minimum and maximum', done => { + vm = createVue({ + template: ` + + + + + + + `, + data() { + return { + checkList: ['a'], + lastEvent: null + }; + } + }, true); + expect(vm.checkList.length === 1).to.be.true; + expect(vm.$refs.a.isDisabled).to.be.true; + vm.$refs.a.$el.click(); + vm.$nextTick(() => { + expect(vm.checkList.indexOf('a') !== -1).to.be.true; + vm.$refs.b.$el.click(); + vm.$nextTick(() => { + expect(vm.checkList.indexOf('a') !== -1).to.be.true; + expect(vm.checkList.indexOf('b') !== -1).to.be.true; + vm.$refs.c.$el.click(); + vm.$nextTick(() => { + expect(vm.checkList.indexOf('c') !== -1).to.be.false; + expect(vm.checkList.indexOf('d') !== -1).to.be.false; + expect(vm.$refs.c.isDisabled).to.be.true; + expect(vm.$refs.d.isDisabled).to.be.true; + done(); + }); + }); + }); + }); + + it('nested group', done => { + vm = createVue({ + template: ` + + + + + + + + + `, + data() { + return { + checkList: [] + }; + } + }, true); + expect(vm.checkList.length === 0).to.be.true; + vm.$refs.a.$el.click(); + vm.$nextTick(_ => { + expect(vm.checkList.indexOf('a') !== -1).to.be.true; + done(); + }); + }); + + it('true false label', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + checked: 'a' + }; + } + }, true); + vm.$el.click(); + vm.$nextTick(_ => { + expect(vm.checked === 3).to.be.true; + done(); + }); + }); + it('checked', () => { + vm = createVue({ + template: ` +
+ + + + +
+ `, + data() { + return { + checked: false, + checklist: [] + }; + } + }, true); + expect(vm.checked).to.be.true; + expect(vm.checklist.indexOf('a') !== -1).to.be.true; + }); + + describe('checkbox-button', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + checked: false + }; + } + }, true); + let checkboxElm = vm.$el; + expect(checkboxElm.classList.contains('el-checkbox-button')).to.be.true; + checkboxElm.click(); + vm.$nextTick(_ => { + expect(checkboxElm.classList.contains('is-checked')).to.be.ok; + done(); + }); + }); + it('disabled', () => { + vm = createVue({ + template: ` + + + `, + data() { + return { + checked: false + }; + } + }, true); + let checkboxElm = vm.$el; + expect(checkboxElm.classList.contains('is-disabled')).to.be.ok; + }); + + it('change event', done => { + vm = createVue({ + template: ` + + + `, + methods: { + onChange(val) { + this.data = val; + } + }, + data() { + return { + data: '', + checked: false + }; + } + }, true); + let checkboxElm = vm.$el; + checkboxElm.click(); + setTimeout(_ => { + expect(vm.data).to.true; + vm.checked = false; + setTimeout(_ => { + expect(vm.data).to.true; + done(); + }, 10); + }, 10); + }); + + it('checkbox group', done => { + vm = createVue({ + template: ` + + + + + + + `, + data() { + return { + checkList: [] + }; + } + }, true); + expect(vm.checkList.length === 0).to.be.true; + vm.$refs.a.$el.click(); + vm.$nextTick(_ => { + expect(vm.checkList.indexOf('a') !== -1).to.be.true; + vm.$refs.b.$el.click(); + vm.$nextTick(_ => { + expect(vm.checkList.indexOf('a') !== -1).to.be.true; + expect(vm.checkList.indexOf('b') !== -1).to.be.true; + done(); + }); + }); + }); + + it('checkbox-button group change event', done => { + vm = createVue({ + template: ` + + + + + + + `, + methods: { + onChange(val) { + this.data = val; + } + }, + data() { + return { + data: '', + checkList: [] + }; + } + }, true); + vm.$refs.a.$el.click(); + setTimeout(_ => { + expect(vm.data).to.deep.equal(['a']); + vm.checkList = ['b']; + setTimeout(_ => { + expect(vm.data).to.deep.equal(['a']); + done(); + }, 10); + }, 10); + }); + + it('checkbox group props', () => { + vm = createVue({ + template: ` + + + + + + + `, + data() { + return { + checkList: ['a', 'd'] + }; + } + }, true); + expect(vm.checkList.length === 2).to.be.true; + expect(vm.$refs.a.$el.classList.contains('is-checked')).to.be.true; + expect(vm.$refs.a.$el.classList.contains('el-checkbox-button--large')).to.be.true; + expect(vm.$refs.a.$el.querySelector('.el-checkbox-button__inner').style.backgroundColor).to.be.eql('rgb(255, 0, 0)'); + expect(vm.$refs.a.$el.querySelector('.el-checkbox-button__inner').style.boxShadow).to.be.eql('rgb(255, 0, 0) -1px 0px 0px 0px'); + expect(vm.$refs.a.$el.querySelector('.el-checkbox-button__inner').style.borderColor).to.be.eql('rgb(255, 0, 0)'); + expect(vm.$refs.a.$el.querySelector('.el-checkbox-button__inner').style.color).to.be.eql('rgb(0, 0, 0)'); + expect(vm.$refs.b.$el.classList.contains('is-checked')).to.be.false; + expect(vm.$refs.c.$el.classList.contains('is-checked')).to.be.false; + expect(vm.$refs.d.$el.classList.contains('is-checked')).to.be.true; + }); + + it('checkbox group minimum and maximum', done => { + vm = createVue({ + template: ` + + + + + + + `, + data() { + return { + checkList: ['a'], + lastEvent: null + }; + } + }, true); + expect(vm.checkList.length === 1).to.be.true; + vm.$refs.a.$el.click(); + vm.$nextTick(() => { + expect(vm.checkList.indexOf('a') !== -1).to.be.true; + vm.$refs.b.$el.click(); + vm.$nextTick(() => { + expect(vm.checkList.indexOf('a') !== -1).to.be.true; + expect(vm.checkList.indexOf('b') !== -1).to.be.true; + vm.$refs.c.$el.click(); + vm.$nextTick(() => { + expect(vm.checkList.indexOf('c') !== -1).to.be.false; + expect(vm.checkList.indexOf('d') !== -1).to.be.false; + done(); + }); + }); + }); + }); + + it('nested group', done => { + vm = createVue({ + template: ` + + + + + + + + + `, + data() { + return { + checkList: [] + }; + } + }, true); + expect(vm.checkList.length === 0).to.be.true; + vm.$refs.a.$el.click(); + vm.$nextTick(_ => { + expect(vm.checkList.indexOf('a') !== -1).to.be.true; + done(); + }); + }); + + it('true false label', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + checked: 'a' + }; + } + }, true); + vm.$el.click(); + vm.$nextTick(_ => { + expect(vm.checked === 3).to.be.true; + done(); + }); + }); + it('checked', () => { + vm = createVue({ + template: ` +
+ + + + +
+ `, + data() { + return { + checked: false, + checklist: [] + }; + } + }, true); + expect(vm.checked).to.be.true; + expect(vm.checklist.indexOf('a') !== -1).to.be.true; + }); + + }); +}); diff --git a/test/unit/specs/col.spec.js b/test/unit/specs/col.spec.js new file mode 100644 index 0000000..4809dde --- /dev/null +++ b/test/unit/specs/col.spec.js @@ -0,0 +1,78 @@ +import { createVue, destroyVM } from '../util'; + +describe('Col', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createVue({ + template: ` + + + ` + }, true); + let colElm = vm.$el; + expect(colElm.classList.contains('el-col')).to.be.true; + }); + it('span', () => { + vm = createVue({ + template: ` + + + ` + }, true); + let colElm = vm.$el; + expect(colElm.classList.contains('el-col-12')).to.be.true; + }); + it('pull', () => { + vm = createVue({ + template: ` + + + ` + }, true); + let colElm = vm.$el; + expect(colElm.classList.contains('el-col-pull-3')).to.be.true; + }); + it('push', () => { + vm = createVue({ + template: ` + + + ` + }, true); + let colElm = vm.$el; + expect(colElm.classList.contains('el-col-push-3')).to.be.true; + }); + it('gutter', () => { + vm = createVue({ + template: ` + + + + + ` + }, true); + let colElm = vm.$refs.col.$el; + expect(colElm.style.paddingLeft === '10px').to.be.true; + expect(colElm.style.paddingRight === '10px').to.be.true; + }); + it('responsive', () => { + vm = createVue({ + template: ` + + + + + ` + }, true); + let colElm = vm.$refs.col.$el; + expect(colElm.classList.contains('el-col-sm-4')).to.be.true; + expect(colElm.classList.contains('el-col-sm-offset-2')).to.be.true; + expect(colElm.classList.contains('el-col-lg-6')).to.be.true; + expect(colElm.classList.contains('el-col-lg-offset-3')).to.be.true; + expect(colElm.classList.contains('el-col-md-8')).to.be.true; + }); +}); diff --git a/test/unit/specs/collapse.spec.js b/test/unit/specs/collapse.spec.js new file mode 100644 index 0000000..40cdb22 --- /dev/null +++ b/test/unit/specs/collapse.spec.js @@ -0,0 +1,130 @@ +import { createVue, destroyVM } from '../util'; + +describe('Collapse', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', done => { + vm = createVue({ + data() { + return { + activeNames: ['1'] + }; + }, + template: ` + + +
与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;
+
在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。
+
+ +
控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;
+
页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。
+
+ +
简化流程:设计简洁直观的操作流程;
+
清晰明确:语言表达清晰且表意明确,让用户快速理解进而作出决策;
+
帮助用户识别:界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。
+
+ +
用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;
+
结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。
+
+
+ ` + }, true); + + expect(vm.$refs.item1.isActive).to.be.true; + vm.$refs.item3.$el.querySelector('.el-collapse-item__header').click(); + vm.$nextTick(_ => { + expect(vm.$refs.item1.isActive).to.be.true; + expect(vm.$refs.item3.isActive).to.be.true; + + vm.$refs.item1.$el.querySelector('.el-collapse-item__header').click(); + + vm.$nextTick(_ => { + expect(vm.$refs.item1.isActive).to.be.false; + done(); + }); + }); + }); + + it('accordion', done => { + vm = createVue({ + data() { + return { + activeNames: ['1'] + }; + }, + template: ` + + +
与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;
+
在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。
+
+ +
控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;
+
页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。
+
+ +
简化流程:设计简洁直观的操作流程;
+
清晰明确:语言表达清晰且表意明确,让用户快速理解进而作出决策;
+
帮助用户识别:界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。
+
+ +
用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;
+
结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。
+
+
+ ` + }, true); + + expect(vm.$refs.item1.isActive).to.be.true; + vm.$refs.item3.$el.querySelector('.el-collapse-item__header').click(); + vm.$nextTick(_ => { + expect(vm.$refs.item1.isActive).to.be.false; + expect(vm.$refs.item3.isActive).to.be.true; + done(); + }); + }); + + it('event:change', done => { + vm = createVue({ + data() { + return { + activeNames: ['1'] + }; + }, + template: ` + + +
与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;
+
在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。
+
+ +
控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;
+
页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。
+
+ +
简化流程:设计简洁直观的操作流程;
+
清晰明确:语言表达清晰且表意明确,让用户快速理解进而作出决策;
+
帮助用户识别:界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。
+
+ +
用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;
+
结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。
+
+
+ ` + }, true); + const spy = sinon.spy(); + vm.$refs.collapse.$on('change', spy); + vm.$refs.item3.$el.querySelector('.el-collapse-item__header').click(); + vm.$nextTick(_ => { + expect(spy.withArgs().calledOnce).to.be.true; + done(); + }); + }); +}); diff --git a/test/unit/specs/color-picker.spec.js b/test/unit/specs/color-picker.spec.js new file mode 100644 index 0000000..34c4d53 --- /dev/null +++ b/test/unit/specs/color-picker.spec.js @@ -0,0 +1,362 @@ +import { createTest, createVue, destroyVM } from '../util'; +import ColorPicker from 'packages/color-picker'; + +describe('ColorPicker', () => { + let vm; + + afterEach(() => { + vm.$destroy(true); + destroyVM(vm); + const dropdown = document.querySelector('.el-color-dropdown'); + if (dropdown && dropdown.parentNode) dropdown.parentNode.removeChild(dropdown); + }); + + it('should work', () => { + vm = createTest(ColorPicker, true); + expect(vm.$el).to.exist; + }); + + it('should show alpha slider when show-alpha=true', (done) => { + const vm = createVue({ + template: ` + + `, + + data() { + return { + color: null + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const alphaSlider = document.querySelector('.el-color-alpha-slider'); + expect(alphaSlider).to.exist; + done(); + }, ANIMATION_TIME); + }); + + it('should show color picker when click trigger', (done) => { + vm = createTest(ColorPicker, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + vm.$nextTick(() => { + const dropdown = document.querySelector('.el-color-dropdown'); + expect(dropdown).to.exist; + done(); + }); + }); + + const ANIMATION_TIME = 300; + + it('should pick a color when confirm button click', (done) => { + const vm = createVue({ + template: ` + + `, + + data() { + return { + color: null + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const dropdown = document.querySelector('.el-color-dropdown__btn'); + dropdown.click(); + vm.$nextTick(() => { + expect(vm.color).to.equal('#FF0000'); + done(); + }); + }, ANIMATION_TIME); + }); + + it('should show correct rgb value', (done) => { + const vm = createVue({ + template: ` + + `, + + data() { + return { + color: '#20A0FF' + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const input = document.querySelector('.el-color-dropdown__value input'); + expect(input.value.trim().toUpperCase()).to.equal('#20A0FF'); + done(); + }, ANIMATION_TIME); + }); + + it('should init the right color when open', (done) => { + const vm = createVue({ + template: ` + + `, + + data() { + return { + color: '#0f0' + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const dropdown = document.querySelector('.el-color-dropdown__btn'); + dropdown.click(); + vm.$nextTick(() => { + const hueBar = document.querySelector('.el-color-hue-slider__thumb'); + const top = parseInt(hueBar.style.top, 10); + expect(top > 10).to.be.true; + done(); + }); + }, ANIMATION_TIME); + }); + + it('should clear a color when clear button click', (done) => { + const vm = createVue({ + template: ` + + `, + + data() { + return { + color: '#f00' + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const clearBtn = document.querySelector('.el-color-dropdown__link-btn'); + clearBtn.click(); + setTimeout(() => { + expect(vm.color).to.equal(null); + done(); + }, 30); + }, ANIMATION_TIME); + }); + + it('should change hue when clicking the hue bar', (done) => { + const vm = createVue({ + template: ` + + `, + + data() { + return { + color: '#f00' + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const hueBar = document.querySelector('.el-color-hue-slider'); + hueBar.__vue__.handleClick({ target: null, clientX: 0, clientY: 1000 }); + vm.$nextTick(() => { + const picker = vm.$children[0]; + expect(picker.color._hue > 0).to.true; + done(); + }); + }, ANIMATION_TIME); + }); + + it('should change hue when saturation is zero', (done) => { + const vm = createVue({ + template: ` + + `, + + data() { + return { + color: '#FFFFFF' + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const hueBar = document.querySelector('.el-color-hue-slider'); + hueBar.__vue__.handleClick({ target: null, clientX: 0, clientY: 1000 }); + vm.$nextTick(() => { + const thumb = document.querySelector('.el-color-hue-slider__thumb'); + expect(parseInt(thumb.style.top, 10) > 0).to.true; + done(); + }); + }, ANIMATION_TIME); + }); + + it('should change alpha when clicking the alpha bar', (done) => { + const vm = createVue({ + template: ` + + `, + + data() { + return { + color: '#f00' + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const alphaBar = document.querySelector('.el-color-alpha-slider'); + alphaBar.__vue__.handleClick({ target: null, clientX: 50, clientY: 0 }); + vm.$nextTick(() => { + const picker = vm.$children[0]; + expect(picker.color._alpha < 100).to.true; + done(); + }); + }, ANIMATION_TIME); + }); + + it('should change saturation and value when clicking the sv-panel', (done) => { + const vm = createVue({ + template: ` + + `, + + data() { + return { + color: 'hsv(0, 50%, 50%)' + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const svPanel = document.querySelector('.el-color-svpanel'); + svPanel.__vue__.handleDrag({ clientX: 0, clientY: 0 }); + vm.$nextTick(() => { + const picker = vm.$children[0]; + expect(picker.color._saturation !== 50).to.true; + expect(picker.color._value !== 50).to.true; + done(); + }); + }, ANIMATION_TIME); + }); + + it('should change color to the selected color', done => { + const vm = createVue({ + template: ` + + `, + data() { + return { + color: 'hsva(180, 65, 20, 0.5)', + colors: [ + 'rgba(19, 206, 102, 0.18)', + 'rgb(25, 159, 147)', + 'hsv(250, 54, 98)', + 'hsva(180, 65, 20, 0.5)', + 'hsl(170, 32%, 87%)', + 'hsla(45, 62%, 47%, 0.13)', + '#7486de', + '#45aa9477', + '#892345' + ] + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + expect(document.querySelectorAll('.el-color-predefine__color-selector').length === 9).to.be.true; + const selector = document.querySelector('.el-color-predefine__color-selector:nth-child(4)'); + selector.click(); + vm.$nextTick(() => { + const picker = vm.$children[0]; + expect(picker.color._hue === 180).to.be.true; + expect(picker.color._saturation === 65).to.be.true; + expect(picker.color._value === 20).to.be.true; + expect(picker.color._alpha === 50).to.be.true; + + const selector2 = document.querySelector('.el-color-predefine__color-selector:nth-child(3)'); + selector2.click(); + + vm.$nextTick(() => { + expect(picker.color._hue === 250).to.be.true; + expect(picker.color._saturation === 54).to.be.true; + expect(picker.color._value === 98).to.be.true; + expect(picker.color._alpha === 100).to.be.true; + done(); + }); + }); + }); + }); + + it('should change selected state of predefined color', done => { + const vm = createVue({ + template: ` + + `, + data() { + return { + color: 'hsva(180, 65, 20, 0.5)', + colors: [ + 'rgba(19, 206, 102, 0.18)', + 'rgb(25, 159, 147)', + 'hsv(250, 54, 98)', + 'hsva(180, 65, 20, 0.5)', + 'hsl(170, 32%, 87%)', + 'hsla(45, 62%, 47%, 0.13)', + '#7486de', + '#45aa9477', + '#892345' + ] + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const selector = document.querySelector('.el-color-predefine__color-selector:nth-child(4)'); + selector.click(); + vm.$nextTick(() => { + expect(selector.classList.contains('selected')).to.be.true; + + const hueBar = document.querySelector('.el-color-hue-slider'); + hueBar.__vue__.handleClick({ target: null, clientX: 0, clientY: 1000 }); + + vm.$nextTick(() => { + expect(selector.classList.contains('selected')).to.be.false; + done(); + }); + }); + }); + }); +}); diff --git a/test/unit/specs/container.spec.js b/test/unit/specs/container.spec.js new file mode 100644 index 0000000..bd41b6f --- /dev/null +++ b/test/unit/specs/container.spec.js @@ -0,0 +1,128 @@ +import { createTest, createVue, destroyVM } from '../util'; +import Container from 'packages/container'; +import Header from 'packages/header'; +import Main from 'packages/main'; +import Aside from 'packages/aside'; +import Footer from 'packages/footer'; + +describe('Container', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Container, true); + expect(vm.$el).to.exist; + }); + + it('vertical', () => { + vm = createVue({ + template: ` + + + + + ` + }, true); + expect(vm.$children[0].$el.classList.contains('is-vertical')).to.true; + }); + + it('direction', done => { + vm = createVue({ + template: ` + + + + + `, + data() { + return { + direction: 'horizontal' + }; + } + }, true); + expect(vm.$children[0].$el.classList.contains('is-vertical')).not.to.true; + vm.direction = 'vertical'; + vm.$nextTick(() => { + expect(vm.$children[0].$el.classList.contains('is-vertical')).to.true; + done(); + }); + }); +}); + +describe('Header', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Header, true); + expect(vm.$el).to.exist; + }); + + it('height', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$children[0].$el.style.height).to.equal('100px'); + }); +}); + +describe('Aside', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Aside, true); + expect(vm.$el).to.exist; + }); + + it('width', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$children[0].$el.style.width).to.equal('200px'); + }); +}); + +describe('Main', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Main, true); + expect(vm.$el).to.exist; + }); +}); + +describe('Footer', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Footer, true); + expect(vm.$el).to.exist; + }); + + it('height', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$children[0].$el.style.height).to.equal('100px'); + }); +}); + diff --git a/test/unit/specs/date-picker.spec.js b/test/unit/specs/date-picker.spec.js new file mode 100644 index 0000000..070db48 --- /dev/null +++ b/test/unit/specs/date-picker.spec.js @@ -0,0 +1,2855 @@ +import { + createTest, + createVue, + destroyVM, + triggerEvent, + wait +} from '../util'; +import DatePicker from 'packages/date-picker'; + +const DELAY = 50; + +const LEFT = 37; +const ENTER = 13; +const TAB = 9; + +const keyDown = (el, keyCode) => { + const evt = document.createEvent('Events'); + evt.initEvent('keydown', true, true); + evt.keyCode = keyCode; + el.dispatchEvent(evt); +}; + +describe('DatePicker', () => { + let vm; + afterEach(() => { destroyVM(vm); }); + + it('create', () => { + vm = createTest(DatePicker, { + readonly: true, + placeholder: '23333', + format: 'HH-mm-ss' + }, true); + const input = vm.$el.querySelector('input'); + + expect(input.getAttribute('placeholder')).to.equal('23333'); + expect(input.getAttribute('readonly')).to.equal('readonly'); + }); + + it('select date', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: '' + }; + } + }, true); + const input = vm.$el.querySelector('input'); + const date = new Date(); + + input.blur(); + input.focus(); + + setTimeout(_ => { + const $el = vm.$refs.compo.picker.$el; + const spans = $el.querySelectorAll('.el-date-picker__header-label'); + const arrowLeftElm = $el.querySelector('.el-date-picker__prev-btn.el-icon-arrow-left'); + const arrowRightElm = $el.querySelector('.el-date-picker__next-btn.el-icon-arrow-right'); + + expect(spans[0].textContent).to.include(date.getFullYear()); + expect(spans[1].textContent).to.include(date.getMonth() + 1); + $el.querySelector('.el-date-picker__prev-btn.el-icon-d-arrow-left').click(); + let count = 20; + while (--count) { + arrowLeftElm.click(); + } + + count = 20; + while (--count) { + arrowRightElm.click(); + } + setTimeout(_ => { + expect(spans[0].textContent).to.include(date.getFullYear() - 1); + expect(spans[1].textContent).to.include(date.getMonth() + 1); + $el.querySelector('td.available').click(); + vm.$nextTick(_ => { + expect(vm.value).to.exist; + }); + done(); + }, DELAY); + }, DELAY); + }); + + it('clear value', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: '' + }; + } + }, true); + const input = vm.$el.querySelector('input'); + + input.focus(); + setTimeout(_ => { + const $el = vm.$refs.compo.picker.$el; + $el.querySelector('td.available').click(); + setTimeout(_ => { + vm.$refs.compo.showClose = true; + vm.$refs.compo.handleClickIcon({ stopPropagation: () => null }); + setTimeout(_ => { + expect(vm.value).to.equal(null); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }); + + it('disabled clear value', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: '' + }; + } + }, true); + const input = vm.$el.querySelector('input'); + + input.focus(); + setTimeout(_ => { + const $el = vm.$refs.compo.picker.$el; + $el.querySelector('td.available').click(); + vm.$nextTick(_ => { + vm.$el.querySelector('.el-input__icon').click(); + setTimeout(_ => { + expect(vm.value).to.be.exist; + done(); + }, DELAY); + }); + }, DELAY); + }); + + it('reset', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: '' + }; + } + }, true); + const input = vm.$el.querySelector('input'); + + input.blur(); + input.focus(); + setTimeout(_ => { + const $el = vm.$refs.compo.picker.$el; + $el.querySelector('.el-date-picker__next-btn.el-icon-arrow-right').click(); + setTimeout(_ => { + $el.querySelector('td.available').click(); + vm.$nextTick(_ => { + vm.value = ''; + setTimeout(_ => { + expect(vm.$refs.compo.picker.date.getDate()).to.equal(new Date().getDate()); + done(); + }, DELAY); + }); + }, DELAY); + }, DELAY); + }); + + it('focus', done => { + vm = createVue({ + template: ` + + ` + }, true); + + const spy = sinon.spy(); + + vm.$refs.picker.$on('focus', spy); + vm.$refs.picker.focus(); + + vm.$nextTick(_ => { + expect(spy.calledOnce).to.be.true; + done(); + }); + }); + + it('change event', done => { + let onChangeValue; + + vm = createVue({ + template: ` + `, + + methods: { + handleChange(val) { + onChangeValue = val; + } + }, + + data() { + return { + value: '' + }; + } + }, true); + + const input = vm.$el.querySelector('input'); + + input.blur(); + input.focus(); + + setTimeout(_ => { + const picker = vm.$refs.compo.picker; + + // programatic modification of bound value does not emit cange + vm.value = new Date(2000, 9, 2); + setTimeout(_ => { + expect(onChangeValue).to.not.exist; + // user interaction does emit change + picker.$el.querySelector('td.available').click(); + setTimeout(_ => { + expect(onChangeValue.getTime()).to.equal(vm.value.getTime()); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }); + + it('change event: when clear(), without opening picker', done => { + vm = createVue({ + template: ` + `, + data() { + return { + value: new Date() + }; + } + }, true); + + const spy = sinon.spy(); + vm.$refs.compo.$on('change', spy); + + setTimeout(_ => { + vm.$refs.compo.showClose = true; + vm.$refs.compo.handleClickIcon({ stopPropagation: () => null }); + setTimeout(_ => { + expect(spy.calledOnce).to.equal(true); + expect(spy.calledWith(null)).to.equal(true); + done(); + }, DELAY); + }, DELAY); + }); + + it('nuke invalid input on close', done => { + vm = createVue({ + template: '', + data() { + return { + value: '2010-10-01' + }; + } + }, true); + + const compo = vm.$refs.compo; + const input = compo.$el.querySelector('input'); + input.blur(); + input.focus(); + + setTimeout(_ => { + compo.userInput = 'abc'; + compo.handleChange(); // simplified test + compo.handleClose(); + setTimeout(_ => { + expect(input.value).to.equal('2010-10-01'); + expect(vm.value).to.equal('2010-10-01'); + done(); + }, DELAY); + }, DELAY); + }); + + it('select datetime with defaultTime', done => { + vm = createVue({ + template: ` + + `, + data() { + return { + value: '' + }; + } + }, true); + + const input = vm.$el.querySelector('input'); + input.blur(); + input.focus(); + setTimeout(_ => { + const picker = vm.$refs.compo.picker; + picker.$el.querySelector('td.available').click(); + setTimeout(_ => { + const date = vm.$refs.compo.picker.date; + expect(date.getHours()).to.equal(12); + expect(date.getMinutes()).to.equal(0); + expect(date.getSeconds()).to.equal(0); + done(); + }, DELAY); + }, DELAY); + }); + + describe('input event', () => { + // mimic standard + +
+ `, + + data() { + return { + title: 'dialog test', + visible: true + }; + } + }, true); + const dialog = vm.$children[0]; + await waitImmediate(); + dialog.$el.querySelector('input').value = '123'; + dialog.$el.click(); + await waitImmediate(); + vm.visible = true; + await waitImmediate(); + expect(dialog.$el.querySelector('input').value).to.be.equal(''); + }); +}); diff --git a/test/unit/specs/divider.spec.js b/test/unit/specs/divider.spec.js new file mode 100644 index 0000000..cea5dc2 --- /dev/null +++ b/test/unit/specs/divider.spec.js @@ -0,0 +1,37 @@ +import { createVue, destroyVM } from '../util'; + +describe('Divider', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('content', () => { + vm = createVue({ + template: ` + 我是一条完美分割线! + ` + }); + + expect(vm.$el).to.property('textContent').to.include('我是一条完美分割线!'); + }); + + it('direction', () => { + vm = createVue({ + template: ` + 我是一条完美分割线! + ` + }); + + expect(vm.$el.className).to.include('el-divider--vertical'); + }); + + it('apply class to divider', () => { + vm = createVue({ + template: ` + 我是一条完美分割线! + ` + }); + expect(vm.$el.className).to.include('my-divider'); + }); +}); diff --git a/test/unit/specs/drawer.spec.js b/test/unit/specs/drawer.spec.js new file mode 100644 index 0000000..c8d1c3c --- /dev/null +++ b/test/unit/specs/drawer.spec.js @@ -0,0 +1,350 @@ +import { createVue, destroyVM, waitImmediate, wait } from '../util'; + +const title = '我是测试 title'; +const content = 'content'; + +describe('Drawer', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', async() => { + vm = createVue( + { + template: ` + + `, + data() { + return { + title, + visible: true + }; + } + }, + true + ); + const drawer = vm.$children[0]; + await waitImmediate(); + expect(document.querySelector('.v-modal')).to.exist; + expect(vm.$el.querySelector('.el-drawer__header').textContent).to.equal( + title + ); + expect(drawer.$el.style.display).to.not.equal('none'); + }); + + it('render correct content', async() => { + vm = createVue( + { + template: ` + + 这是一段信息 + 取消 + 确定 + + `, + + data() { + return { + title: 'drawer test', + visible: true + }; + } + }, + true + ); + await waitImmediate(); + expect(vm.$el.querySelector('.el-drawer__body span').textContent).to.equal( + '这是一段信息' + ); + const footerBtns = vm.$el.querySelectorAll('.el-button'); + expect(footerBtns.length).to.equal(2); + expect(footerBtns[0].querySelector('span').textContent).to.equal('取消'); + expect(footerBtns[1].querySelector('span').textContent).to.equal('确定'); + }); + + it('should append to body, when append-to-body flag is true', async() => { + vm = createVue( + { + template: ` + + content + + `, + data() { + return { + title, + visible: true + }; + } + }, + true + ); + await waitImmediate(); + expect(vm.$el.parentNode).to.equal(document.body); + }); + + it('should open and close drawer properly', async() => { + vm = createVue({ + template: ` + + ${content} + + `, + data() { + return { + title, + visible: false + }; + } + }); + let drawer = vm.$children[0].$el; + expect(drawer.style.display).to.equal('none'); + vm.visible = true; + await waitImmediate(); + expect(drawer.style.display).not.to.equal('none'); + vm.visible = false; + await wait(400); + expect(drawer.style.display).to.equal('none'); + }); + + it('should destroy every child after drawer was closed when destroy-on-close flag is true', async() => { + vm = createVue({ + template: ` + + ${content} + + `, + data() { + return { + title, + visible: true + }; + } + }); + + await waitImmediate(); + expect(vm.$el.querySelector('.el-drawer__body span').textContent).to.equal( + content + ); + vm.$refs.drawer.closeDrawer(); + await wait(400); + expect(vm.$el.querySelector('.el-drawer__body')).not.to.exist; + }); + + it('should close dialog by clicking the close button', async() => { + vm = createVue({ + template: ` + + ${content} + + `, + data() { + return { + title, + visible: true + }; + } + }); + + await waitImmediate(); + vm.$children[0].$el.querySelector('.el-drawer__close-btn').click(); + expect(vm.visible).to.equal(false); + }); + + it('should invoke before-close', async() => { + const beforeClose = sinon.spy(); + vm = createVue({ + template: ` + + ${content} + + `, + data() { + return { + title, + visible: true, + beforeClose + }; + } + }); + + await waitImmediate(); + vm.$refs.drawer.closeDrawer(); + await waitImmediate(); + expect(beforeClose.called).to.be.true; + }); + + it('should not show close button when show-close flag is false', async() => { + vm = createVue({ + template: ` + + ${content} + + `, + data() { + return { + title, + visible: false + }; + } + }); + expect(vm.$el.querySelector('.el-drawer__close-btn')).not.to.exist; + }); + + it('should have custom classes when custom classes were given', async() => { + const classes = 'some-custom-class'; + vm = createVue({ + template: ` + + ${content} + + `, + data() { + return { + title, + visible: false + }; + } + }); + + expect(vm.$el.querySelector(`.${classes}`)).to.exist; + }); + + it('should not render header when withHeader attribute is false', () => { + vm = createVue({ + template: ` + + ${content} + + `, + data() { + return { + title, + visible: true + }; + } + }); + + expect(vm.$el.querySelector('.el-drawer__header')).to.not.exist; + }); + + describe('directions', () => { + const renderer = direction => { + return createVue({ + template: ` + + ${content} + + `, + data: { + visible: true, + title + } + }); + }; + it('should render from left to right', async() => { + vm = renderer('ltr'); + await waitImmediate(); + expect(vm.$el.querySelector('.ltr')).to.exist; + }); + + it('should render from right to left', async() => { + vm = renderer('rtl'); + await waitImmediate(); + expect(vm.$el.querySelector('.rtl')).to.exist; + }); + + it('should render from top to bottom', async() => { + vm = renderer('ttb'); + await waitImmediate(); + expect(vm.$el.querySelector('.ttb')).to.exist; + }); + + it('should render from bottom to top', async() => { + vm = renderer('btt'); + await waitImmediate(); + expect(vm.$el.querySelector('.btt')).to.exist; + }); + }); + + it('events', async() => { + const open = sinon.spy(); + const opened = sinon.spy(); + const close = sinon.spy(); + const closed = sinon.spy(); + + vm = createVue({ + template: ` + + ${content} + + `, + data() { + return { + content, + visible: false, + title + }; + }, + methods: { + close, + closed, + open, + opened + } + }); + vm.visible = true; + await wait(400); + expect(open.called).to.be.true; + expect(opened.called).to.be.true; + expect(close.called).to.be.false; + expect(closed.called).to.be.false; + vm.visible = false; + await wait(500); + expect(close.called).to.be.true; + expect(closed.called).to.be.true; + }); + + describe('size', () => { + const renderer = (size, isVertical) => + createVue({ + template: ` + + ${content} + + `, + data: { + visible: true, + title + } + }); + + it('should effect height when drawer is vertical', async() => { + const size = '50%'; + vm = renderer(size, true); + + expect(vm.$el.querySelector('.el-drawer').style.width).to.equal('50%'); + }); + + it('should effect width when drawer is horizontal', async() => { + const size = '50%'; + vm = renderer(size, false); + expect(vm.$el.querySelector('.el-drawer').style.height).to.equal('50%'); + }); + }); +}); diff --git a/test/unit/specs/dropdown.spec.js b/test/unit/specs/dropdown.spec.js new file mode 100644 index 0000000..b68f8af --- /dev/null +++ b/test/unit/specs/dropdown.spec.js @@ -0,0 +1,283 @@ +import { createVue, triggerEvent, destroyVM, triggerKeyDown } from '../util'; + +describe('Dropdown', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', done => { + vm = createVue({ + template: ` + + + 下拉菜单 + + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + ` + }, true); + let dropdown = vm.$refs.dropdown; + let dropdownElm = dropdown.$el; + let triggerElm = dropdownElm.children[0]; + + triggerEvent(triggerElm, 'mouseenter'); + setTimeout(_ => { + expect(dropdown.visible).to.be.true; + + triggerEvent(triggerElm, 'mouseleave'); + setTimeout(_ => { + expect(dropdown.visible).to.not.true; + done(); + }, 300); + }, 400); + }); + it('menu click', done => { + const myCommandObject = { name: 'CommandC' }; + vm = createVue({ + template: ` + + + 下拉菜单 + + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + `, + data() { + return { + myCommandObject + }; + } + }, true); + let dropdown = vm.$refs.dropdown; + let dropdownElm = dropdown.$el; + let triggerElm = dropdownElm.children[0]; + let callback = sinon.spy(); + + dropdown.$on('command', callback); + + triggerEvent(triggerElm, 'mouseenter'); + setTimeout(_ => { + vm.$refs.commandC.$el.click(); + setTimeout(_ => { + expect(dropdown.visible).to.not.true; + expect(callback.calledWith(myCommandObject)).to.be.true; + done(); + }, 300); + }, 300); + }); + it('trigger', done => { + vm = createVue({ + template: ` + + + 下拉菜单trigger click + + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + ` + }, true); + let dropdownElm = vm.$el; + let dropdown = vm.$refs.dropdown; + let triggerElm = dropdownElm.children[0]; + + triggerEvent(triggerElm, 'mouseenter'); + dropdown.$nextTick(_ => { + expect(dropdown.visible).to.not.true; + triggerElm.click(); + setTimeout(_ => { + expect(dropdown.visible).to.be.true; + done(); + }, 300); + }); + }); + it('split button', done => { + vm = createVue({ + template: ` + + 更多菜单 + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + ` + }, true); + + let dropdown = vm.$refs.dropdown; + let dropdownElm = dropdown.$el; + let triggerElm = dropdownElm.querySelector('.el-dropdown__caret-button'); + var callback = sinon.spy(); + + dropdown.$on('click', callback); + dropdownElm.querySelector('.el-button').click(); + + setTimeout(_ => { + expect(callback.called).to.be.true; + }, 300); + + triggerEvent(triggerElm, 'mouseenter'); + setTimeout(_ => { + expect(dropdown.visible).to.be.true; + + triggerEvent(triggerElm, 'mouseleave'); + setTimeout(_ => { + expect(dropdown.visible).to.not.true; + done(); + }, 300); + }, 300); + }); + it('hide on click', done => { + vm = createVue({ + template: ` + + + 下拉菜单 + + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + ` + }, true); + let dropdown = vm.$refs.dropdown; + let dropdownElm = dropdown.$el; + let triggerElm = dropdownElm.children[0]; + let callback = sinon.spy(); + + dropdown.$on('command', callback); + + triggerEvent(triggerElm, 'mouseenter'); + setTimeout(_ => { + vm.$refs.commandC.$el.click(); + setTimeout(_ => { + expect(dropdown.visible).to.true; + expect(callback.calledWith('c')).to.be.true; + done(); + }, 300); + }, 300); + }); + it('triggerElm keydown', done => { + vm = createVue({ + template: ` + + + 下拉菜单 + + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + ` + }, true); + let dropdown = vm.$refs.dropdown; + let dropdownElm = dropdown.$el; + let triggerElm = dropdownElm.children[0]; + triggerKeyDown(triggerElm, 13); // enter + setTimeout(() => { + expect(dropdown.visible).to.be.true; + triggerKeyDown(triggerElm, 27); // esc + setTimeout(() => { + expect(dropdown.visible).to.be.false; + done(); + }, 300); + }, 400); + }); + it('dropdown menu keydown', done => { + vm = createVue({ + template: ` + + + 下拉菜单 + + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + ` + }, true); + let dropdown = vm.$refs.dropdown; + let dropdownElm = dropdown.$el; + let triggerElm = dropdownElm.children[0]; + let dropdownMenu = dropdown.dropdownElm; + + triggerEvent(triggerElm, 'mouseenter'); + + setTimeout(() => { + expect(dropdown.visible).to.be.true; + triggerKeyDown(dropdownMenu, 40); // down + setTimeout(() => { + triggerKeyDown(dropdownMenu, 13); // enter + setTimeout(() => { + expect(dropdown.visible).to.be.false; + done(); + }, 100); + }, 100); + }, 300); + }); + it('updatePopper', done => { + vm = createVue({ + template: ` + + + 下拉菜单 + + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + ` + }, true); + let dropdown = vm.$refs.dropdown; + let dropdownElm = dropdown.$el; + let triggerElm = dropdownElm.children[0]; + + triggerEvent(triggerElm, 'mouseenter'); + setTimeout(() => { + const zIndex1 = document.querySelector('.el-dropdown-menu').style.zIndex; + dropdown.broadcast('ElDropdownMenu', 'updatePopper'); + setTimeout(() => { + const zIndex2 = document.querySelector('.el-dropdown-menu').style.zIndex; + expect(zIndex2 > zIndex1).to.be.true; + done(); + }, 100); + }, 300); + }); +}); diff --git a/test/unit/specs/form.spec.js b/test/unit/specs/form.spec.js new file mode 100644 index 0000000..c3f6edd --- /dev/null +++ b/test/unit/specs/form.spec.js @@ -0,0 +1,993 @@ +import { createVue, destroyVM, waitImmediate } from '../util'; + +const DELAY = 50; + +describe('Form', () => { + let vm; + let hasPromise = true; + before(() => { + if (!window.Promise) { + hasPromise = false; + window.Promise = require('es6-promise').Promise; + } + }); + + after(() => { + if (!hasPromise) { + window.Promise = undefined; + } + }); + + afterEach(() => { + destroyVM(vm); + }); + + it('label width', done => { + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + name: '' + } + }; + } + }, true); + expect(vm.$el.querySelector('.el-form-item__label').style.width).to.equal('80px'); + expect(vm.$el.querySelector('.el-form-item__content').style.marginLeft).to.equal('80px'); + done(); + }); + it('auto label width', async() => { + vm = createVue({ + template: ` + + + + + + + + + `, + data() { + return { + display: true, + form: { + name: '', + intro: '' + } + }; + } + }, true); + + await waitImmediate(); + + const formItems = vm.$el.querySelectorAll('.el-form-item__content'); + const marginLeft = parseInt(formItems[0].style.marginLeft, 10); + const marginLeft1 = parseInt(formItems[1].style.marginLeft, 10); + expect(marginLeft === marginLeft1).to.be.true; + + vm.display = false; + await waitImmediate(); + + const formItem = vm.$el.querySelector('.el-form-item__content'); + const newMarginLeft = parseInt(formItem.style.marginLeft, 10); + expect(newMarginLeft < marginLeft).to.be.true; + }); + it('inline form', done => { + vm = createVue({ + template: ` + + + + + + + + + `, + data() { + return { + form: { + name: '', + address: '' + } + }; + } + }, true); + expect(vm.$el.classList.contains('el-form--inline')).to.be.true; + done(); + }); + it('label position', done => { + vm = createVue({ + template: ` +
+ + + + + + + + + + + + + + + + +
+ `, + data() { + return { + form: { + name: '', + address: '' + } + }; + } + }, true); + expect(vm.$refs.labelTop.$el.classList.contains('el-form--label-top')).to.be.true; + expect(vm.$refs.labelLeft.$el.classList.contains('el-form--label-left')).to.be.true; + done(); + }); + it('label size', () => { + vm = createVue({ + template: ` +
+ + + + + +
+ `, + data() { + return { + form: { + name: '' + } + }; + } + }, true); + expect(vm.$refs.labelMini.$el.children[0].classList.contains('el-form-item--mini')).to.be.true; + }); + it('show message', done => { + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + name: '' + } + }; + } + }, true); + vm.$refs.form.validate(valid => { + expect(valid).to.not.true; + vm.$refs.form.$nextTick(_ => { + expect(vm.$el.querySelector('.el-form-item__error')).to.not.exist; + done(); + }); + }); + }); + it('reset field', done => { + vm = createVue({ + template: ` + + + + + + + + + + + + + + + + + `, + data() { + return { + form: { + name: '', + address: '', + type: [] + }, + rules: { + name: [ + { required: true, message: '请输入活动名称', trigger: 'blur' } + ], + address: [ + { required: true, message: '请选择活动区域', trigger: 'change' } + ], + type: [ + { type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' } + ] + } + }; + }, + methods: { + setValue() { + this.form.name = 'jack'; + this.form.address = 'aaaa'; + this.form.type.push('地推活动'); + } + } + }, true); + vm.setValue(); + vm.$refs.form.resetFields(); + vm.$refs.form.$nextTick(_ => { + expect(vm.form.name).to.equal(''); + expect(vm.form.address).to.equal(''); + expect(vm.form.type.length).to.equal(0); + done(); + }); + }); + it('clear validate', done => { + vm = createVue({ + template: ` + + + + + + + + + + + + + + + + + `, + data() { + return { + form: { + name: '', + address: '', + type: [] + }, + rules: { + name: [ + { required: true, message: '请输入活动名称', trigger: 'blur' } + ], + address: [ + { required: true, message: '请选择活动区域', trigger: 'change' } + ], + type: [ + { type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' } + ] + } + }; + } + }, true); + const form = vm.$refs.form; + const nameField = form.fields.filter(field => field.prop === 'name')[0]; + const addressField = form.fields.filter(field => field.prop === 'address')[0]; + form.validate(); + vm.$nextTick(() => { + expect(nameField.validateMessage).to.equal('请输入活动名称'); + form.clearValidate(['name']); + vm.$nextTick(() => { + expect(nameField.validateMessage).to.equal(''); + form.clearValidate(); + vm.$nextTick(() => { + expect(addressField.validateMessage).to.equal(''); + done(); + }); + }); + }); + }); + it('form item nest', done => { + vm = createVue({ + template: ` + + + + + + + + - + + + + + + + + `, + data() { + return { + form: { + date1: '', + date2: '' + }, + rules: { + date1: [ + { type: 'date', required: true, message: '请选择日期', trigger: 'change' } + ] + } + }; + }, + methods: { + setValue() { + this.name = 'jack'; + this.address = 'aaaa'; + } + } + }, true); + vm.$refs.form.validate(valid => { + expect(valid).to.not.true; + done(); + }); + }); + describe('validate', () => { + it('input', done => { + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + name: '' + }, + rules: { + name: [ + { required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 } + ] + } + }; + }, + methods: { + setValue(value) { + this.form.name = value; + } + } + }, true); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.not.true; + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal('请输入活动名称'); + vm.setValue('aaaaa'); + + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal(''); + vm.setValue('aa'); + + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal('请输入活动名称'); + done(); + }); + }); + }); + }); + }); + it('textarea', done => { + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + name: '' + }, + rules: { + name: [ + { required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 } + ] + } + }; + }, + methods: { + setValue(value) { + this.form.name = value; + } + } + }, true); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.not.true; + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal('请输入活动名称'); + vm.setValue('aaaaa'); + + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal(''); + vm.setValue('aa'); + + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal('请输入活动名称'); + done(); + }); + }); + }); + }); + }); + it('selector', done => { + vm = createVue({ + template: ` + + + + + + + + + `, + data() { + return { + form: { + region: '' + }, + rules: { + region: [ + {required: true, message: '请选择活动区域', trigger: 'change' } + ] + } + }; + } + }, true); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.false; + setTimeout(_ => { + expect(field.validateMessage).to.equal('请选择活动区域'); + // programatic modification triggers change validation + vm.form.region = 'shanghai'; + setTimeout(_ => { + expect(field.validateMessage).to.equal(''); + vm.form.region = ''; + setTimeout(_ => { + expect(field.validateMessage).to.equal('请选择活动区域'); + // user modification of bound value triggers change validation + vm.$refs.opt.$el.click(); + setTimeout(_ => { + expect(field.validateMessage).to.equal(''); + done(); + }, 100); + }, 100); + }, 100); + }, 100); + }); + }); + it('datepicker', done => { + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + date: '' + }, + rules: { + date: [ + {type: 'date', required: true, message: '请选择日期', trigger: 'change' } + ] + } + }; + } + }, true); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.not.true; + setTimeout(_ => { + expect(field.validateMessage).to.equal('请选择日期'); + // programatic modification triggers change validation + vm.form.date = new Date(); + setTimeout(_ => { + expect(field.validateMessage).to.equal(''); + vm.form.date = ''; + // user modification triggers change + const input = vm.$refs.picker.$el.querySelector('input'); + input.blur(); + input.focus(); + setTimeout(_ => { + const keyDown = (el, keyCode) => { + const evt = document.createEvent('Events'); + evt.initEvent('keydown', true, true); + evt.keyCode = keyCode; + el.dispatchEvent(evt); + }; + keyDown(input, 37); + setTimeout(_ => { + keyDown(input, 13); + setTimeout(_ => { + expect(field.validateMessage).to.equal(''); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }, DELAY); + }, DELAY); + }); + }); + it('timepicker', done => { + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + date: '' + }, + rules: { + date: [ + {type: 'date', required: true, message: '请选择时间', trigger: 'change' } + ] + } + }; + } + }, true); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.not.true; + setTimeout(_ => { + expect(field.validateMessage).to.equal('请选择时间'); + // programatic modification does not trigger change + vm.value = new Date(); + setTimeout(_ => { + expect(field.validateMessage).to.equal('请选择时间'); + vm.value = ''; + // user modification triggers change + const input = vm.$refs.picker.$el.querySelector('input'); + input.blur(); + input.focus(); + setTimeout(_ => { + vm.$refs.picker.picker.$el.querySelector('.confirm').click(); + setTimeout(_ => { + expect(field.validateMessage).to.equal(''); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }, DELAY); + }); + }); + it('checkbox', done => { + vm = createVue({ + template: ` + + + + 接受协议 + + + + `, + data() { + return { + form: { + accept: true + }, + rules: { + accept: [ + { + validator: (rule, value, callback) => { + value ? callback() : callback(new Error('您需要接受用户协议')); + }, + trigger: 'change' + } + ] + } + }; + }, + methods: { + setValue(value) { + this.form.accept = value; + } + } + }, true); + vm.form.accept = false; + vm.$nextTick(_ => { + expect(vm.$refs.field.validateMessage).to.equal('您需要接受用户协议'); + }); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.not.true; + expect(field.validateMessage).to.equal('您需要接受用户协议'); + vm.$refs.form.$nextTick(_ => { + vm.setValue(true); + + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal(''); + done(); + }); + }); + }); + }); + it('checkbox group', done => { + vm = createVue({ + template: ` + + + + + + + + + + + `, + data() { + return { + form: { + type: [] + }, + rules: { + type: [ + { type: 'array', required: true, message: '请选择活动类型', trigger: 'change' } + ] + } + }; + }, + methods: { + setValue(value) { + this.form.type = value; + } + } + }, true); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.not.true; + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal('请选择活动类型'); + vm.setValue(['地推活动']); + + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal(''); + done(); + }); + }); + }); + }); + it('radio group', done => { + vm = createVue({ + template: ` + + + + + + + + + `, + data() { + return { + form: { + type: '' + }, + rules: { + type: [ + { required: true, message: '请选择活动类型', trigger: 'change' } + ] + } + }; + }, + methods: { + setValue(value) { + this.form.type = value; + } + } + }, true); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.not.true; + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal('请选择活动类型'); + vm.setValue('线下场地免费'); + + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal(''); + done(); + }); + }); + }); + }); + it('validate field', done => { + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + name: '' + }, + rules: { + name: [ + { required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 } + ] + } + }; + }, + methods: { + setValue(value) { + this.form.name = value; + } + } + }, true); + vm.$refs.form.validateField('name', valid => { + expect(valid).to.not.true; + done(); + }); + }); + it('custom validate', done => { + var checkName = (rule, value, callback) => { + if (value.length < 5) { + callback(new Error('长度至少为5')); + } else { + callback(); + } + }; + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + name: '' + }, + rules: { + name: [ + { validator: checkName, trigger: 'change' } + ] + } + }; + }, + methods: { + setValue(value) { + this.form.name = value; + } + } + }, true); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.not.true; + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal('长度至少为5'); + vm.setValue('aaaaaa'); + + vm.$refs.form.$nextTick(_ => { + expect(field.validateMessage).to.equal(''); + done(); + }); + }); + }); + }); + it('error', done => { + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + error: 'dsad', + form: { + name: 'sada' + }, + rules: { + name: [ + { required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 } + ] + } + }; + }, + methods: { + setValue(value) { + this.form.name = value; + } + } + }, true); + vm.$refs.form.validate(valid => { + let field = vm.$refs.field; + expect(valid).to.true; + vm.error = '输入不合法'; + + vm.$refs.field.$nextTick(_ => { + expect(field.validateState).to.equal('error'); + expect(field.validateMessage).to.equal('输入不合法'); + done(); + }); + }); + }); + it('invalid fields', done => { + var checkName = (rule, value, callback) => { + if (value.length < 5) { + callback(new Error('长度至少为5')); + } else { + callback(); + } + }; + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + name: '' + }, + rules: { + name: [ + { validator: checkName, trigger: 'change' } + ] + } + }; + } + }, true); + vm.$refs.form.validate((valid, invalidFields) => { + expect(invalidFields.name.length).to.equal(1); + done(); + }); + }); + it('validate return promise', done => { + var checkName = (rule, value, callback) => { + if (value.length < 5) { + callback(new Error('长度至少为5')); + } else { + callback(); + } + }; + vm = createVue({ + template: ` + + + + + + `, + data() { + return { + form: { + name: '' + }, + rules: { + name: [ + { validator: checkName, trigger: 'change' } + ] + } + }; + } + }, true); + vm.$refs.form.validate().catch(validFailed => { + expect(validFailed).to.false; + done(); + }); + }); + }); + it('validate event', done => { + vm = createVue({ + template: ` + + + + + + + + + `, + data() { + return { + form: { + name: '', + addr: '' + }, + valid: { + name: null, + addr: null + }, + error: { + name: null, + addr: null + }, + rules: { + name: [ + { required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 } + ], + addr: [ + { required: true, message: '请输入活动名称', trigger: 'change' } + ] + } + }; + }, + methods: { + onValidate(prop, valid, msg) { + this.valid[prop] = valid; + this.error[prop] = msg; + }, + setValue(prop, value) { + this.form[prop] = value; + } + } + }, true); + vm.setValue('name', '1'); + setTimeout(() => { + expect(vm.valid.name).to.equal(false); + expect(vm.error.name).to.equal('请输入活动名称'); + vm.setValue('addr', '1'); + setTimeout(() => { + expect(vm.valid.addr).to.equal(true); + expect(vm.error.addr).to.equal(null); + vm.setValue('name', '111'); + setTimeout(() => { + expect(vm.valid.name).to.equal(true); + expect(vm.error.name).to.equal(null); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }); +}); diff --git a/test/unit/specs/image.spec.js b/test/unit/specs/image.spec.js new file mode 100644 index 0000000..77624df --- /dev/null +++ b/test/unit/specs/image.spec.js @@ -0,0 +1,137 @@ +import { createTest, createVue, destroyVM, wait } from '../util'; +import Image from 'packages/image'; +import { IMAGE_SUCCESS, IMAGE_FAIL } from '../mocks/uri'; + +const src = IMAGE_SUCCESS; + +describe('Image', () => { + let vm; + + afterEach(() => { + destroyVM(vm); + }); + + it('create', async() => { + vm = createTest(Image, { + src, + fit: 'fill' + }, true); + const placeholder = vm.$el.querySelector('.el-image__placeholder'); + const error = vm.$el.querySelector('.el-image__error'); + let img = vm.$el.querySelector('.el-image__inner'); + expect(placeholder).to.exist; + expect(error).to.be.null; + expect(img).to.be.null; + + await wait(); + img = vm.$el.querySelector('.el-image__inner'); + expect(img.style.objectFit).to.equal('fill'); + }); + + it('load failed', async() => { + vm = createTest(Image, { + src: IMAGE_FAIL + }, true); + await wait(); + const error = vm.$el.querySelector('.el-image__error'); + expect(error).to.be.exist; + }); + + it('lazy load', async() => { + vm = createVue({ + template: ` +
+ +
+ `, + data() { + return { + src + }; + } + }, true); + const { image, wrapper } = vm.$refs; + const [image1, image2] = image; + + await wait(); + expect(image1.loading).to.be.false; + expect(image2.loading).to.be.true; + wrapper.scrollTop = 10; + + await wait(); + expect(image2.loading).to.be.false; + }); + + it('$attrs', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + src + }; + } + }, true); + + await wait(); + const $img = vm.$el.querySelector('.el-image__inner'); + expect($img.getAttribute('alt')).to.be.equal('$attrs test'); + expect($img.getAttribute('referrerpolicy')).to.be.equal('origin'); + }); + + it('pass event listeners', async() => { + let result; + vm = createVue({ + template: ` + + `, + data() { + return { + src + }; + }, + methods: { + handleClick(e) { + result = e; + } + } + }, true); + await wait(); + vm.$el.querySelector('.el-image__inner').click(); + await wait(); + expect(result).to.exist; + }); + + it('big image preview', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + src: src, + srcList: [src] + }; + } + }, true); + await wait(); + vm.$el.querySelector('.el-image__inner').click(); + await wait(); + + expect(document.querySelector('.el-image-viewer__wrapper')).to.exist; + document.querySelector('.el-image-viewer__close').click(); + await wait(1000); + expect(document.querySelector('.el-image-viewer__wrapper')).to.not.exist; + }); +}); + diff --git a/test/unit/specs/infiniteScroll.spec.js b/test/unit/specs/infiniteScroll.spec.js new file mode 100644 index 0000000..7f3d26b --- /dev/null +++ b/test/unit/specs/infiniteScroll.spec.js @@ -0,0 +1,58 @@ +import { createVue, wait, destroyVM } from '../util'; + +describe('InfiniteScroll', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', async() => { + vm = createVue({ + template: ` +
    +
  • {{ i }}
  • +
+ `, + data() { + return { + count: 0 + }; + }, + methods: { + load() { + this.count += 2; + } + } + }, true); + vm.$refs.scrollTarget.scrollTop = 2000; + await wait(); + expect(vm.$el.innerText.indexOf('2') > -1).to.be.true; + }); + + it('invisible element not trigger', async() => { + vm = createVue({ + template: ` +
+
    +
  • {{ i }}
  • +
+
+ `, + data() { + return { + count: 0 + }; + }, + methods: { + load() { + this.count += 2; + } + } + }, true); + vm.$refs.scrollTarget.scrollTop = 2000; + await wait(); + expect(vm.$el.innerText.indexOf('2') > -1).to.be.false; + }); + +}); + diff --git a/test/unit/specs/input-number.spec.js b/test/unit/specs/input-number.spec.js new file mode 100644 index 0000000..dbff288 --- /dev/null +++ b/test/unit/specs/input-number.spec.js @@ -0,0 +1,453 @@ +import {createVue, triggerEvent, triggerClick, destroyVM, waitImmediate} from '../util'; + +const DELAY = 1; + +describe('InputNumber', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + it('create', () => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 1 + }; + } + }, true); + let input = vm.$el.querySelector('input'); + + expect(vm.value).to.be.equal(1); + expect(input.value).to.be.equal('1'); + }); + it('decrease', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 5 + }; + } + }, true); + + let input = vm.$el.querySelector('input'); + let btnDecrease = vm.$el.querySelector('.el-input-number__decrease'); + + triggerEvent(btnDecrease, 'mousedown'); + triggerClick(document, 'mouseup'); + + vm.$nextTick(_ => { + expect(vm.value).to.be.equal(4); + expect(input.value).to.be.equal('4'); + done(); + }); + }); + it('increase', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 1.5 + }; + } + }, true); + + let input = vm.$el.querySelector('input'); + let btnIncrease = vm.$el.querySelector('.el-input-number__increase'); + + triggerEvent(btnIncrease, 'mousedown'); + triggerClick(document, 'mouseup'); + + vm.$nextTick(_ => { + expect(vm.value).to.be.equal(2.5); + expect(input.value).to.be.equal('2.5'); + done(); + }); + }); + it('disabled', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 2 + }; + } + }, true); + + let input = vm.$el.querySelector('input'); + let btnDecrease = vm.$el.querySelector('.el-input-number__decrease'); + let btnIncrease = vm.$el.querySelector('.el-input-number__increase'); + + triggerEvent(btnDecrease, 'mousedown'); + triggerClick(document, 'mouseup'); + + vm.$nextTick(_ => { + expect(vm.value).to.be.equal(2); + expect(input.value).to.be.equal('2'); + + triggerEvent(btnIncrease, 'mousedown'); + triggerClick(document, 'mouseup'); + + vm.$nextTick(_ => { + expect(vm.value).to.be.equal(2); + expect(input.value).to.be.equal('2'); + done(); + }); + }); + }); + it('step', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 5 + }; + } + }, true); + + let input = vm.$el.querySelector('input'); + let btnIncrease = vm.$el.querySelector('.el-input-number__increase'); + let btnDecrease = vm.$el.querySelector('.el-input-number__decrease'); + + triggerEvent(btnIncrease, 'mousedown'); + triggerClick(document, 'mouseup'); + + vm.$nextTick(_ => { + expect(vm.value).to.be.equal(8.2); + expect(input.value).to.be.equal('8.2'); + + triggerEvent(btnDecrease, 'mousedown'); + triggerClick(document, 'mouseup'); + + vm.$nextTick(_ => { + expect(vm.value).to.be.equal(5); + expect(input.value).to.be.equal('5'); + done(); + }); + }); + }); + it('step strictly', async() => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 5 + }; + } + }, true); + + let input = vm.$el.querySelector('input'); + await waitImmediate(); + expect(vm.value).to.be.equal(4.8); + expect(input.value).to.be.equal('4.8'); + vm.value = '8'; + + await waitImmediate(); + expect(vm.value).to.be.equal(8.4); + expect(input.value).to.be.equal('8.4'); + }); + it('min', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 6 + }; + } + }, true); + const vm2 = createVue({ + template: ` + + + `, + data() { + return { + value: 3 + }; + } + }, true); + + expect(vm2.value === 6); + expect(vm2.$el.querySelector('input').value).to.be.equal('6'); + + let input = vm.$el.querySelector('input'); + let btnDecrease = vm.$el.querySelector('.el-input-number__decrease'); + + triggerEvent(btnDecrease, 'mousedown'); + triggerClick(document, 'mouseup'); + + vm.$nextTick(_ => { + expect(vm.value).to.be.equal(6); + expect(input.value).to.be.equal('6'); + done(); + }); + }); + it('max', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 8 + }; + } + }, true); + const vm2 = createVue({ + template: ` + + + `, + data() { + return { + value: 100 + }; + } + }, true); + + expect(vm2.value === 8); + expect(vm2.$el.querySelector('input').value).to.be.equal('8'); + + let input = vm.$el.querySelector('input'); + let btnIncrease = vm.$el.querySelector('.el-input-number__increase'); + + triggerEvent(btnIncrease, 'mousedown'); + triggerClick(document, 'mouseup'); + + vm.$nextTick(_ => { + expect(vm.value).to.be.equal(8); + expect(input.value).to.be.equal('8'); + done(); + }); + }); + describe('precision', () => { + it('precision is 2', () => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 6.999 + }; + } + }, true); + expect(vm.value === 7); + expect(vm.$el.querySelector('input').value).to.be.equal('7.00'); + }); + + it('precision greater than the precision of step', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 6.999 + }; + } + }, true); + const input = vm.$el.querySelector('input'); + const btnIncrease = vm.$el.querySelector('.el-input-number__increase'); + + expect(vm.value === 7); + expect(input.value).to.be.equal('7'); + + triggerEvent(btnIncrease, 'mousedown'); + triggerClick(document, 'mouseup'); + + vm.$nextTick(_ => { + expect(vm.value).to.be.equal(7); + expect(input.value).to.be.equal('7'); + done(); + }); + }); + }); + it('controls', () => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 8 + }; + } + }, true); + + expect(vm.$el.querySelector('.el-input-number__decrease')).to.not.exist; + expect(vm.$el.querySelector('.el-input-number__increase')).to.not.exist; + }); + it('invalid value reset', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 5 + }; + } + }, true); + const inputNumber = vm.$refs.inputNumber; + vm.value = 100; + vm.$nextTick(_ => { + expect(inputNumber.currentValue).to.be.equal(10); + vm.value = 4; + + vm.$nextTick(_ => { + expect(inputNumber.currentValue).to.be.equal(5); + vm.value = 'dsajkhd'; + + vm.$nextTick(_ => { + expect(inputNumber.currentValue).to.be.equal(5); + done(); + }); + }); + }); + }); + describe('event:change', () => { + let spy; + + beforeEach(() => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 2 + }; + } + }, true); + spy = sinon.spy(); + vm.$refs.compo.$on('change', spy); + }); + + it('emit on input', done => { + vm.$refs.compo.handleInputChange('3'); + setTimeout(_ => { + expect(spy.calledOnce).to.be.true; + expect(spy.args[0][0]).to.equal(3); + done(); + }, DELAY); + }); + + it('emit on button', done => { + const btnIncrease = vm.$el.querySelector('.el-input-number__increase'); + triggerEvent(btnIncrease, 'mousedown'); + triggerClick(document, 'mouseup'); + setTimeout(_ => { + expect(spy.calledOnce).to.be.true; + expect(spy.args[0][0]).to.equal(3); + done(); + }, DELAY); + }); + + it('does not emit on programatic change', done => { + vm.value = 3; + setTimeout(_ => { + expect(spy.notCalled).to.be.true; + done(); + }, DELAY); + }); + }); + it('event:focus & blur', done => { + vm = createVue({ + template: ` + + + ` + }, true); + + const spyFocus = sinon.spy(); + const spyBlur = sinon.spy(); + + vm.$refs.input.$on('focus', spyFocus); + vm.$refs.input.$on('blur', spyBlur); + vm.$el.querySelector('input').focus(); + vm.$el.querySelector('input').blur(); + + vm.$nextTick(_ => { + expect(spyFocus.calledOnce).to.be.true; + expect(spyBlur.calledOnce).to.be.true; + done(); + }); + }); + it('focus', done => { + vm = createVue({ + template: ` + + ` + }, true); + + const spy = sinon.spy(); + + vm.$refs.input.$on('focus', spy); + vm.$refs.input.focus(); + + vm.$nextTick(_ => { + expect(spy.calledOnce).to.be.true; + done(); + }); + }); + + describe('InputNumber Methods', () => { + it('method:select', done => { + const testContent = '123'; + + vm = createVue({ + template: ` + + ` + }, true); + + expect(vm.$refs.inputNumComp.$refs.input.$refs.input.selectionStart) + .to.equal(testContent.length); + expect(vm.$refs.inputNumComp.$refs.input.$refs.input.selectionEnd) + .to.equal(testContent.length); + + vm.$refs.inputNumComp.select(); + + vm.$nextTick(_ => { + expect(vm.$refs.inputNumComp.$refs.input.$refs.input.selectionStart) + .to.equal(0); + expect(vm.$refs.inputNumComp.$refs.input.$refs.input.selectionEnd) + .to.equal(testContent.length); + + done(); + }); + }); + }); +}); diff --git a/test/unit/specs/input.spec.js b/test/unit/specs/input.spec.js new file mode 100644 index 0000000..f12b87b --- /dev/null +++ b/test/unit/specs/input.spec.js @@ -0,0 +1,483 @@ +import { createVue, destroyVM, triggerEvent, wait, waitImmediate } from '../util'; + +describe('Input', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', async() => { + vm = createVue({ + template: ` + + + `, + data() { + return { + input: 'input', + inputFocus: false + }; + }, + methods: { + handleFocus() { + this.inputFocus = true; + } + } + }, true); + let inputElm = vm.$el.querySelector('input'); + inputElm.focus(); + expect(vm.inputFocus).to.be.true; + expect(inputElm.getAttribute('placeholder')).to.equal('请输入内容'); + expect(inputElm.value).to.equal('input'); + expect(inputElm.getAttribute('minlength')).to.equal('3'); + expect(inputElm.getAttribute('maxlength')).to.equal('5'); + + vm.input = 'text'; + await waitImmediate(); + expect(inputElm.value).to.equal('text'); + }); + + it('default to empty', () => { + vm = createVue({ + template: '' + }, true); + let inputElm = vm.$el.querySelector('input'); + expect(inputElm.value).to.equal(''); + }); + + it('disabled', () => { + vm = createVue({ + template: ` + + + ` + }, true); + expect(vm.$el.querySelector('input').getAttribute('disabled')).to.ok; + }); + + it('suffixIcon', () => { + vm = createVue({ + template: ` + + ` + }, true); + var icon = vm.$el.querySelector('.el-input__icon'); + expect(icon).to.be.exist; + }); + + it('prefixIcon', () => { + vm = createVue({ + template: ` + + ` + }, true); + var icon = vm.$el.querySelector('.el-input__icon'); + expect(icon).to.be.exist; + }); + + it('size', () => { + vm = createVue({ + template: ` + + + ` + }, true); + + expect(vm.$el.classList.contains('el-input--large')).to.true; + }); + + it('type', () => { + vm = createVue({ + template: ` + + + ` + }, true); + + expect(vm.$el.classList.contains('el-textarea')).to.true; + }); + + it('rows', () => { + vm = createVue({ + template: ` + + + ` + }, true); + expect(vm.$el.querySelector('.el-textarea__inner').getAttribute('rows')).to.be.equal('3'); + }); + + // Github issue #2836 + it('resize', async() => { + vm = createVue({ + template: ` +
+ +
+ `, + data: { + resize: 'none' + } + }, true); + await waitImmediate(); + expect(vm.$el.querySelector('.el-textarea__inner').style.resize).to.be.equal(vm.resize); + vm.resize = 'horizontal'; + await waitImmediate(); + expect(vm.$el.querySelector('.el-textarea__inner').style.resize).to.be.equal(vm.resize); + }); + + it('autosize', async() => { + vm = createVue({ + template: ` +
+ + + + +
+ `, + data() { + return { + textareaValue: 'sda\ndasd\nddasdsda\ndasd\nddasdsda\ndasd\nddasdsda\ndasd\nddasd' + }; + } + }, true); + + var limitSizeInput = vm.$refs.limitSize; + var limitlessSizeInput = vm.$refs.limitlessSize; + expect(limitSizeInput.textareaStyle.height).to.be.equal('117px'); + expect(limitlessSizeInput.textareaStyle.height).to.be.equal('201px'); + + vm.textareaValue = ''; + + await wait(); + expect(limitSizeInput.textareaStyle.height).to.be.equal('75px'); + expect(limitlessSizeInput.textareaStyle.height).to.be.equal('33px'); + }); + + it('focus', async() => { + vm = createVue({ + template: ` + + + ` + }, true); + + const spy = sinon.spy(); + + vm.$refs.input.$on('focus', spy); + vm.$refs.input.focus(); + + await waitImmediate(); + expect(spy.calledOnce).to.be.true; + }); + + it('Input contains Select and append slot', async() => { + vm = createVue({ + template: ` + + + + + + + + + `, + data() { + return { + value: '1234', + select: '1' + }; + } + }, true); + vm.$refs.input.hovering = true; + + await wait(); + const suffixEl = document.querySelector('.input-with-select > .el-input__suffix'); + expect(suffixEl).to.not.be.null; + expect(suffixEl.style.transform).to.not.be.empty; + }); + + it('validateEvent', async() => { + const spy = sinon.spy(); + vm = createVue({ + template: ` + + + + + + + `, + data() { + const validator = (rule, value, callback) => { + spy(); + callback(); + }; + return { + model: { + input: '' + }, + rules: { + input: [ + { validator } + ] + } + }; + } + }, true); + + vm.model.input = '123'; + await waitImmediate(); + expect(spy.called).to.be.false; + }); + + describe('Input Events', () => { + it('event:focus & blur', async() => { + vm = createVue({ + template: ` + + + ` + }, true); + + const spyFocus = sinon.spy(); + const spyBlur = sinon.spy(); + + vm.$refs.input.$on('focus', spyFocus); + vm.$refs.input.$on('blur', spyBlur); + vm.$el.querySelector('input').focus(); + vm.$el.querySelector('input').blur(); + + await waitImmediate(); + expect(spyFocus.calledOnce).to.be.true; + expect(spyBlur.calledOnce).to.be.true; + }); + it('event:change', async() => { + // NOTE: should be same as native's change behavior + vm = createVue({ + template: ` + + + `, + data() { + return { + input: 'a' + }; + } + }, true); + + const inputElm = vm.$el.querySelector('input'); + const simulateEvent = (text, event) => { + inputElm.value = text; + inputElm.dispatchEvent(new Event(event)); + }; + + const spy = sinon.spy(); + vm.$refs.input.$on('change', spy); + + // simplified test, component should emit change when native does + simulateEvent('1', 'input'); + simulateEvent('2', 'change'); + await waitImmediate(); + expect(spy.calledWith('2')).to.be.true; + expect(spy.calledOnce).to.be.true; + }); + it('event:clear', async() => { + vm = createVue({ + template: ` + + + `, + data() { + return { + input: 'a' + }; + } + }, true); + + const spyClear = sinon.spy(); + const inputElm = vm.$el.querySelector('input'); + + // focus to show clear button + inputElm.focus(); + vm.$refs.input.$on('clear', spyClear); + await waitImmediate(); + vm.$el.querySelector('.el-input__clear').click(); + await waitImmediate(); + expect(spyClear.calledOnce).to.be.true; + }); + it('event:input', async() => { + vm = createVue({ + template: ` + + + `, + data() { + return { + input: 'a' + }; + } + }, true); + const spy = sinon.spy(); + vm.$refs.input.$on('input', spy); + const nativeInput = vm.$refs.input.$el.querySelector('input'); + nativeInput.value = '1'; + triggerEvent(nativeInput, 'compositionstart'); + triggerEvent(nativeInput, 'input'); + await waitImmediate(); + nativeInput.value = '2'; + triggerEvent(nativeInput, 'compositionupdate'); + triggerEvent(nativeInput, 'input'); + await waitImmediate(); + triggerEvent(nativeInput, 'compositionend'); + await waitImmediate(); + // input event does not fire during composition + expect(spy.calledOnce).to.be.true; + // native input value is controlled + expect(vm.input).to.equal('a'); + expect(nativeInput.value).to.equal('a'); + + }); + }); + + describe('Input Methods', () => { + it('method:select', async() => { + const testContent = 'test'; + + vm = createVue({ + template: ` + + ` + }, true); + + expect(vm.$refs.inputComp.$refs.input.selectionStart).to.equal(testContent.length); + expect(vm.$refs.inputComp.$refs.input.selectionEnd).to.equal(testContent.length); + + vm.$refs.inputComp.select(); + + await waitImmediate(); + expect(vm.$refs.inputComp.$refs.input.selectionStart).to.equal(0); + expect(vm.$refs.inputComp.$refs.input.selectionEnd).to.equal(testContent.length); + }); + }); + + it('sets value on textarea / input type change', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + type: 'text', + val: '123' + }; + } + }, true); + + expect(vm.$el.querySelector('input').value).to.equal('123'); + vm.type = 'textarea'; + await waitImmediate(); + expect(vm.$el.querySelector('textarea').value).to.equal('123'); + vm.type = 'password'; + await waitImmediate(); + expect(vm.$el.querySelector('input').value).to.equal('123'); + }); + + it('limit input and show word count', async() => { + vm = createVue({ + template: ` +
+ + + + + + + + +
+ `, + data() { + return { + input1: '', + input2: '', + input3: '', + input4: 'exceed', + show: false + }; + } + }, true); + + const inputElm1 = vm.$el.querySelector('.test-text'); + const inputElm2 = vm.$el.querySelector('.test-textarea'); + const inputElm3 = vm.$el.querySelector('.test-password'); + const inputElm4 = vm.$el.querySelector('.test-initial-exceed'); + + expect(inputElm1.querySelectorAll('.el-input__count').length).to.equal(0); + expect(inputElm2.querySelectorAll('.el-input__count').length).to.equal(1); + expect(inputElm3.querySelectorAll('.el-input__count').length).to.equal(0); + expect(inputElm4.classList.contains('is-exceed')).to.true; + + vm.show = true; + await waitImmediate(); + expect(inputElm1.querySelectorAll('.el-input__count').length).to.equal(1); + + vm.input4 = '1'; + await waitImmediate(); + expect(inputElm4.classList.contains('is-exceed')).to.false; + }); +}); diff --git a/test/unit/specs/link.spec.js b/test/unit/specs/link.spec.js new file mode 100644 index 0000000..5eae9f0 --- /dev/null +++ b/test/unit/specs/link.spec.js @@ -0,0 +1,66 @@ +import { createTest, createVue, destroyVM, wait } from '../util'; +import Link from 'packages/link'; + +describe('Link', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Link, { + type: 'primary' + }, true); + let linkElm = vm.$el; + expect(linkElm.classList.contains('el-link--primary')).to.be.true; + }); + it('icon', () => { + vm = createTest(Link, { + icon: 'el-icon-search' + }, true); + let linkElm = vm.$el; + expect(linkElm.querySelector('.el-icon-search')).to.be.ok; + }); + it('href', () => { + vm = createTest(Link, { + href: 'https://element.eleme.io/' + }, true); + let linkElm = vm.$el; + expect(linkElm.getAttribute('href')).to.be.equal('https://element.eleme.io/'); + }); + it('target', () => { + vm = createVue(` + + default + + `); + let linkElm = vm.$el; + expect(linkElm.getAttribute('target')).to.be.equal('_blank'); + }); + it('disabled', () => { + vm = createTest(Link, { + disabled: true + }, true); + let linkElm = vm.$el; + expect(linkElm.classList.contains('is-disabled')).to.be.true; + }); + + it('click', async() => { + let result; + vm = createVue({ + template: ` + + `, + methods: { + handleClick(evt) { + result = evt; + } + } + }, true); + vm.$el.click(); + await wait(); + expect(result).to.exist; + }); + +}); + diff --git a/test/unit/specs/loading.spec.js b/test/unit/specs/loading.spec.js new file mode 100644 index 0000000..480d861 --- /dev/null +++ b/test/unit/specs/loading.spec.js @@ -0,0 +1,282 @@ +import { getStyle } from '../../../src/utils/dom'; +import { createVue, destroyVM } from '../util'; +import Vue from 'vue'; +import LoadingRaw from 'packages/loading'; +const Loading = LoadingRaw.service; + +describe('Loading', () => { + let vm, loadingInstance, loadingInstance2; + afterEach(() => { + destroyVM(vm); + if (loadingInstance) { + loadingInstance.close(); + loadingInstance.$el && + loadingInstance.$el.parentNode && + loadingInstance.$el.parentNode.removeChild(loadingInstance.$el); + } + if (loadingInstance2) { + loadingInstance2.close(); + loadingInstance2.$el && + loadingInstance2.$el.parentNode && + loadingInstance2.$el.parentNode.removeChild(loadingInstance2.$el); + } + }); + + describe('as a directive', () => { + it('create', done => { + vm = createVue({ + template: ` +
+ `, + + data() { + return { + loading: true + }; + } + }); + Vue.nextTick(() => { + const mask = vm.$el.querySelector('.el-loading-mask'); + expect(mask).to.exist; + vm.loading = false; + setTimeout(() => { + expect(mask.style.display).to.equal('none'); + done(); + }, 100); + }); + }); + + it('unbind', done => { + const vm1 = createVue({ + template: ` +
+ `, + + data() { + return { + show: true, + loading: true + }; + } + }); + const vm2 = createVue({ + template: ` +
+ `, + + data() { + return { + show: true, + loading: true + }; + } + }); + Vue.nextTick(() => { + vm1.loading = false; + vm2.loading = false; + Vue.nextTick(() => { + vm1.show = false; + vm2.show = false; + Vue.nextTick(() => { + expect(document.querySelector('.el-loading-mask')).to.not.exist; + done(); + }); + }); + }); + }); + + it('body', done => { + vm = createVue({ + template: ` +
+ `, + + data() { + return { + loading: true + }; + } + }, true); + Vue.nextTick(() => { + const mask = document.querySelector('.el-loading-mask'); + expect(mask.parentNode === document.body).to.true; + vm.loading = false; + document.body.removeChild(mask); + document.body.removeChild(vm.$el); + done(); + }); + }); + + it('fullscreen', done => { + vm = createVue({ + template: ` +
+ `, + + data() { + return { + loading: true + }; + } + }, true); + Vue.nextTick(() => { + const mask = document.querySelector('.el-loading-mask'); + expect(mask.parentNode === document.body).to.true; + expect(mask.classList.contains('is-fullscreen')).to.true; + vm.loading = false; + document.body.removeChild(mask); + document.body.removeChild(vm.$el); + done(); + }); + }); + + it('lock', done => { + vm = createVue({ + template: ` +
+ `, + + data() { + return { + loading: true + }; + } + }, true); + Vue.nextTick(() => { + expect(getStyle(document.body, 'overflow')).to.equal('hidden'); + vm.loading = false; + document.body.removeChild(document.querySelector('.el-loading-mask')); + document.body.removeChild(vm.$el); + done(); + }); + }); + + it('text', done => { + vm = createVue({ + template: ` +
+ `, + + data() { + return { + loading: true + }; + } + }, true); + Vue.nextTick(() => { + const mask = document.querySelector('.el-loading-mask'); + const text = mask.querySelector('.el-loading-text'); + expect(text).to.exist; + expect(text.textContent).to.equal('拼命加载中'); + done(); + }); + }); + + it('customClass', done => { + vm = createVue({ + template: ` +
+ `, + + data() { + return { + loading: true + }; + } + }, true); + Vue.nextTick(() => { + const mask = document.querySelector('.el-loading-mask'); + expect(mask.classList.contains('loading-custom-class')).to.true; + done(); + }); + }); + }); + + describe('as a service', () => { + it('create', () => { + loadingInstance = Loading(); + expect(document.querySelector('.el-loading-mask')).to.exist; + }); + + it('close', () => { + loadingInstance = Loading(); + loadingInstance.close(); + expect(loadingInstance.visible).to.false; + }); + + it('target', done => { + vm = createVue({ + template: ` +
+ ` + }, true); + loadingInstance = Loading({ target: '.loading-container' }); + let mask = document.querySelector('.el-loading-mask'); + let container = document.querySelector('.loading-container'); + expect(mask).to.exist; + expect(mask.parentNode).to.equal(container); + loadingInstance.close(); + setTimeout(() => { + expect(getStyle(container, 'position')).to.equal('relative'); + done(); + }, 200); + }); + + it('body', () => { + vm = createVue({ + template: ` +
+ ` + }, true); + loadingInstance = Loading({ + target: '.loading-container', + body: true + }); + let mask = document.querySelector('.el-loading-mask'); + expect(mask).to.exist; + expect(mask.parentNode).to.equal(document.body); + }); + + it('fullscreen', () => { + loadingInstance = Loading({ fullScreen: true }); + const mask = document.querySelector('.el-loading-mask'); + expect(mask.parentNode).to.equal(document.body); + expect(mask.classList.contains('is-fullscreen')).to.true; + }); + + it('fullscreen singleton', done => { + loadingInstance = Loading({ fullScreen: true }); + setTimeout(() => { + loadingInstance2 = Loading({ fullScreen: true }); + setTimeout(() => { + let masks = document.querySelectorAll('.el-loading-mask'); + expect(masks.length).to.equal(1); + loadingInstance2.close(); + setTimeout(() => { + masks = document.querySelectorAll('.el-loading-mask'); + expect(masks.length).to.equal(0); + done(); + }, 350); + }, 50); + }, 50); + }); + + it('lock', () => { + loadingInstance = Loading({ lock: true }); + expect(getStyle(document.body, 'overflow')).to.equal('hidden'); + }); + + it('text', () => { + loadingInstance = Loading({ text: 'Loading...' }); + const text = document.querySelector('.el-loading-text'); + expect(text).to.exist; + expect(text.textContent).to.equal('Loading...'); + }); + + it('customClass', () => { + loadingInstance = Loading({ customClass: 'el-loading-custom-class' }); + const customClass = document.querySelector('.el-loading-custom-class'); + expect(customClass).to.exist; + }); + }); +}); diff --git a/test/unit/specs/menu.spec.js b/test/unit/specs/menu.spec.js new file mode 100644 index 0000000..e670ff5 --- /dev/null +++ b/test/unit/specs/menu.spec.js @@ -0,0 +1,424 @@ +import { createVue, triggerEvent, destroyVM } from '../util'; + +describe('Menu', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', done => { + vm = createVue({ + template: ` + + 处理中心 + 订单管理 + + ` + }, true); + var item1 = vm.$refs.item1; + var item2 = vm.$refs.item2; + item1.$el.click(); + setTimeout(_ => { + expect(item1.$el.classList.contains('is-active')).to.be.true; + item2.$el.click(); + setTimeout(_ => { + expect(item2.$el.classList.contains('is-active')).to.be.true; + done(); + }, 20); + }, 20); + }); + it('background-color', done => { + vm = createVue({ + template: ` + + 处理中心 + 订单管理 + + ` + }, true); + expect(vm.$el.style.backgroundColor).to.equal('rgb(255, 0, 0)'); + expect(vm.$refs.item1.$el.style.backgroundColor).to.equal('rgb(255, 0, 0)'); + expect(vm.$refs.item1.$el.style.color).to.equal('rgb(0, 0, 0)'); + expect(vm.$refs.item2.$el.style.color).to.equal('rgb(0, 255, 0)'); + triggerEvent(vm.$refs.item1.$el, 'mouseenter'); + setTimeout(_ => { + expect(vm.$refs.item1.$el.style.backgroundColor).to.equal('rgb(204, 0, 0)'); + done(); + }, 20); + }); + it('menu-item click', done => { + vm = createVue({ + template: ` + + 处理中心 + 订单管理 + + `, + methods: { + onMenuItemClick(el) { + expect(el).to.be.equal(vm.$refs.item1); + this.clicksCount = this.clicksCount + 1; + } + }, + data() { + return { + clicksCount: 0 + }; + } + }, true); + var item1 = vm.$refs.item1; + item1.$el.click(); + + setTimeout(_ => { + expect(vm.clicksCount).to.be.equal(1); + done(); + }, 20); + + }); + it('menu-item disabled', done => { + vm = createVue({ + template: ` + + 处理中心 + 订单管理 + + ` + }, true); + expect(vm.$refs.item2.$el.classList.contains('is-active')).to.be.true; + vm.$refs.item1.$el.click(); + setTimeout(_ => { + expect(vm.$refs.item1.$el.classList.contains('is-active')).to.be.false; + done(); + }, 20); + }); + describe('default active', () => { + it('normal active', done => { + vm = createVue({ + template: ` + + 处理中心 + 订单管理 + + ` + }, true); + expect(vm.$refs.item2.$el.classList.contains('is-active')).to.be.true; + vm.$refs.item1.$el.click(); + setTimeout(_ => { + expect(vm.$refs.item1.$el.classList.contains('is-active')).to.be.true; + done(); + }, 20); + }); + it('dynamic active', done => { + vm = createVue({ + template: ` + + active watch处理中心 + active watch订单管理 + + `, + data() { + return { + active: '2' + }; + } + }, true); + setTimeout(_ => { + vm.active = '1'; + setTimeout(_ => { + expect(vm.$refs.item1.$el.classList.contains('is-active')).to.be.true; + done(); + }, 20); + }, 100); + }); + it('vertical submenu item active', done => { + vm = createVue({ + template: ` +
+ + 处理中心 + + + 选项1 + 选项2 + 选项3 + + 订单管理 + +
+ ` + }, true); + expect(vm.$refs.submenuItem2.$el.classList.contains('is-active')).to.be.true; + + setTimeout(_ => { + expect(vm.$refs.submenu.$el.classList.contains('is-opened')).to.be.true; + expect(vm.$refs.submenu.$el.classList.contains('is-active')).to.be.true; + done(); + }, 20); + }); + it('horizontal submenu item active', done => { + vm = createVue({ + template: ` +
+ + 处理中心 + + + 选项1 + 选项2 + 选项3 + + 订单管理 + +
+ ` + }, true); + expect(vm.$refs.submenuItem2.$el.classList.contains('is-active')).to.be.true; + + setTimeout(_ => { + expect(vm.$refs.submenu.$el.classList.contains('is-opened')).to.be.true; + expect(vm.$refs.submenu.$el.classList.contains('is-active')).to.be.true; + done(); + }, 20); + }); + }); + describe('submenu', function() { + it('toggle', done => { + vm = createVue({ + template: ` + + 处理中心 + + + 选项1 + 选项2 + 选项3 + + 订单管理 + + `, + data() { + return { + }; + } + }, true); + var submenuItem2 = vm.$refs.submenuItem2; + var submenu = vm.$refs.submenu; + submenu.$el.querySelector('.el-submenu__title').click(); + setTimeout(_ => { + expect(submenu.$el.classList.contains('is-opened')).to.be.true; + submenuItem2.$el.click(); + setTimeout(_ => { + expect(submenuItem2.$el.classList.contains('is-active')).to.be.true; + submenu.$el.querySelector('.el-submenu__title').click(); + setTimeout(_ => { + expect(submenu.$el.classList.contains('is-opened')).to.not.true; + done(); + }, 20); + }, 20); + }, 20); + }); + it('default opened', done => { + vm = createVue({ + template: ` + + default opened处理中心 + + + 选项1 + 选项2 + 选项3 + + + + 选项1 + 选项2 + 选项3 + + + `, + data() { + return { + defaultOpeneds: ['2', '3'] + }; + } + }, true); + expect(vm.$refs.submenu1.$el.classList.contains('is-opened')).to.be.true; + expect(vm.$refs.submenu2.$el.classList.contains('is-opened')).to.be.true; + vm.defaultOpeneds = ['2']; + setTimeout(_ => { + expect(vm.$refs.submenu1.$el.classList.contains('is-opened')).to.be.true; + expect(vm.$refs.submenu2.$el.classList.contains('is-opened')).to.not.true; + done(); + }, 20); + }); + it('disabled', done => { + vm = createVue({ + template: ` + + 处理中心 + + + 选项1 + 选项2 + 选项3 + + 订单管理 + + ` + }, true); + var submenu = vm.$refs.submenu; + submenu.$el.querySelector('.el-submenu__title').click(); + setTimeout(_ => { + expect(submenu.$el.classList.contains('is-opened')).to.be.false; + done(); + }, 20); + }); + }); + it('unique-opened', done => { + vm = createVue({ + template: ` + + 处理中心 + + + 选项1 + 选项2 + 选项3 + + + + 选项1 + 选项2 + 选项3 + + + `, + data() { + return { + }; + } + }, true); + vm.$refs.submenu2.$el.querySelector('.el-submenu__title').click(); + setTimeout(_ => { + expect(vm.$refs.submenu1.$el.classList.contains('is-opened')).to.not.true; + done(); + }, 20); + }); + it('horizontal mode', done => { + vm = createVue({ + template: ` + + 处理中心 + + + 选项1 + 选项2 + 选项3 + + 订单管理 + + `, + data() { + return { + }; + } + }, true); + expect(vm.$el.classList.contains('el-menu--horizontal')).to.be.true; + var submenu = vm.$refs.submenu; + triggerEvent(submenu.$el, 'mouseenter'); + setTimeout(_ => { + expect(document.body.querySelector('.el-menu--popup').parentElement.style.display).to.not.ok; + done(); + }, 500); + }); + it('menu trigger click', done => { + vm = createVue({ + template: ` + + 处理中心 + + + 选项1 + 选项2 + 选项3 + + 订单管理 + + `, + data() { + return { + }; + } + }, true); + expect(vm.$el.classList.contains('el-menu--horizontal')).to.be.true; + var submenu = vm.$refs.submenu; + var triggerElm = submenu.$el.querySelector('.el-submenu__title'); + + triggerEvent(submenu.$el, 'mouseenter'); + triggerElm.click(); + + setTimeout(_ => { + expect(document.body.querySelector('.el-menu--popup').parentElement.style.display).to.not.ok; + triggerElm.click(); + setTimeout(_ => { + expect(document.body.querySelector('.el-menu--popup').parentElement.style.display).to.be.equal('none'); + done(); + }, 1000); + }, 500); + }); + it('menu group', () => { + vm = createVue({ + template: ` + + + 导航一 + 导航二 + + + + + 选项1 + 选项2 + + + + ` + }, true); + expect(vm.$refs.group1.$el.querySelector('.el-menu-item-group__title').innerText).to.be.equal('分组一'); + }); + it('dynamic menus, issue 9092', done => { + vm = createVue({ + template: ` + + + {{menu.description}} + + + `, + data() { + return { + active: '', + menus: [] + }; + } + }, true); + setTimeout(_ => { + vm.active = '2'; + vm.menus = [ + {name: '1', description: 'happy'}, + {name: '2', description: 'new'}, + {name: '3', description: 'year'} + ]; + setTimeout(_ => { + expect(vm.$el.querySelector('.el-menu-item.is-active').innerText).to.equal('new'); + done(); + }, 20); + }, 100); + }); +}); diff --git a/test/unit/specs/message-box.spec.js b/test/unit/specs/message-box.spec.js new file mode 100644 index 0000000..9e11c71 --- /dev/null +++ b/test/unit/specs/message-box.spec.js @@ -0,0 +1,263 @@ +import MessageBox from 'packages/message-box'; + +describe('MessageBox', () => { + let hasPromise = true; + before(() => { + if (!window.Promise) { + hasPromise = false; + window.Promise = require('es6-promise').Promise; + } + }); + + after(() => { + if (!hasPromise) { + window.Promise = undefined; + } + }); + + afterEach(() => { + const el = document.querySelector('.el-message-box__wrapper'); + if (!el) return; + if (el.parentNode) { + el.parentNode.removeChild(el); + } + MessageBox.close(); + }); + + it('create and close', done => { + MessageBox({ + type: 'success', + title: '消息', + message: '这是一段内容' + }); + setTimeout(() => { + const msgbox = document.querySelector('.el-message-box__wrapper'); + expect(msgbox.__vue__.$parent.visible).to.true; + expect(msgbox.querySelector('.el-message-box__title span').textContent).to.equal('消息'); + expect(msgbox.querySelector('.el-message-box__message') + .querySelector('p').textContent).to.equal('这是一段内容'); + MessageBox.close(); + expect(msgbox.__vue__.$parent.visible).to.false; + done(); + }, 300); + }); + + it('invoke with strings', done => { + MessageBox('消息', '这是一段内容', 'success'); + setTimeout(() => { + expect(document.querySelector('.el-message-box__wrapper')).to.exist; + done(); + }, 300); + }); + + it('custom icon', done => { + MessageBox({ + type: 'warning', + iconClass: 'el-icon-question', + message: '这是一段内容' + }); + setTimeout(() => { + const icon = document.querySelector('.el-message-box__status'); + expect(icon.classList.contains('el-icon-question')).to.true; + done(); + }, 300); + }); + + it('html string', done => { + MessageBox({ + title: 'html string', + dangerouslyUseHTMLString: true, + message: 'html string' + }); + setTimeout(() => { + const message = document.querySelector('.el-message-box__message strong'); + expect(message.textContent).to.equal('html string'); + done(); + }, 300); + }); + + it('distinguish cancel and close', done => { + let msgAction = ''; + MessageBox({ + title: '消息', + message: '这是一段内容', + distinguishCancelAndClose: true + }, action => { + msgAction = action; + }); + setTimeout(() => { + document.querySelector('.el-message-box__close').click(); + setTimeout(() => { + expect(msgAction).to.equal('close'); + done(); + }, 10); + }, 10); + }); + + it('alert', done => { + MessageBox.alert('这是一段内容', { + title: '标题名称', + type: 'warning' + }); + setTimeout(() => { + document.querySelector('.v-modal').click(); + expect(document.querySelector('.el-message-box__wrapper') + .__vue__.$parent.visible).to.true; + expect(document.querySelector('.el-message-box__wrapper') + .__vue__.$parent.type).to.equal('warning'); + done(); + }, 300); + }); + + it('confirm', done => { + MessageBox.confirm('这是一段内容', { + title: '标题名称', + type: 'warning' + }); + setTimeout(() => { + document.querySelector('.el-message-box__wrapper') + .querySelector('.el-button--primary').click(); + expect(document.querySelector('.el-message-box__wrapper') + .__vue__.$parent.visible).to.false; + done(); + }, 200); + }); + + it('prompt', done => { + MessageBox.prompt('这是一段内容', { + title: '标题名称', + inputPattern: /test/, + inputErrorMessage: 'validation failed' + }); + setTimeout(() => { + 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(messageBox.$el.querySelector('.el-message-box__errormsg') + .textContent).to.equal('validation failed'); + done(); + }, 100); + }, 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', () => { + it('returns a string', done => { + const validator = value => { + if (value !== 'test') return 'wrong'; + return true; + }; + MessageBox.prompt('这是一段内容', { + title: '标题名称', + inputValidator: validator + }); + setTimeout(() => { + const messageBox = document.querySelector('.el-message-box__wrapper').__vue__.$parent; + messageBox.inputValue = 'no'; + setTimeout(() => { + expect(document.querySelector('.el-message-box__errormsg') + .textContent).to.equal('wrong'); + messageBox.inputValue = 'test'; + setTimeout(() => { + expect(document.querySelector('.el-message-box__errormsg') + .textContent).to.equal(''); + done(); + }, 100); + }, 100); + }, 200); + }); + + it('returns false', done => { + const validator = value => false; + MessageBox.prompt('这是一段内容', { + title: '标题名称', + inputValidator: validator + }); + setTimeout(() => { + const messageBox = document.querySelector('.el-message-box__wrapper').__vue__.$parent; + messageBox.inputValue = 'no'; + setTimeout(() => { + expect(document.querySelector('.el-message-box__errormsg') + .textContent).to.equal('输入的数据不合法!'); + done(); + }, 100); + }, 200); + }); + }); + + it('callback', done => { + let msgAction = ''; + MessageBox({ + title: '消息', + message: '这是一段内容' + }, action => { + msgAction = action; + }); + setTimeout(() => { + document.querySelector('.el-message-box__close').click(); + setTimeout(() => { + expect(msgAction).to.equal('cancel'); + done(); + }, 10); + }, 10); + }); + + it('beforeClose', done => { + let msgAction = ''; + MessageBox({ + title: '消息', + message: '这是一段内容', + beforeClose: (action, instance) => { + instance.close(); + } + }, action => { + msgAction = action; + }); + setTimeout(() => { + document.querySelector('.el-message-box__wrapper .el-button--primary').click(); + setTimeout(() => { + expect(msgAction).to.equal('confirm'); + done(); + }, 10); + }, 10); + }); + + describe('promise', () => { + it('resolve', done => { + MessageBox.confirm('此操作将永久删除该文件, 是否继续?', '提示') + .then(action => { + expect(action).to.equal('confirm'); + done(); + }); + setTimeout(() => { + document.querySelector('.el-message-box__wrapper .el-button--primary').click(); + }, 50); + }); + + it('reject', done => { + MessageBox.confirm('此操作将永久删除该文件, 是否继续?', '提示') + .catch(action => { + expect(action).to.equal('cancel'); + done(); + }); + setTimeout(() => { + document.querySelector('.el-message-box__wrapper .el-button').click(); + }, 50); + }); + }); +}); diff --git a/test/unit/specs/message.spec.js b/test/unit/specs/message.spec.js new file mode 100644 index 0000000..69e37f4 --- /dev/null +++ b/test/unit/specs/message.spec.js @@ -0,0 +1,115 @@ +import { triggerEvent } from '../util'; +import Message from 'packages/message'; + +describe('Message', () => { + afterEach(() => { + const el = document.querySelector('.el-message'); + if (!el) return; + if (el.parentNode) { + el.parentNode.removeChild(el); + } + if (el.__vue__) { + el.__vue__.$destroy(); + } + }); + + it('automatically close', done => { + Message({ + message: '灰风', + duration: 500 + }); + const message = document.querySelector('.el-message__content'); + expect(document.querySelector('.el-message')).to.exist; + expect(message.textContent).to.equal('灰风'); + setTimeout(() => { + expect(document.querySelector('.el-message')).to.not.exist; + done(); + }, 1000); + }); + + it('manually close', done => { + Message({ + message: '夏天', + showClose: true + }); + setTimeout(() => { + document.querySelector('.el-message__closeBtn').click(); + setTimeout(() => { + expect(document.querySelector('.el-message')).to.not.exist; + done(); + }, 500); + }, 500); + }); + + it('custom icon', done => { + Message({ + message: '夏天', + iconClass: 'el-icon-close' + }); + setTimeout(() => { + const icon = document.querySelector('.el-message i'); + expect(icon.classList.contains('el-icon-close')).to.true; + done(); + }, 500); + }); + + it('html string', () => { + Message({ + message: '夏天', + dangerouslyUseHTMLString: true + }); + const message = document.querySelector('.el-message strong'); + expect(message.textContent).to.equal('夏天'); + }); + + it('close all', done => { + Message({ + message: '夏天', + duration: 0 + }); + Message({ + message: '淑女', + duration: 0 + }); + setTimeout(() => { + Message.closeAll(); + setTimeout(() => { + expect(document.querySelector('.el-message')).to.not.exist; + done(); + }, 500); + }, 500); + }); + + it('create', () => { + Message('娜梅莉亚'); + expect(document.querySelector('.el-message')).to.exist; + }); + + it('invoke with type', () => { + Message.success('毛毛狗'); + expect(document.querySelector('.el-message').__vue__.type).to.equal('success'); + }); + + it('center', () => { + Message({ + message: '夏天', + center: true, + duration: 0 + }); + expect(document.querySelector('.el-message').classList.contains('is-center')).to.true; + }); + + it('reset timer', done => { + Message({ + message: '白灵', + duration: 1000 + }); + setTimeout(() => { + triggerEvent(document.querySelector('.el-message'), 'mouseenter'); + setTimeout(() => { + expect(document.querySelector('.el-message')).to.exist; + done(); + }, 700); + }, 500); + }); +}); diff --git a/test/unit/specs/mixin.vue-popup.spec.js b/test/unit/specs/mixin.vue-popup.spec.js new file mode 100644 index 0000000..5e11d5d --- /dev/null +++ b/test/unit/specs/mixin.vue-popup.spec.js @@ -0,0 +1,74 @@ +import VuePopup from 'element-ui/src/utils/popup'; +import { createTest, destroyVM } from '../util'; + +const Popup = Object.assign({}, VuePopup, { + render(h) { + return h('div'); + }, + created() { + this.rendered = true; + } +}); + +describe('Mixin:vue-popup', () => { + let vm; + before(() => { + const modals = document.querySelectorAll('.v-modal'); + [].forEach.call(modals, modal => { + modal && + modal.parentNode && + modal.parentNode.removeChild(modal); + }); + }); + afterEach(() => { + vm.close && vm.close(); + destroyVM(vm); + const modal = document.querySelector('.v-modal'); + modal && + modal.parentNode && + modal.parentNode.removeChild(modal); + }); + + it('show modal', () => { + vm = createTest(Popup); + vm.open(); + expect(document.querySelector('.v-modal')).to.not.exist; + vm.close(); + destroyVM(vm); + vm = createTest(Popup, { modal: true }); + vm.open(); + expect(document.querySelector('.v-modal')).to.exist; + }); + + it('custom modal class', () => { + vm = createTest(Popup, { modal: true, modalClass: 'custom-class' }); + vm.open(); + expect(document.querySelector('.v-modal').classList.contains('custom-class')).to.true; + }); + + it('lock scroll', done => { + vm = createTest(Popup, { modal: true }); + vm.open(); + expect(document.body.classList.contains('el-popup-parent--hidden')).to.be.true; + vm.close(); + destroyVM(vm); + setTimeout(() => { + vm = createTest(Popup, { modal: true, lockScroll: false }); + vm.open(); + expect(document.body.classList.contains('el-popup-parent--hidden')).to.be.false; + done(); + }, 200); + }); + + it('z-index should increase', () => { + vm = createTest(Popup, { modal: true }); + vm.open(); + const zIndex1 = document.querySelector('.v-modal').style.zIndex; + vm.close(); + destroyVM(vm); + vm = createTest(Popup, { modal: true }); + vm.open(); + const zIndex2 = document.querySelector('.v-modal').style.zIndex; + expect(zIndex2 > zIndex1).to.true; + }); +}); diff --git a/test/unit/specs/notification.spec.js b/test/unit/specs/notification.spec.js new file mode 100644 index 0000000..1a4306c --- /dev/null +++ b/test/unit/specs/notification.spec.js @@ -0,0 +1,121 @@ +import Vue from 'vue'; +import { triggerEvent } from '../util'; +import Notification from 'packages/notification'; + +describe('Notification', () => { + afterEach(() => { + const el = document.querySelector('.el-notification'); + if (!el) return; + if (el.parentNode) { + el.parentNode.removeChild(el); + } + if (el.__vue__) { + el.__vue__.$destroy(); + } + }); + + it('automatically close', done => { + Notification({ + message: '玻璃蜡烛', + duration: 500 + }); + expect(document.querySelector('.el-notification')).to.exist; + setTimeout(() => { + expect(document.querySelector('.el-notification')).to.not.exist; + done(); + }, 1000); + }); + + it('manually close', done => { + Notification({ + message: '苍白母马' + }); + setTimeout(() => { + document.querySelector('.el-notification__closeBtn').click(); + setTimeout(() => { + expect(document.querySelector('.el-notification')).to.not.exist; + done(); + }, 500); + }, 500); + }); + + it('create', () => { + Notification({ + title: '狮子', + message: '狮鹫', + duration: 0 + }); + const group = document.querySelector('.el-notification__group'); + const title = group.querySelector('.el-notification__title'); + const message = group.querySelector('.el-notification__content p'); + expect(document.querySelector('.el-notification')).to.exist; + expect(title.textContent).to.equal('狮子'); + expect(message.textContent).to.equal('狮鹫'); + }); + + it('html string as message', () => { + Notification({ + title: '狮子', + message: '狮鹫', + dangerouslyUseHTMLString: true, + duration: 0 + }); + const message = document.querySelector('.el-notification__content strong'); + expect(message.textContent).to.equal('狮鹫'); + }); + + it('create by vnode', () => { + const fakeVM = new Vue(); + const h = fakeVM.$createElement; + + Notification({ + message: h('p', { style: { color: 'red' } }, '大美兴,川普王') + }); + const group = document.querySelector('.el-notification__group'); + const message = group.querySelector('.el-notification__content'); + + expect(message.innerHTML).to.equal('

大美兴,川普王

'); + }); + + it('alias by vnode', () => { + const fakeVM = new Vue(); + const h = fakeVM.$createElement; + + Notification.error(h('p', { style: { color: 'green' } }, '+1s')); + const group = document.querySelector('.el-notification__group'); + const message = group.querySelector('.el-notification__content'); + + expect(message.innerHTML).to.equal('

+1s

'); + }); + + it('invoke with type', () => { + Notification.success('太阳之子'); + expect(document.querySelector('.el-notification').__vue__.type).to.equal('success'); + }); + + it('reset timer', done => { + Notification({ + message: '芳香总管', + duration: 1000 + }); + setTimeout(() => { + triggerEvent(document.querySelector('.el-notification'), 'mouseenter'); + setTimeout(() => { + triggerEvent(document.querySelector('.el-notification'), 'mouseleave'); + expect(document.querySelector('.el-notification')).to.exist; + done(); + }, 700); + }, 500); + }); + + it('no close button', done => { + Notification({ + message: 'Hello', + showClose: false + }); + setTimeout(() => { + expect(document.querySelector('.el-notification__closeBtn')).to.not.exist; + done(); + }, 500); + }); +}); diff --git a/test/unit/specs/page-header.spec.js b/test/unit/specs/page-header.spec.js new file mode 100644 index 0000000..b0c31cd --- /dev/null +++ b/test/unit/specs/page-header.spec.js @@ -0,0 +1,24 @@ +import { createVue, destroyVM, waitImmediate } from '../util'; +import PageHeader from 'packages/page-header'; + +describe('PageHeader', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('render well and trigger back event', async() => { + vm = createVue(PageHeader, { + content: 'content' + }); + expect(vm.$el).to.exist; + const spy = sinon.spy(); + vm.$on('back', spy); + vm.$el.querySelector('.el-page-header__left').click(); + + await waitImmediate(); + + expect(spy.calledOnce).to.be.true; + }); +}); + diff --git a/test/unit/specs/pagination.spec.js b/test/unit/specs/pagination.spec.js new file mode 100644 index 0000000..d093085 --- /dev/null +++ b/test/unit/specs/pagination.spec.js @@ -0,0 +1,491 @@ +import { createTest, createVue, triggerEvent, destroyVM } from '../util'; +import Pagination from 'packages/pagination'; + +describe('Pagination', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + it('create', () => { + vm = createTest(Pagination); + const elm = vm.$el; + // prev + expect(elm.querySelector('button.btn-prev')).to.exist; + // pager + expect(elm.querySelector('ul.el-pager')).to.exist; + // next + expect(elm.querySelector('button.btn-next')).to.exist; + // jumper + expect(elm.querySelector('.el-pagination__jump')).to.exist; + // -> + expect(elm.querySelector('.el-pagination__rightwrapper')).to.exist; + }); + + it('set layout', () => { + vm = createTest(Pagination, { + layout: 'prev, pager, next' + }); + const elm = vm.$el; + // prev + expect(elm.querySelector('button.btn-prev')).to.exist; + // pager + expect(elm.querySelector('ul.el-pager')).to.exist; + // next + expect(elm.querySelector('button.btn-next')).to.exist; + // not found jumper + expect(elm.querySelector('.el-pagination__jump')).to.not.exist; + // not found -> + expect(elm.querySelector('.el-pagination__rightwrapper')).to.not.exist; + // not found total + expect(elm.querySelector('.el-pagination__total')).to.not.exist; + }); + + it('layout: all in right, need clear float', () => { + vm = createTest(Pagination, { + layout: '->, prev, pager, next', + total: 100 + }, true); + const elm = vm.$el; + let right_div = elm.querySelector('.el-pagination__rightwrapper'); + expect(elm.clientHeight > 0 && right_div.clientHeight > 0).to.equal(true); + // elm 将来 padding 可能会变化, 所以使用 >= 来判定 + expect(elm.clientHeight >= right_div.clientHeight).to.equal(true); + }); + + it('custom slot', () => { + vm = createVue({ + template: ` + + slot test + + ` + }); + expect(vm.$el.querySelector('.slot-test')).to.exist; + }); + + it('small', () => { + vm = createTest(Pagination, { + small: true + }); + expect(vm.$el.classList.contains('el-pagination--small')).to.true; + }); + + it('pageSize', () => { + vm = createTest(Pagination, { + pageSize: 25, + total: 100 + }); + + expect(vm.$el.querySelectorAll('li.number')).to.length(4); + }); + + it('pageSize: NaN', () => { + vm = createTest(Pagination, { + pageSize: NaN, + total: 100 + }); + + const pagers = vm.$el.querySelectorAll('li.number'); + expect(pagers).to.length(7); + }); + + it('pageCount', () => { + const vm = createTest(Pagination, { + pageSize: 25, + pageCount: 4 + }); + + expect(vm.$el.querySelectorAll('li.number')).to.length(4); + }); + + it('pagerCount', () => { + const vm = createTest(Pagination, { + pageSize: 25, + total: 1000, + pagerCount: 21 + }); + + expect(vm.$el.querySelectorAll('li.number')).to.length(21); + }); + + it('will work without total & page-count', (done) => { + const vm = createTest(Pagination, { + pageSize: 25, + currentPage: 2 + }); + + vm.$el.querySelector('.btn-prev').click(); + + setTimeout(() => { + vm.internalCurrentPage.should.be.equal(1); + + vm.$el.querySelector('.btn-prev').click(); + vm.internalCurrentPage.should.be.equal(1); + + done(); + }, 20); + }); + + it('currentPage', () => { + vm = createTest(Pagination, { + pageSize: 20, + total: 200, + currentPage: 3 + }); + + expect(vm.$el.querySelector('li.number.active')).to.have.property('textContent').to.equal('3'); + }); + + it('currentPage: NaN', () => { + vm = createTest(Pagination, { + pageSize: 20, + total: 200, + currentPage: NaN + }); + + expect(vm.$el.querySelector('li.number.active')).to.have.property('textContent').to.equal('1'); + expect(vm.$el.querySelectorAll('li.number')).to.length(7); + }); + + it('set currentPage & total', (done) => { + vm = createVue({ + template: ` + + `, + + methods: { + handleChange(val) { + this.currentPage = val; + this.page = val; + }, + resetTotal() { + this.total = 30; + this.currentPage = 1; + } + }, + + data() { + return { + currentPage: 10 + }; + } + }, true); + + expect(vm.$el.querySelector('li.number.active')).to.have.property('textContent').to.equal('10'); + vm.resetTotal(); + setTimeout(() => { + expect(vm.$el.querySelector('li.number.active')).to.have.property('textContent').to.equal('1'); + done(); + }, 50); + }); + + it('pageSizes', () => { + vm = createTest(Pagination, { + pageSizes: [10, 15, 35, 50], + pageSize: 35, + total: 1000, + layout: 'sizes, prev, pager, next' + }); + + expect(vm.$el.querySelector('.el-select-dropdown__item.selected')).to.property('textContent').include('35'); + expect([].slice.call(vm.$el.querySelectorAll('.el-select-dropdown__item')) + .map(node => parseInt(node.textContent, 10))) + .to.deep.equal([10, 15, 35, 50]); + }); + + it('pageSizes:not found pageSize', () => { + vm = createTest(Pagination, { + pageSizes: [10, 15, 35, 50], + pageSize: 24, + total: 1000, + layout: 'sizes, prev, pager, next' + }); + + expect(vm.$el.querySelector('.el-select-dropdown__item.selected')).to.property('textContent').include('10'); + }); + + it('layout is empty', () => { + vm = createTest(Pagination, { + layout: '' + }); + + expect(vm.$el.textContent).to.empty; + }); + + it('jumper: change value', (done) => { + vm = createVue({ + template: ` + + `, + + methods: { + handleChange(val) { + this.page = val; + } + }, + + data() { + return { + page: 1, + inputer: null + }; + }, + + mounted() { + this.inputer = this.$children[0].$children[1].$children[0]; + } + }, true); + const input = vm.inputer; + const changeValue = (value) => { + input.$emit('input', value); + input.$emit('change', value); + }; + + changeValue(1); + setTimeout(() => { + expect(input.value).to.equal(1); + // 多次输入不在min-max区间内的数字 + changeValue(0); + setTimeout(() => { + expect(input.value).to.equal(1); + changeValue(0); + setTimeout(() => { + 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); + }); + + it('event:current-change', (done) => { + vm = createVue({ + template: ` + + `, + + data() { + return { change: false }; + } + }); + const next = vm.$el.querySelector('button.btn-next'); + const prev = vm.$el.querySelector('button.btn-prev'); + + expect(vm.change).to.false; + // click 9 + let count = 9; + while (--count) { + next.click(); + } + + prev.click(); + setTimeout(() => { + expect(vm.change).to.true; + done(); + }, 50); + }); + + it('event:current-change after current page is manually updated', (done) => { + vm = createVue({ + template: ` + + `, + + data() { + return { + emitCount: 0, + currentPage: 1 + }; + } + }); + const next = vm.$el.querySelector('button.btn-next'); + next.click(); + setTimeout(() => { + expect(vm.emitCount).to.equal(1); + vm.currentPage = 1; + setTimeout(() => { + expect(vm.emitCount).to.equal(1); + next.click(); + setTimeout(() => { + expect(vm.emitCount).to.equal(2); + done(); + }, 50); + }, 50); + }, 50); + }); + + it('event:size-change', done => { + vm = createVue({ + template: ` + + `, + + data() { + return { trigger: false }; + } + }, true); + + expect(vm.trigger).to.false; + + setTimeout(_ => { + vm.$el.querySelectorAll('li.el-select-dropdown__item')[1].click(); + setTimeout(_ => { + expect(vm.trigger).to.true; + done(); + }, 50); + }, 50); + }); + + it('event: prev and next click', done => { + vm = createVue({ + template: ` + + `, + + data() { + return { trigger: false }; + } + }, true); + const prev = vm.$el.querySelector('.btn-prev'); + const next = vm.$el.querySelector('.btn-next'); + prev.click(); + setTimeout(_ => { + expect(vm.trigger).to.false; + next.click(); + setTimeout(_ => { + expect(vm.trigger).to.true; + done(); + }, 50); + }, 50); + }); + + it('pageSize > total', () => { + vm = createVue({ + template: ` + + `, + + methods: { + handleChange(val) { + this.page = val; + } + }, + + data() { + return { page: 1 }; + } + }); + const input = vm.$el.querySelector('.el-pagination__jump input'); + + input.value = 2; + triggerEvent(input, 'change'); + expect(vm.page).to.equal(1); + + input.value = '我好帅'; + triggerEvent(input, 'change'); + expect(vm.page).to.equal(1); + }); + + it('hideOnSinglePage', () => { + vm = createVue({ + template: ` + + ` + }); + expect(vm.$el.nodeType).to.be.equal(window.Node.COMMENT_NODE); + }); + + describe('click pager', () => { + it('click ul', () => { + vm = createTest(Pagination, { + total: 1000 + }, true); + + vm.$el.querySelector('.el-pager').click(); + expect(vm.internalCurrentPage).to.equal(1); + }); + + it('click li', () => { + vm = createTest(Pagination, { + total: 1000 + }, true); + + vm.$el.querySelectorAll('.el-pager li.number')[1].click(); + expect(vm.internalCurrentPage).to.equal(2); + }); + + it('click next icon-more', () => { + vm = createTest(Pagination, { + total: 1000 + }, true); + + vm.$el.querySelector('.el-pager .more').click(); + expect(vm.internalCurrentPage).to.equal(6); + }); + + it('click prev icon-more', done => { + vm = createTest(Pagination, { + total: 1000 + }, true); + + vm.$el.querySelector('.btn-quicknext.more').click(); + setTimeout(_ => { + expect(vm.$el.querySelector('.btn-quickprev.more')).to.exist; + vm.$el.querySelector('.btn-quickprev.more').click(); + expect(vm.internalCurrentPage).to.equal(1); + done(); + }, 50); + }); + + it('click last page', done => { + vm = createTest(Pagination, { + total: 1000 + }, true); + const nodes = vm.$el.querySelectorAll('li.number'); + + nodes[nodes.length - 1].click(); + setTimeout(_ => { + expect(vm.$el.querySelector('.btn-quickprev.more')).to.exist; + expect(vm.$el.querySelector('.btn-quicknext.more')).to.not.exist; + done(); + }, 50); + }); + }); +}); diff --git a/test/unit/specs/popconfirm.spec.js b/test/unit/specs/popconfirm.spec.js new file mode 100644 index 0000000..a956513 --- /dev/null +++ b/test/unit/specs/popconfirm.spec.js @@ -0,0 +1,29 @@ +import { createVue, destroyVM } from '../util'; + +describe('Popconfirm', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + describe('trigger', () => { + const createVM = () => { + return createVue(` +
+ + + +
+ `, true); + }; + it('click', () => { + vm = createVM(); + vm.$el.querySelector('button').click(); + document.body.click(); + expect(document.body.querySelector('.el-popconfirm__action').style.display).to.equal(''); + }); + }); + +}); diff --git a/test/unit/specs/popover.spec.js b/test/unit/specs/popover.spec.js new file mode 100644 index 0000000..a1d4e91 --- /dev/null +++ b/test/unit/specs/popover.spec.js @@ -0,0 +1,309 @@ +import { createVue, triggerEvent, createTest, destroyVM, wait } from '../util'; +import Popover from 'packages/popover'; + +describe('Popover', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + describe('trigger', () => { + const createVM = (trigger) => { + return createVue(` +
+ + + +
+ `, true); + }; + + it('click', () => { + vm = createVM('click'); + const compo = vm.$refs.popover; + + vm.$el.querySelector('button').click(); + expect(compo.showPopper).to.true; + document.body.click(); + expect(compo.showPopper).to.false; + }); + + it('hover', done => { + vm = createVM('hover'); + const compo = vm.$refs.popover; + const button = vm.$el.querySelector('button'); + + triggerEvent(button, 'mouseenter'); + expect(compo.showPopper).to.true; + triggerEvent(button, 'mouseleave'); + setTimeout(_ => { + expect(compo.showPopper).to.false; + done(); + }, 250); // 代码里是 200ms + }); + + it('manual', done => { + vm = createVM('manual'); + const compo = vm.$refs.popover; + const button = vm.$el.querySelector('button'); + + triggerEvent(button, 'mouseenter'); + expect(compo.showPopper).to.false; + triggerEvent(button, 'mouseleave'); + setTimeout(_ => { + expect(compo.showPopper).to.false; + done(); + }, 250); // 代码里是 200ms + }); + + it('focus input in children node', () => { + vm = createVue(` +
+ +
+ +
+
+
+ `, true); + const compo = vm.$refs.popover; + const input = vm.$el.querySelector('input'); + + input.focus(); + expect(compo.showPopper).to.true; + input.blur(); + expect(compo.showPopper).to.false; + }); + + it('focus textarea in children node', () => { + vm = createVue(` +
+ +
+ +
+
+
+ `, true); + const compo = vm.$refs.popover; + const textarea = vm.$el.querySelector('textarea'); + + textarea.focus(); + expect(compo.showPopper).to.true; + textarea.blur(); + expect(compo.showPopper).to.false; + }); + + it('focus input', () => { + vm = createVue(` +
+ + + +
+ `, true); + const compo = vm.$refs.popover; + const input = vm.$el.querySelector('input'); + + input.focus(); + expect(compo.showPopper).to.true; + input.blur(); + expect(compo.showPopper).to.false; + }); + + it('focus button', () => { + vm = createVM('focus'); + const compo = vm.$refs.popover; + const button = vm.$el.querySelector('button'); + + triggerEvent(button, 'mousedown'); + expect(compo.showPopper).to.true; + triggerEvent(button, 'mouseup'); + expect(compo.showPopper).to.false; + }); + }); + + describe('create by directive', () => { + const vm = createVue({ + template: ` +
+ + + +
+ `, + + directives: { + Popover: Popover.directive + } + }, true); + const compo = vm.$refs.popover1; + + it('render', () => { + expect(vm.$el.querySelector('.el-popover')).to.have.deep.property('textContent').include('content'); + }); + + it('triggering click', done => { + vm.$el.querySelector('button').click(); + expect(compo.popperElm).to.not.exist; + vm.$nextTick(_ => { + const popperElm = compo.popperElm; + expect(getComputedStyle(popperElm).display).to.not.equal('none'); + done(); + }); + }); + + it('click outside', () => { + document.body.click(); + expect(compo.showPopper).to.false; + }); + }); + + describe('create by slot', () => { + const vm = createVue(` +
+ + + +
+ `, true); + const compo = vm.$refs.popover; + + it('render', () => { + expect(vm.$el.querySelector('.el-popover')).to.have.deep.property('textContent').include('content'); + }); + + it('triggering click', done => { + vm.$el.querySelector('button').click(); + expect(compo.popperElm).to.not.exist; + vm.$nextTick(_ => { + const popperElm = compo.popperElm; + expect(getComputedStyle(popperElm).display).to.not.equal('none'); + done(); + }); + }); + + it('click outside', () => { + document.body.click(); + expect(compo.showPopper).to.false; + }); + }); + + it('show/hide events', done => { + vm = createVue({ + template: ` +
+ + + +
+ `, + + methods: { + handleShow() { + this.trigger = true; + }, + handleHide() { + this.trigger = false; + } + }, + + data() { + return { + trigger: false + }; + } + }, true); + + vm.$el.querySelector('button').click(); + setTimeout(_ => { + expect(vm.trigger).to.true; + document.body.click(); + setTimeout(_ => { + expect(vm.trigger).to.false; + done(); + }, 50); + }, 50); + }); + + describe('open/close delays', () => { + it('100ms open / instant close', async() => { + vm = createVue(` +
+ + + +
+ `, true); + const compo = vm.$refs.popover; + const button = vm.$el.querySelector('button'); + + triggerEvent(button, 'mouseenter'); + expect(compo.showPopper).to.false; + await wait(150); + expect(compo.showPopper).to.true; + triggerEvent(button, 'mouseleave'); + expect(compo.showPopper).to.false; + }); + + it('instant open / 100ms close', async() => { + vm = createVue(` +
+ + + +
+ `, true); + const compo = vm.$refs.popover; + const button = vm.$el.querySelector('button'); + + triggerEvent(button, 'mouseenter'); + expect(compo.showPopper).to.true; + triggerEvent(button, 'mouseleave'); + expect(compo.showPopper).to.true; + await wait(150); + expect(compo.showPopper).to.false; + }); + }); + + it('destroy event', () => { + vm = createTest(Popover, { + reference: document.createElement('div'), + popper: document.createElement('div') + }); + expect(() => vm.$destroy(true)).not.throw(); + }); +}); diff --git a/test/unit/specs/progress.spec.js b/test/unit/specs/progress.spec.js new file mode 100644 index 0000000..e1dcfef --- /dev/null +++ b/test/unit/specs/progress.spec.js @@ -0,0 +1,191 @@ +import { createVue, destroyVM, waitImmediate } from '../util'; + +describe('Progress', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createVue({ + template: ` +
+ + + +
+ ` + }, true); + expect(vm.$refs.percent0.$el.querySelector('.el-progress__text').innerText).to.be.equal('0%'); + expect(vm.$refs.percent0.$el.querySelector('.el-progress-bar__inner').style.width).to.be.equal('0%'); + + expect(vm.$refs.percent50.$el.querySelector('.el-progress__text').innerText).to.be.equal('50%'); + expect(vm.$refs.percent50.$el.querySelector('.el-progress-bar__inner').style.width).to.be.equal('50%'); + + expect(vm.$refs.percent100.$el.querySelector('.el-progress__text').innerText).to.be.equal('100%'); + expect(vm.$refs.percent100.$el.querySelector('.el-progress-bar__inner').style.width).to.be.equal('100%'); + }); + it('status', () => { + vm = createVue({ + template: ` +
+ + + + +
+ ` + }, true); + expect(vm.$refs.lineSuccess.$el.classList.contains('is-success')).to.be.true; + expect(vm.$refs.lineSuccess.$el.querySelector('.el-progress__text .el-icon-circle-check')).to.be.exist; + expect(vm.$refs.lineException.$el.classList.contains('is-exception')).to.be.true; + expect(vm.$refs.lineException.$el.querySelector('.el-progress__text .el-icon-circle-close')).to.be.exist; + + expect(vm.$refs.circleSuccess.$el.classList.contains('is-success')).to.be.true; + expect(vm.$refs.circleSuccess.$el.querySelector('.el-progress__text .el-icon-check')).to.be.exist; + expect(vm.$refs.circleException.$el.classList.contains('is-exception')).to.be.true; + expect(vm.$refs.circleException.$el.querySelector('.el-progress__text .el-icon-close')).to.be.exist; + }); + it('text inside', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.classList.contains('el-progress--text-inside')).to.be.true; + }); + it('stroke width', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.querySelector('.el-progress-bar__outer').style.height).to.be.equal('8px'); + }); + it('show text', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.querySelector('.el-progress__text')).to.not.exist; + }); + it('circle', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.classList.contains('el-progress--circle')).to.be.true; + }); + it('dashboard', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.classList.contains('el-progress--dashboard')).to.be.true; + }); + it('width', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.querySelector('.el-progress-circle').style.height).to.be.equal('120px'); + expect(vm.$el.querySelector('.el-progress-circle').style.width).to.be.equal('120px'); + }); + it('should work with stroke-width', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.querySelector('.el-progress-bar__innerText').offsetTop).to.be.equal(12); + }); + it('color', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(0, 0, 0)'); + }); + it('color is function', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + percentage: 50 + }; + }, + methods: { + customColor(percentage) { + if (percentage > 50) { + return '#13ce66'; + } else { + return '#20a0ff'; + } + }, + increase() { + this.percentage = 60; + } + } + }, true); + + expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(32, 160, 255)'); + vm.increase(); + + await waitImmediate(); + expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(19, 206, 102)'); + }); + + it('color is array', async() => { + vm = createVue({ + template: ` + + `, + data() { + return { + percentage: 50, + colors: [ + {color: '#f56c6c', percentage: 20}, + {color: '#e6a23c', percentage: 40}, + {color: '#20a0ff', percentage: 60}, + {color: '#13ce66', percentage: 80}, + {color: '#6f7ad3', percentage: 100} + ] + }; + }, + methods: { + increase() { + this.percentage = 70; + } + } + }, true); + + // #20a0ff + expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(32, 160, 255)'); + + vm.increase(); + await waitImmediate(); + // #13ce66 + expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(19, 206, 102)'); + }); + + it('format content', () => { + vm = createVue({ + template: ` + + `, + methods: { + format(percentage) { + return `占比${percentage}%`; + } + } + }, true); + expect(vm.$el.querySelector('.el-progress__text').innerHTML).to.equal('占比50%'); + }); +}); diff --git a/test/unit/specs/radio.spec.js b/test/unit/specs/radio.spec.js new file mode 100644 index 0000000..5d8fa37 --- /dev/null +++ b/test/unit/specs/radio.spec.js @@ -0,0 +1,425 @@ +import { createVue, destroyVM, triggerKeyDown } from '../util'; + +describe('Radio', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + radio: '' + }; + } + }, true); + let radioElm = vm.$el; + expect(radioElm.classList.contains('el-radio')).to.be.true; + radioElm.click(); + setTimeout(_ => { + expect(radioElm.querySelector('.is-checked')).to.be.ok; + done(); + }, 10); + }); + it('disabled', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + radio: '' + }; + } + }, true); + let radioElm = vm.$el; + radioElm.click(); + setTimeout(_ => { + expect(vm.radio === '').to.be.true; + expect(radioElm.querySelector('.is-disabled')).to.be.ok; + done(); + }, 10); + }); + it('border', () => { + vm = createVue({ + template: ` + + + `, + data() { + return { + radio: '' + }; + } + }, true); + let radioElm = vm.$el; + expect(radioElm.classList.contains('is-bordered')).to.be.true; + }); + it('change event', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + radio: '', + data: '' + }; + }, + methods: { + handleChange(val) { + this.data = val; + } + } + }, true); + let radioElm = vm.$el; + radioElm.click(); + setTimeout(_ => { + expect(vm.data).to.equal('3'); + done(); + }, 10); + }); + it('change event only triggers on user input', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { + radio: '', + data: '' + }; + }, + methods: { + handleChange(val) { + this.data = val; + } + } + }, true); + vm.radio = '3'; + setTimeout(_ => { + expect(vm.data).to.equal(''); + done(); + }, 10); + }); + describe('Radio group', () => { + it('create', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + data() { + return { + radio: 3 + }; + } + }, true); + setTimeout(_ => { + expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.ok; + let radioElm = vm.$refs.radio2.$el; + radioElm.click(); + setTimeout(_ => { + expect(radioElm.querySelector('.is-checked')).to.be.ok; + expect(vm.radio === 6).to.be.true; + done(); + }, 10); + }, 50); + }); + it('disabled', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + data() { + return { + radio: 3 + }; + } + }, true); + let radio2 = vm.$refs.radio2; + expect(vm.$el.querySelectorAll('label.is-disabled').length).to.be.equal(3); + expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.exist; + radio2.$el.click(); + setTimeout(_ => { + expect(vm.radio === 3).to.be.true; + expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.exist; + done(); + }, 10); + }); + it('change event', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + methods: { + onChange(val) { + this.data = val; + } + }, + data() { + return { + radio: 3, + data: 0 + }; + } + }, true); + let radio2 = vm.$refs.radio2; + radio2.$el.click(); + setTimeout(_ => { + expect(vm.data).to.equal(6); + done(); + }, 10); + }); + it('change event only triggers on user input', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + methods: { + onChange(val) { + this.data = val; + } + }, + data() { + return { + radio: 3, + data: 0 + }; + } + }, true); + vm.radio = 6; + setTimeout(_ => { + expect(vm.data).to.equal(0); + done(); + }, 10); + }); + it('disabled when children is radio button', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + data() { + return { + radio: 3 + }; + } + }, true); + let radio2 = vm.$refs.radio2; + expect(vm.$el.querySelectorAll('.is-disabled').length).to.be.equal(3); + expect(vm.$refs.radio1.$el.classList.contains('is-active')).to.be.true; + radio2.$el.click(); + setTimeout(_ => { + expect(vm.radio === 3).to.be.true; + expect(vm.$refs.radio1.$el.classList.contains('is-active')).to.be.true; + done(); + }, 10); + }); + it('keyboard event', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + data() { + return { + radio: 6 + }; + } + }, true); + + expect(vm.radio).to.be.equal(6); + vm.$nextTick(() => { + triggerKeyDown(vm.$refs.radio2.$el, 37); + expect(vm.radio).to.be.equal(3); + + triggerKeyDown(vm.$refs.radio1.$el, 37); + expect(vm.radio).to.be.equal(9); + + vm.$nextTick(() => { + triggerKeyDown(vm.$refs.radio3.$el, 39); + expect(vm.radio).to.be.equal(3); + + triggerKeyDown(vm.$refs.radio1.$el, 39); + expect(vm.radio).to.be.equal(6); + + vm.$nextTick(() => { + triggerKeyDown(vm.$refs.radio1.$el, 13); + expect(vm.radio).to.be.equal(6); + + done(); + }); + }); + }); + }); + describe('Radio Button', () => { + it('create', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + data() { + return { + radio: 3 + }; + } + }, true); + expect(vm.$refs.radio1.$el.classList.contains('is-active')).to.be.true; + let radio = vm.$refs.radio2; + radio.$el.click(); + setTimeout(_ => { + expect(radio.$el.classList.contains('is-active')).to.be.true; + expect(vm.radio === 6).to.be.true; + done(); + }, 10); + }); + it('custom color', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + data() { + return { + radio: 3 + }; + } + }, true); + setTimeout(_ => { + expect(vm.$refs.radio1.activeStyle.backgroundColor).to.equal('#000'); + expect(vm.$refs.radio1.activeStyle.borderColor).to.equal('#000'); + expect(vm.$refs.radio1.activeStyle.color).to.equal('#ff0'); + done(); + }, 10); + }); + it('change event', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + methods: { + onChange(val) { + this.data = val; + } + }, + data() { + return { + data: 0, + radio: 3 + }; + } + }, true); + let radio = vm.$refs.radio2; + radio.$el.click(); + setTimeout(_ => { + expect(vm.data).to.equal(6); + done(); + }, 10); + }); + it('change event only triggers on user input', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + methods: { + onChange(val) { + this.data = val; + } + }, + data() { + return { + data: 0, + radio: 3 + }; + } + }, true); + vm.radio = 6; + setTimeout(_ => { + expect(vm.data).to.equal(0); + done(); + }, 10); + }); + it('size', done => { + vm = createVue({ + template: ` + + 备选项 + 备选项 + 备选项 + + `, + data() { + return { + radio: 3 + }; + } + }, true); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-radio-button--large').length).to.be.equal(3); + done(); + }, 10); + }); + }); + }); +}); diff --git a/test/unit/specs/rate.spec.js b/test/unit/specs/rate.spec.js new file mode 100644 index 0000000..48a27e8 --- /dev/null +++ b/test/unit/specs/rate.spec.js @@ -0,0 +1,229 @@ +import { createTest, createVue, destroyVM } from '../util'; +import Rate from 'packages/rate'; +import Vue from 'vue'; + +describe('Rate', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Rate, { max: 10 }, true); + const stars = vm.$el.querySelectorAll('.el-rate__item'); + expect(stars.length).to.equal(10); + }); + + it('with texts', () => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 4 + }; + } + }, true); + const text = vm.$el.querySelector('.el-rate__text'); + expect(text.textContent).to.equal('4'); + }); + + it('value change', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + const rate = vm.$children[0]; + expect(rate.value).to.equal(0); + vm.value = 3; + Vue.nextTick(() => { + expect(rate.value).to.equal(3); + done(); + }); + }); + + it('click', () => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + const thirdStar = vm.$el.querySelectorAll('.el-rate__item')[2]; + thirdStar.click(); + expect(vm.value).to.equal(3); + }); + + it('colors', () => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 4 + }; + } + }, true); + const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[2].querySelector('.el-rate__icon'); + expect(thirdIcon.style.color).to.equal('rgb(255, 153, 0)'); + }); + + it('colors are updated after prop is changed', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + computed: { + colors() { + if (this.muted) { + return ['#999', '#999', '#999']; + } else { + return ['#99A9BF', '#F7BA2A', '#FF9900']; + } + } + }, + data() { + return { + value: 4, + muted: false + }; + } + }, true); + setTimeout(() => { + vm.muted = true; + vm.$nextTick(() => { + const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[2].querySelector('.el-rate__icon'); + expect(thirdIcon.style.color).to.equal('rgb(153, 153, 153)'); + done(); + }); + }, 10); + }); + + it('threshold', () => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 3 + }; + } + }, true); + const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[2].querySelector('.el-rate__icon'); + expect(thirdIcon.style.color).to.equal('rgb(247, 186, 42)'); + }); + + it('disabled', () => { + const vm1 = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 3.7 + }; + } + }, true); + const vm2 = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 3.4 + }; + } + }, true); + const firstStar = vm1.$el.querySelectorAll('.el-rate__item')[0]; + firstStar.click(); + vm1.$children[0].resetCurrentValue(); + expect(vm1.value).to.equal(3.7); + + const fourthStar = vm2.$el.querySelectorAll('.el-rate__item')[3]; + const halfStar = fourthStar.querySelector('.el-rate__decimal'); + expect(halfStar.style.width).to.equal('40%'); + }); + + it('allow half', () => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + const rate = vm.$children[0]; + const secondStar = vm.$el.querySelectorAll('.el-rate__item')[1]; + rate.setCurrentValue(1, { target: secondStar, offsetX: 2 }); + secondStar.click(); + rate.resetCurrentValue(); + expect(vm.value).to.equal(0.5); + }); + + it('custom icon classes by passing object', () => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 4 + }; + } + }, true); + const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[3].querySelector('.el-rate__icon'); + expect(thirdIcon.className).to.include('icon-rate-face-3'); + }); + +}); diff --git a/test/unit/specs/row.spec.js b/test/unit/specs/row.spec.js new file mode 100644 index 0000000..4974014 --- /dev/null +++ b/test/unit/specs/row.spec.js @@ -0,0 +1,44 @@ +import { createTest, destroyVM } from '../util'; +import Row from 'packages/row'; + +describe('Row', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Row, true); + let rowElm = vm.$el; + expect(rowElm.classList.contains('el-row')).to.be.true; + }); + it('gutter', () => { + vm = createTest(Row, { + gutter: 20 + }, true); + let rowElm = vm.$el; + expect(rowElm.style.marginLeft).to.be.equal('-10px'); + expect(rowElm.style.marginRight).to.be.equal('-10px'); + }); + it('type', () => { + vm = createTest(Row, { + type: 'flex' + }, true); + let rowElm = vm.$el; + expect(rowElm.classList.contains('el-row--flex')).to.be.true; + }); + it('justify', () => { + vm = createTest(Row, { + justify: 'end' + }, true); + let rowElm = vm.$el; + expect(rowElm.classList.contains('is-justify-end')).to.be.true; + }); + it('align', () => { + vm = createTest(Row, { + align: 'bottom' + }, true); + let rowElm = vm.$el; + expect(rowElm.classList.contains('is-align-bottom')).to.be.true; + }); +}); diff --git a/test/unit/specs/select.spec.js b/test/unit/specs/select.spec.js new file mode 100644 index 0000000..69677d0 --- /dev/null +++ b/test/unit/specs/select.spec.js @@ -0,0 +1,910 @@ +import { createTest, createVue, triggerEvent, destroyVM, waitImmediate } from '../util'; +import Select from 'packages/select'; + +describe('Select', () => { + const getSelectVm = (configs = {}, options) => { + ['multiple', 'clearable', 'filterable', 'allowCreate', 'remote', 'collapseTags', 'automaticDropdown'].forEach(config => { + configs[config] = configs[config] || false; + }); + configs.multipleLimit = configs.multipleLimit || 0; + if (!options) { + options = [{ + value: '选项1', + label: '黄金糕', + disabled: false + }, { + value: '选项2', + label: '双皮奶', + disabled: false + }, { + value: '选项3', + label: '蚵仔煎', + disabled: false + }, { + value: '选项4', + label: '龙须面', + disabled: false + }, { + value: '选项5', + label: '北京烤鸭', + disabled: false + }]; + } + const vm = createVue({ + template: ` +
+ + + + +
+ `, + + data() { + return { + options, + multiple: configs.multiple, + multipleLimit: configs.multipleLimit, + clearable: configs.clearable, + filterable: configs.filterable, + collapseTags: configs.collapseTags, + allowCreate: configs.allowCreate, + popperClass: configs.popperClass, + automaticDropdown: configs.automaticDropdown, + loading: false, + filterMethod: configs.filterMethod && configs.filterMethod(this), + remote: configs.remote, + remoteMethod: configs.remoteMethod && configs.remoteMethod(this), + value: configs.multiple ? [] : '' + }; + } + }, true); + return vm; + }; + + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Select, true); + expect(vm.$el.className).to.equal('el-select'); + expect(vm.$el.querySelector('.el-input__inner').placeholder).to.equal('请选择'); + vm.toggleMenu(); + expect(vm.visible).to.true; + }); + + it('options rendered correctly', () => { + vm = getSelectVm(); + const options = vm.$el.querySelectorAll('.el-select-dropdown__item'); + const result = [].every.call(options, (option, index) => { + let text = option.querySelector('span').textContent; + return text === vm.options[index].label; + }); + expect(result).to.true; + }); + + it('custom dropdown class', () => { + vm = getSelectVm({ popperClass: 'custom-dropdown' }); + const dropdown = vm.$el.querySelector('.el-select-dropdown'); + expect(dropdown.classList.contains('custom-dropdown')).to.true; + }); + + it('default value', done => { + vm = createVue({ + template: ` +
+ + + + +
+ `, + + data() { + return { + options: [{ + value: '选项1', + label: '黄金糕' + }, { + value: '选项2', + label: '双皮奶' + }], + value: '选项2' + }; + } + }, true); + setTimeout(() => { + expect(vm.$el.querySelector('.el-input__inner').value).to.equal('双皮奶'); + done(); + }, 100); + }); + + it('single select', done => { + vm = createVue({ + template: ` +
+ + +

{{item.label}} {{item.value}}

+
+
+
+ `, + + data() { + return { + options: [{ + value: '选项1', + label: '黄金糕' + }, { + value: '选项2', + label: '双皮奶' + }, { + value: '选项3', + label: '蚵仔煎' + }, { + value: '选项4', + label: '龙须面' + }, { + value: '选项5', + label: '北京烤鸭' + }], + value: '', + count: 0 + }; + }, + + methods: { + handleChange() { + this.count++; + } + } + }, true); + const options = vm.$el.querySelectorAll('.el-select-dropdown__item'); + expect(vm.value).to.equal(''); + triggerEvent(options[2], 'mouseenter'); + options[2].click(); + setTimeout(() => { + expect(vm.value).to.equal('选项3'); + expect(vm.count).to.equal(1); + triggerEvent(options[2], 'mouseenter'); + options[4].click(); + setTimeout(() => { + expect(vm.value).to.equal('选项5'); + expect(vm.count).to.equal(2); + done(); + }, 100); + }, 100); + }); + + it('disabled option', done => { + vm = getSelectVm(); + vm.options[1].disabled = true; + setTimeout(() => { + const options = vm.$el.querySelectorAll('.el-select-dropdown__item'); + expect(options[1].classList.contains('is-disabled')).to.true; + options[1].click(); + setTimeout(() => { + expect(vm.value).to.equal(''); + done(); + }, 100); + }, 100); + }); + + it('disabled select', () => { + vm = createTest(Select, { disabled: true }, true); + expect(vm.$el.querySelector('.el-input').classList.contains('is-disabled')).to.true; + }); + + it('visible event', done => { + vm = createVue({ + template: ` +
+ + + + +
+ `, + + data() { + return { + options: [], + value: '', + visible: '' + }; + }, + + methods: { + handleVisibleChange(val) { + this.visible = val; + } + } + }, true); + vm.$children[0].visible = true; + setTimeout(() => { + expect(vm.visible).to.true; + done(); + }, 50); + }); + + it('keyboard operations', done => { + vm = getSelectVm(); + const select = vm.$children[0]; + let i = 8; + while (i--) { + select.navigateOptions('next'); + } + select.navigateOptions('prev'); + setTimeout(() => { + expect(select.hoverIndex).to.equal(0); + select.selectOption(); + setTimeout(() => { + expect(select.value).to.equal('选项1'); + done(); + }, 100); + }, 100); + }); + + it('clearable', done => { + vm = getSelectVm({ clearable: true }); + const select = vm.$children[0]; + vm.value = '选项1'; + select.inputHovering = true; + setTimeout(() => { + const iconClear = vm.$el.querySelector('.el-input__icon.el-icon-circle-close'); + expect(iconClear).to.exist; + iconClear.click(); + expect(vm.value).to.equal(''); + done(); + }, 100); + }); + + it('object typed value', done => { + vm = createVue({ + template: ` +
+ + + + +
+ `, + + data() { + return { + options: [{ + id: 1, + label: 'label1' + }, { + id: 2, + label: 'label2' + }], + value: { + id: 1, + label: 'label1' + } + }; + } + }, true); + setTimeout(() => { + expect(vm.$el.querySelector('.el-input__inner').value).to.equal('label1'); + expect(vm.$el.querySelector('.el-select-dropdown__item').classList.contains('selected')); + done(); + }, 100); + }); + + it('prefixed icon', () => { + vm = createTest({ + template: ` +
+ + + + + +
+ `, + + data() { + return { + options: [], + value: '' + }; + } + }); + expect(vm.$el.querySelector('.el-input__icon').classList.contains('el-icon-search')).to.be.true; + }); + + it('custom el-option template', () => { + vm = createVue({ + template: ` +
+ + +

{{item.label}} {{item.value}}

+
+
+
+ `, + + data() { + return { + options: [{ + value: 'value', + label: 'label' + }], + value: '' + }; + } + }, true); + expect(vm.$el.querySelector('.el-select-dropdown__item p').textContent).to.equal('label value'); + }); + + it('option group', () => { + vm = createVue({ + template: ` +
+ + + + + + +
+ `, + + data() { + return { + options: [{ + label: '热门城市', + options: [{ + value: 'Shanghai', + label: '上海' + }, { + value: 'Beijing', + label: '北京' + }] + }, { + label: '城市名', + disabled: true, + options: [{ + value: 'Chengdu', + label: '成都' + }, { + value: 'Shenzhen', + label: '深圳' + }, { + value: 'Guangzhou', + label: '广州' + }, { + value: 'Dalian', + label: '大连' + }] + }], + value: '' + }; + } + }, true); + const groups = vm.$el.querySelectorAll('.el-select-group__wrap'); + const options = groups[1].querySelectorAll('.el-select-dropdown__item'); + expect(groups.length).to.equal(2); + expect(options.length).to.equal(4); + expect(options[0].querySelector('span').textContent).to.equal('成都'); + }); + + it('filterable', done => { + vm = getSelectVm({ filterable: true }); + const select = vm.$children[0]; + setTimeout(() => { + select.selectedLabel = '面'; + select.onInputChange(); + select.visible = true; + setTimeout(() => { + expect(select.filteredOptionsCount).to.equal(1); + done(); + }, 10); + }, 10); + }); + + it('filterable with custom filter-method', done => { + const filterMethod = vm => { + return query => { + vm.options = vm.options.filter(option => option.label.indexOf(query) === -1); + }; + }; + vm = getSelectVm({ filterable: true, filterMethod }); + const select = vm.$children[0]; + select.$el.click(); + setTimeout(() => { + select.selectedLabel = '面'; + select.onInputChange(); + setTimeout(() => { + expect(select.filteredOptionsCount).to.equal(4); + done(); + }, 10); + }, 10); + }); + + it('default-first-option', done => { + vm = createVue({ + template: ` +
+ + + +
+ `, + data() { + return { + options: ['1', '2', '3', '4', '5'], + value: '' + }; + } + }, true); + + const select = vm.$children[0]; + setTimeout(() => { + select.$el.click(); + select.query = '3'; + select.handleQueryChange('3'); + select.selectOption(); + setTimeout(() => { + expect(select.value).to.equal('3'); + done(); + }, 10); + }, 10); + }); + + it('allow create', done => { + vm = getSelectVm({ filterable: true, allowCreate: true }); + const select = vm.$children[0]; + select.$el.querySelector('input').focus(); + setTimeout(() => { + select.selectedLabel = 'new'; + select.onInputChange(); + setTimeout(() => { + const options = document.querySelectorAll('.el-select-dropdown__item span'); + const target = [].filter.call(options, option => option.innerText === 'new'); + target[0].click(); + setTimeout(() => { + expect(select.value.indexOf('new') > -1).to.true; + done(); + }, 10); + }, 10); + }, 10); + }); + + it('multiple select', done => { + vm = getSelectVm({ multiple: true }); + const options = vm.$el.querySelectorAll('.el-select-dropdown__item'); + vm.value = ['选项1']; + setTimeout(() => { + options[1].click(); + setTimeout(() => { + options[3].click(); + setTimeout(() => { + expect(vm.value.indexOf('选项2') > -1 && vm.value.indexOf('选项4') > -1).to.true; + const tagCloseIcons = vm.$el.querySelectorAll('.el-tag__close'); + tagCloseIcons[0].click(); + setTimeout(() => { + expect(vm.value.indexOf('选项1')).to.equal(-1); + done(); + }, 100); + }, 100); + }, 100); + }, 100); + }); + + it('multiple remove-tag', done => { + sinon.stub(window.console, 'log'); + vm = createVue({ + template: ` +
+ + +

{{item.label}} {{item.value}}

+
+
+
+ `, + + data() { + return { + options: [{ + value: '选项1', + label: '黄金糕' + }, { + value: '选项2', + label: '双皮奶' + }, { + value: '选项3', + label: '蚵仔煎' + }, { + value: '选项4', + label: '龙须面' + }, { + value: '选项5', + label: '北京烤鸭' + }], + value: ['选项1', '选项3'] + }; + }, + + methods: { + handleRemoveTag() { + console.log('remove tag'); + } + } + }, true); + expect(vm.value.length).to.equal(2); + setTimeout(() => { + const tagCloseIcons = vm.$el.querySelectorAll('.el-tag__close'); + tagCloseIcons[1].click(); + setTimeout(() => { + expect(vm.value.length).to.equal(1); + expect(window.console.log.callCount).to.equal(1); + tagCloseIcons[0].click(); + setTimeout(() => { + expect(vm.value.length).to.equal(0); + expect(window.console.log.callCount).to.equal(2); + window.console.log.restore(); + done(); + }, 50); + }, 50); + }, 50); + }); + + it('multiple limit', done => { + vm = getSelectVm({ multiple: true, multipleLimit: 1 }); + const options = vm.$el.querySelectorAll('.el-select-dropdown__item'); + options[1].click(); + setTimeout(() => { + expect(vm.value.indexOf('选项2') > -1).to.true; + options[3].click(); + setTimeout(() => { + expect(vm.value.indexOf('选项4')).to.equal(-1); + done(); + }, 50); + }, 50); + }); + + it('multiple remote search', done => { + const remoteMethod = vm => { + return query => { + vm.loading = true; + setTimeout(() => { + vm.options = vm.options.filter(option => { + return option.label.indexOf(query) > -1; + }); + vm.loading = false; + }, 200); + }; + }; + vm = getSelectVm({ + multiple: true, + remote: true, + filterable: true, + remoteMethod + }); + const select = vm.$children[0]; + select.handleQueryChange(''); + vm.$nextTick(() => { + select.handleQueryChange('面'); + setTimeout(() => { + expect(select.filteredOptionsCount).to.equal(1); + select.options[0].$el.click(); + vm.$nextTick(() => { + expect(vm.value[0]).to.equal('选项4'); + select.deletePrevTag({ target: select.$refs.input }); + select.deletePrevTag({ target: select.$refs.input }); + select.resetInputState({ keyCode: 1 }); + vm.$nextTick(() => { + expect(vm.value.length).to.equal(0); + done(); + }); + }); + }, 250); + }); + }); + + it('event:focus & blur', done => { + vm = createVue({ + template: ` + + ` + }, true); + + const spyFocus = sinon.spy(); + const spyBlur = sinon.spy(); + + vm.$refs.select.$on('focus', spyFocus); + vm.$refs.select.$on('blur', spyBlur); + vm.$el.querySelector('input').focus(); + vm.$el.querySelector('input').blur(); + + setTimeout(_ => { + expect(spyFocus.calledOnce).to.be.true; + expect(spyBlur.calledOnce).to.be.true; + done(); + }, 250); + }); + + it('should return focus to input inside select after option select', done => { + vm = createVue({ + template: ` +
+ + + +
+ `, + data() { + return { + value: '' + }; + } + }, true); + + const spyInputFocus = sinon.spy(); + const spySelectFocus = sinon.spy(); + + vm.$refs.select.$on('focus', spySelectFocus); + vm.$refs.select.$refs.reference.$on('focus', spyInputFocus); + + const option = vm.$el.querySelectorAll('.el-select-dropdown__item')[0]; + triggerEvent(option, 'mouseenter'); + option.click(); + + vm.$nextTick(_ => { + expect(spyInputFocus.calledOnce).to.be.true; + expect(spySelectFocus.calledOnce).not.to.be.true; + done(); + }); + }); + + it('should not open popper when automatic-dropdown not set', done => { + vm = getSelectVm(); + + vm.$refs.select.$refs.reference.$refs.input.focus(); + + vm.$nextTick(_ => { + expect(vm.$refs.select.visible).to.be.false; + done(); + }); + }); + + it('should open popper when automatic-dropdown is set', done => { + vm = getSelectVm({ automaticDropdown: true }); + + vm.$refs.select.$refs.reference.$refs.input.focus(); + + vm.$nextTick(_ => { + expect(vm.$refs.select.visible).to.be.true; + done(); + }); + }); + + it('focus', done => { + vm = createVue({ + template: ` + + ` + }, true); + const spy = sinon.spy(); + + vm.$refs.select.$on('focus', spy); + vm.$refs.select.focus(); + + vm.$nextTick(_ => { + expect(spy.calledOnce).to.be.true; + done(); + }); + }); + + it('only emit change on user input', done => { + let callCount = 0; + vm = createVue({ + template: ` +
+ + + + + +
+ `, + data() { + return { + value: 1, + change: () => ++callCount + }; + } + }); + + vm.value = 2; + setTimeout(() => { + expect(callCount).to.equal(0); + const options = vm.$el.querySelectorAll('.el-select-dropdown__item'); + triggerEvent(options[2], 'mouseenter'); + options[2].click(); + setTimeout(() => { + expect(callCount).to.equal(1); + done(); + }, 10); + }, 10); + }); + + it('render slot `empty`', done => { + vm = createVue({ + template: ` +
+ +
EmptySlot
+
+
+ `, + data() { + return { + value: 1 + }; + } + }); + + expect(vm.$el.querySelector('.empty-slot').innerText).to.be.equal('EmptySlot'); + done(); + }); + + it('should set placeholder to label of selected option when filterable is true and multiple is false', async() => { + vm = createVue({ + template: ` +
+ + + +
+ `, + data() { + return { + value: 'test' + }; + } + }); + vm.$refs.select.$el.click(); + await waitImmediate(); + expect(vm.$refs.select.visible).to.be.equal(true); + expect(vm.$el.querySelector('.el-input__inner').placeholder).to.be.equal('test'); + expect(vm.value).to.be.equal('test'); + }); + + it('default value is null or undefined', async() => { + vm = createVue({ + template: ` +
+ + + + +
+ `, + + data() { + return { + options: [{ + value: '选项1', + label: '黄金糕' + }, { + value: '选项2', + label: '双皮奶' + }], + value: undefined + }; + } + }, true); + + vm.value = null; + await waitImmediate(); + expect(vm.$el.querySelector('.el-input__inner').value).to.equal(''); + vm.value = '选项1'; + await waitImmediate(); + expect(vm.$el.querySelector('.el-input__inner').value).to.equal('黄金糕'); + }); + + describe('resetInputHeight', () => { + const getSelectComponentVm = (configs) => { + vm = getSelectVm(configs || {}); + return vm.$refs.select; + }; + + it('should reset height if collapse-tags option is disabled', () => { + const select = getSelectComponentVm(); + sinon.stub(select, '$nextTick'); + select.resetInputHeight(); + expect(select.$nextTick.callCount).to.equal(1); + }); + + it('should not reset height if collapse-tags option is enabled', () => { + const select = getSelectComponentVm({ collapseTags: true }); + sinon.stub(select, '$nextTick'); + select.resetInputHeight(); + expect(select.$nextTick.callCount).to.equal(0); + }); + + it('should reset height if both collapse-tags and filterable are enabled', () => { + const select = getSelectComponentVm({ collapseTags: true, filterable: true }); + sinon.stub(select, '$nextTick'); + select.resetInputHeight(); + expect(select.$nextTick.callCount).to.equal(1); + }); + }); +}); diff --git a/test/unit/specs/slider.spec.js b/test/unit/specs/slider.spec.js new file mode 100644 index 0000000..7cd1063 --- /dev/null +++ b/test/unit/specs/slider.spec.js @@ -0,0 +1,501 @@ +import { createTest, createVue, triggerEvent, destroyVM, waitImmediate } from '../util'; +import Slider from 'packages/slider'; + +describe('Slider', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Slider); + expect(vm.value).to.equal(0); + }); + + it('should not exceed min and max', done => { + vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + value: 50 + }; + } + }, true); + setTimeout(() => { + vm.value = 40; + vm.$nextTick(() => { + expect(vm.value).to.equal(50); + vm.value = 120; + vm.$nextTick(() => { + expect(vm.value).to.equal(100); + done(); + }); + }); + }, 10); + }); + + it('show tooltip', () => { + vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + const slider = vm.$children[0].$children[0]; + slider.handleMouseEnter(); + expect(slider.$refs.tooltip.showPopper).to.true; + slider.handleMouseLeave(); + expect(slider.$refs.tooltip.showPopper).to.false; + }); + + it('hide tooltip', () => { + vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + const slider = vm.$children[0].$children[0]; + expect(slider.$refs.tooltip.disabled).to.true; + }); + + it('format tooltip', async() => { + vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + value: 0 + }; + }, + methods: { + formatTooltip(val) { + return '$' + val; + } + } + }, true); + const sliderButton = vm.$refs.slider.$children[0]; + await waitImmediate(); + expect(sliderButton.formatValue).to.equal('$0'); + }); + + it('drag', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + vertical: false, + value: 0 + }; + } + }, true); + const slider = vm.$children[0].$children[0]; + slider.onButtonDown({ clientX: 0, preventDefault() {} }); + slider.onDragging({ clientX: 100 }); + slider.onDragEnd(); + setTimeout(() => { + expect(vm.value > 0).to.true; + vm.vertical = true; + vm.value = 0; + vm.$nextTick(() => { + expect(vm.value === 0).to.true; + slider.onButtonDown({ clientY: 0, preventDefault() {} }); + slider.onDragging({ clientY: -100 }); + slider.onDragEnd(); + setTimeout(() => { + expect(vm.value > 0).to.true; + done(); + }, 10); + }); + }, 10); + }); + + it('accessibility', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 0.1 + }; + } + }, true); + const slider = vm.$children[0].$children[0]; + slider.onRightKeyDown(); + setTimeout(() => { + expect(vm.value).to.equal(1); + slider.onLeftKeyDown(); + setTimeout(() => { + expect(vm.value).to.equal(0); + done(); + }, 10); + }, 10); + }); + + it('step', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + const slider = vm.$children[0].$children[0]; + slider.onButtonDown({ clientX: 0, preventDefault() {} }); + slider.onDragging({ clientX: 100 }); + slider.onDragEnd(); + setTimeout(() => { + expect(vm.value > 0.4 && vm.value < 0.6).to.true; + done(); + }, 10); + }); + + it('click', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + const slider = vm.$children[0]; + setTimeout(() => { + slider.onSliderClick({ clientX: 100 }); + setTimeout(() => { + expect(vm.value > 0).to.true; + done(); + }, 10); + }, 10); + }); + + it('change event', done => { + vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + data: 0, + value: 0 + }; + }, + methods: { + onChange(val) { + this.data = val; + } + } + }, true); + const slider = vm.$children[0]; + vm.value = 10; + setTimeout(() => { + expect(vm.data).to.equal(0); + slider.onSliderClick({ clientX: 100 }); + setTimeout(() => { + expect(vm.data > 0).to.true; + done(); + }, 10); + }, 10); + }); + + it('disabled', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + const slider = vm.$children[0].$children[0]; + slider.onButtonDown({ clientX: 0 }); + slider.onDragging({ clientX: 100 }); + slider.onDragEnd(); + setTimeout(() => { + expect(vm.value).to.equal(0); + done(); + }, 10); + }); + + it('show input', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + setTimeout(() => { + triggerEvent(vm.$el.querySelector('.el-input-number'), 'keyup'); + const inputNumber = vm.$el.querySelector('.el-input-number').__vue__; + inputNumber.setCurrentValue(40); + setTimeout(() => { + expect(vm.value).to.equal(40); + done(); + }, 10); + }, 10); + }); + + it('show stops', () => { + vm = createTest(Slider, { + showStops: true, + step: 10 + }, true); + const stops = vm.$el.querySelectorAll('.el-slider__stop'); + expect(stops.length).to.equal(9); + }); + + it('vertical mode', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: 0 + }; + } + }, true); + const slider = vm.$children[0]; + setTimeout(() => { + slider.onSliderClick({ clientY: 100 }); + setTimeout(() => { + expect(vm.value > 0).to.true; + done(); + }, 10); + }, 10); + }); + + describe('range', () => { + it('basic ranged slider', () => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: [10, 20] + }; + } + }, true); + const buttons = vm.$children[0].$children; + expect(buttons.length).to.equal(2); + }); + + it('should not exceed min and max', done => { + vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + value: [50, 60] + }; + } + }, true); + setTimeout(() => { + vm.value = [40, 60]; + setTimeout(() => { + expect(vm.value).to.deep.equal([50, 60]); + vm.value = [50, 120]; + setTimeout(() => { + expect(vm.value).to.deep.equal([50, 100]); + done(); + }, 10); + }, 10); + }, 10); + }); + + it('click', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: [0, 100] + }; + } + }, true); + const slider = vm.$children[0]; + setTimeout(() => { + slider.onSliderClick({ clientX: 100 }); + setTimeout(() => { + expect(vm.value[0] > 0).to.true; + expect(vm.value[1]).to.equal(100); + done(); + }, 10); + }, 10); + }); + + it('responsive to dynamic min and max', done => { + vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + min: 0, + max: 100, + value: [50, 80] + }; + } + }, true); + setTimeout(() => { + vm.min = 60; + setTimeout(() => { + expect(vm.value).to.deep.equal([60, 80]); + vm.min = 30; + vm.max = 40; + setTimeout(() => { + expect(vm.value).to.deep.equal([40, 40]); + done(); + }, 10); + }, 10); + }, 10); + }); + + it('show stops', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: [30, 60] + }; + } + }, true); + setTimeout(() => { + const stops = vm.$el.querySelectorAll('.el-slider__stop'); + expect(stops.length).to.equal(5); + done(); + }, 10); + }); + + it('marks', async() => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: [30, 60], + marks: { + 0: '0°C', + 8: '8°C', + 37: '37°C', + 50: { + style: { + color: '#f50' + }, + label: 50°C + } + } + }; + } + }, true); + + waitImmediate(); + const stops = vm.$el.querySelectorAll('.el-slider__marks-stop.el-slider__stop'); + const marks = vm.$el.querySelectorAll('.el-slider__marks .el-slider__marks-text'); + expect(marks.length).to.equal(2); + expect(stops.length).to.equal(2); + }); + }); +}); diff --git a/test/unit/specs/steps.spec.js b/test/unit/specs/steps.spec.js new file mode 100644 index 0000000..6efae9e --- /dev/null +++ b/test/unit/specs/steps.spec.js @@ -0,0 +1,163 @@ +import { createVue, destroyVM, waitImmediate } from '../util'; + +describe('Steps', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createVue(` + + + + + + `); + + expect(vm.$el.querySelectorAll('.el-step')).to.length(3); + }); + + it('space', async() => { + vm = createVue(` + + + + + + `, true); + + const vm2 = createVue(` + + + + + + + `, true); + + await waitImmediate(); + const stepElm = vm.$el.querySelector('.el-step'); + const stepElm2 = vm2.$el.querySelector('.el-step'); + expect(getComputedStyle(stepElm).flexBasis).to.equal('50%'); + expect(getComputedStyle(stepElm2).flexBasis).to.equal('100px'); + }); + + it('processStatus', done => { + vm = createVue(` + + + + + + `); + + vm.$nextTick(_ => { + expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(1); + done(); + }); + }); + + it('update processStatus', done => { + vm = createVue({ + template: ` + + + + + `, + data() { + return { processStatus: 'error' }; + } + }); + + vm.$nextTick(_ => { + expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(1); + vm.processStatus = 'process'; + vm.$nextTick(_ => { + expect(vm.$el.querySelectorAll('.el-step__head.is-process')).to.length(1); + done(); + }); + }); + }); + + it('finishStatus', done => { + vm = createVue(` + + + + + `); + + vm.$nextTick(_ => { + expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(1); + done(); + }); + }); + + it('active', done => { + vm = createVue({ + template: ` + + + + + `, + + data() { + return { active: 0 }; + } + }); + + vm.$nextTick(_ => { + expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(0); + vm.active = 2; + vm.$nextTick(_ => { + expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(2); + done(); + }); + }); + }); + + it('create vertical', () => { + vm = createVue(` + + + + + `); + + expect(vm.$el.querySelector('.is-vertical')).to.exist; + }); + + it('vertical:height', async() => { + vm = createVue(` + + + + + `, true); + + await waitImmediate(); + const stepElm = vm.$el.querySelector('.el-step'); + expect(getComputedStyle(stepElm).flexBasis).to.equal('200px'); + }); + + it('step:status=error', done => { + vm = createVue(` + + + + + + `); + + vm.$nextTick(_ => { + const errorLine = vm.$el.querySelector('.el-step:nth-child(2) .el-step__line-inner'); + expect(errorLine.getBoundingClientRect().width).to.equal(0); + const nextStep = vm.$el.querySelector('.el-step:nth-child(3) .el-step__head'); + expect(nextStep.classList.contains('is-wait')).to.equal(true); + done(); + }); + }); +}); diff --git a/test/unit/specs/switch.spec.js b/test/unit/specs/switch.spec.js new file mode 100644 index 0000000..9407a9c --- /dev/null +++ b/test/unit/specs/switch.spec.js @@ -0,0 +1,209 @@ +import { createTest, createVue, destroyVM } from '../util'; +import Switch from 'packages/switch'; +import Vue from 'vue'; + +describe('Switch', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Switch, { + activeText: 'on', + inactiveText: 'off', + activeColor: '#0f0', + inactiveColor: '#f00', + width: 100 + }); + + const core = vm.$el.querySelector('.el-switch__core'); + expect(core.style.backgroundColor).to.equal('rgb(255, 0, 0)'); + expect(core.style.width).to.equal('100px'); + expect(vm.$el.querySelector('.el-switch__label--left').querySelector('span').textContent).to.equal('off'); + }); + + it('switch with icons', () => { + vm = createTest(Switch, { + activeIconClass: 'el-icon-check', + inactiveIconClass: 'el-icon-close' + }); + + const icon = vm.$el.querySelector('.el-switch__label--left').querySelector('i'); + expect(icon.classList.contains('el-icon-close')).to.true; + }); + + it('value correctly update', done => { + vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + value: true + }; + } + }, true); + + const core = vm.$el.querySelector('.el-switch__core'); + expect(core.style.backgroundColor).to.equal('rgb(0, 255, 0)'); + core.click(); + setTimeout(() => { + expect(core.style.backgroundColor).to.equal('rgb(255, 0, 0)'); + expect(vm.value).to.equal(false); + core.click(); + setTimeout(() => { + expect(vm.value).to.equal(true); + done(); + }, 10); + }, 10); + }); + + it('change event', done => { + vm = createVue({ + template: ` +
+ + +
+ `, + mounted() { + setTimeout(() => { + this.value = false; + }, 10); + }, + methods: { + handleChange(val) { + this.target = val; + } + }, + data() { + return { + target: 1, + value: true + }; + } + }, true); + + setTimeout(() => { + const core = vm.$el.querySelector('.el-switch__core'); + expect(vm.target).to.equal(1); + core.click(); + setTimeout(() => { + expect(vm.target).to.equal(true); + done(); + }, 10); + }, 50); + }); + + it('disabled switch should not respond to user click', done => { + vm = createVue({ + template: ` +
+ +
+ `, + + data() { + return { + value: true + }; + } + }, true); + + vm.$el.querySelector('.el-switch__core').click(); + Vue.nextTick(() => { + expect(vm.value).to.true; + done(); + }); + }); + + it('expand switch value', done => { + vm = createVue({ + template: ` +
+ +
+ `, + data() { + return { + value: '100', + onValue: '100', + offValue: '0' + }; + } + }, true); + + const core = vm.$el.querySelector('.el-switch__core'); + core.click(); + setTimeout(() => { + expect(vm.value).to.equal('0'); + core.click(); + setTimeout(() => { + expect(vm.value).to.equal('100'); + done(); + }, 10); + }, 10); + }); + + it('value is the single source of truth', done => { + vm = createVue({ + template: ` +
+ +
+ ` + }, true); + + const component = vm.$children[0]; + const input = vm.$el.querySelector('input'); + const core = vm.$el.querySelector('.el-switch__core'); + core.click(); + setTimeout(() => { + expect(component.checked).to.equal(true); + expect(component.$el.classList.contains('is-checked')).to.equal(true); + expect(input.checked).to.equal(true); + core.click(); + setTimeout(() => { + expect(component.checked).to.equal(true); + expect(component.$el.classList.contains('is-checked')).to.equal(true); + expect(input.checked).to.equal(true); + done(); + }, 10); + }, 10); + }); + + it('sets checkbox value', done => { + vm = createVue({ + template: ` +
+ +
+ `, + data() { + return { + value: false + }; + } + }, true); + + vm.value = true; + setTimeout(() => { + expect(vm.$el.querySelector('input').checked).to.equal(true); + vm.value = false; + setTimeout(() => { + expect(vm.$el.querySelector('input').checked).to.equal(false); + done(); + }, 10); + }, 10); + }); +}); diff --git a/test/unit/specs/table.spec.js b/test/unit/specs/table.spec.js new file mode 100644 index 0000000..f0888d2 --- /dev/null +++ b/test/unit/specs/table.spec.js @@ -0,0 +1,2257 @@ +import { createVue, triggerEvent, destroyVM, waitImmediate, wait } from '../util'; + +const DELAY = 10; +const testDataArr = []; +const toArray = function(obj) { + return [].slice.call(obj); +}; + +const getTestData = function() { + return [ + { id: 1, name: 'Toy Story', release: '1995-11-22', director: 'John Lasseter', runtime: 80 }, + { id: 2, name: 'A Bug\'s Life', release: '1998-11-25', director: 'John Lasseter', runtime: 95 }, + { id: 3, name: 'Toy Story 2', release: '1999-11-24', director: 'John Lasseter', runtime: 92 }, + { id: 4, name: 'Monsters, Inc.', release: '2001-11-2', director: 'Peter Docter', runtime: 92 }, + { id: 5, name: 'Finding Nemo', release: '2003-5-30', director: 'Andrew Stanton', runtime: 100 } + ]; +}; + +getTestData().forEach(cur => { + Object.keys(cur).forEach(prop => { + testDataArr.push(cur[prop].toString()); + }); +}); + +describe('Table', () => { + describe('rendering data is correct', () => { + const vm = createVue({ + template: ` + + + + + + + + `, + + created() { + this.testData = getTestData(); + } + }); + + it('head', done => { + setTimeout(_ => { + const ths = toArray(vm.$el.querySelectorAll('thead th')); + + expect(ths.map(node => node.textContent).filter(o => o)) + .to.eql(['片名', '发行日期', '导演', '时长(分)']); + done(); + }, DELAY); + }); + + it('row length', () => { + expect(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr')).to.length(getTestData().length); + }); + + it('row data', () => { + const cells = toArray(vm.$el.querySelectorAll('td .cell')) + .map(node => node.textContent); + + expect(cells).to.eql(testDataArr); + destroyVM(vm); + }); + }); + + describe('attributes', () => { + const createTable = function(props, opts) { + return createVue(Object.assign({ + template: ` + + + + + + + `, + + created() { + this.testData = getTestData(); + } + }, opts)); + }; + + it('height', done => { + const vm = createTable('height="134"'); + setTimeout(_ => { + expect(vm.$el.style.height).to.equal('134px'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('height as string', done => { + const vm = createTable('height="100px"'); + setTimeout(_ => { + expect(vm.$el.style.height).to.equal('100px'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('maxHeight', done => { + const vm = createTable('max-height="134"'); + setTimeout(_ => { + expect(vm.$el.style.maxHeight).to.equal('134px'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('stripe', done => { + const vm = createTable('stripe'); + setTimeout(_ => { + expect(vm.$el.classList.contains('el-table--striped')).to.true; + destroyVM(vm); + done(); + }, DELAY); + }); + + it('border', done => { + const vm = createTable('border'); + setTimeout(_ => { + expect(vm.$el.classList.contains('el-table--border')).to.true; + destroyVM(vm); + done(); + }, DELAY); + }); + + it('fit', done => { + const vm = createTable(':fit="false"'); + setTimeout(_ => { + expect(vm.$el.classList.contains('el-table--fit')).to.false; + destroyVM(vm); + done(); + }, DELAY); + }); + + it('show-header', done => { + const vm = createTable(':show-header="false"'); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-table__header-wrapper').length).to.equal(0); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('tableRowClassName', done => { + const vm = createTable(':row-class-name="tableRowClassName"', { + methods: { + tableRowClassName({row, rowIndex}) { + if (rowIndex === 1) { + return 'info-row'; + } else if (rowIndex === 3) { + return 'positive-row'; + } + + return ''; + } + } + }); + + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.info-row')).to.length(1); + expect(vm.$el.querySelectorAll('.positive-row')).to.length(1); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('tableRowStyle[Object]', done => { + const vm = createTable(':row-style="{ height: \'60px\' }"', {}); + + setTimeout(_ => { + expect(vm.$el.querySelector('.el-table__body tr').style.height).to.equal('60px'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('tableRowStyle[Function]', done => { + const vm = createTable(':row-style="tableRowStyle"', { + methods: { + tableRowStyle({row, rowIndex}) { + if (rowIndex === 1) { + return { height: '60px', display: 'none' }; + } + + return null; + } + } + }); + + setTimeout(_ => { + let child1 = vm.$el.querySelector('.el-table__body tr:nth-child(1)'); + let child2 = vm.$el.querySelector('.el-table__body tr:nth-child(2)'); + expect(child1.style.height).to.equal(''); + expect(child1.style.display).to.equal(''); + expect(child2.style.height).to.equal('60px'); + expect(child2.style.display).to.equal('none'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('current-row-key', done => { + const vm = createVue({ + template: ` + + + + + + + `, + + created() { + this.testData = getTestData(); + }, + + data() { + return { currentRowKey: null }; + } + }, true); + setTimeout(_ => { + vm.currentRowKey = 1; + const tr = vm.$el.querySelector('.el-table__body-wrapper tbody tr'); + setTimeout(_ => { + expect(tr.classList.contains('current-row')).to.be.true; + vm.currentRowKey = 2; + + const rows = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr'); + setTimeout(_ => { + expect(tr.classList.contains('current-row')).to.be.false; + expect(rows[1].classList.contains('current-row')).to.be.true; + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }); + + it('select-on-indeterminate', done => { + const vm = createVue({ + template: ` + + + + + + + + `, + + created() { + this.testData = getTestData(); + }, + + mounted() { + this.$refs.table.toggleRowSelection(this.testData[0]); + }, + + data() { + return { selected: [] }; + }, + + methods: { + change(val) { + this.selected = val; + } + } + }, true); + + setTimeout(_ => { + vm.$el.querySelector('.el-checkbox').click(); + setTimeout(_ => { + expect(vm.selected).to.length(0); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + }); + + describe('filter', () => { + let vm; + + beforeEach(done => { + vm = createVue({ + template: ` + + + + + + + `, + + created() { + this.testData = getTestData(); + }, + + methods: { + filterMethod(value, row) { + return value === row.director; + }, + handleFilterChange(filters) { + this.filters = filters; + } + } + }, true); + + setTimeout(done, DELAY); + }); + + afterEach(() => destroyVM(vm)); + + it('render', () => { + expect(vm.$el.querySelector('.el-table__column-filter-trigger')).to.exist; + }); + + it('click dropdown', done => { + const btn = vm.$el.querySelector('.el-table__column-filter-trigger'); + triggerEvent(btn, 'click', true, false); + setTimeout(_ => { + const filter = document.body.querySelector('.el-table-filter'); + expect(filter).to.exist; + document.body.removeChild(filter); + done(); + }, 100); + }); + + it('click filter', done => { + const btn = vm.$el.querySelector('.el-table__column-filter-trigger'); + + triggerEvent(btn, 'click', true, false); + setTimeout(_ => { + const filter = document.body.querySelector('.el-table-filter'); + + // John Lasseter + triggerEvent(filter.querySelector('.el-checkbox'), 'click', true, false); + // confrim button + setTimeout(_ => { + triggerEvent(filter.querySelector('.el-table-filter__bottom button'), 'click', true, false); + setTimeout(_ => { + expect(vm.filters['director']).to.be.eql(['John Lasseter']); + expect(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr')).to.length(3); + document.body.removeChild(filter); + done(); + }, DELAY); + }, 100); + }, 100); + }); + + it('click reset', done => { + const btn = vm.$el.querySelector('.el-table__column-filter-trigger'); + + triggerEvent(btn, 'click', true, false); + setTimeout(_ => { + const filter = document.body.querySelector('.el-table-filter'); + + // John Lasseter + triggerEvent(filter.querySelector('.el-checkbox'), 'click', true, false); + setTimeout(_ => { + // reset button + triggerEvent(filter.querySelectorAll('.el-table-filter__bottom button')[1], 'click', true, false); + setTimeout(_ => { + expect(vm.filters['director']).to.be.eql([]); + expect(filter.querySelector('.el-table-filter__bottom button').classList.contains('is-disabled')).to.true; + document.body.removeChild(filter); + destroyVM(vm); + done(); + }, DELAY); + }, 100); + }, 100); + }); + }); + + describe('events', () => { + const createTable = function(prop = '', opts) { + return createVue({ + template: ` + + + + + + + + `, + + methods: { + handleEvent(...args) { + this.result = args; + } + }, + + created() { + this.testData = getTestData(); + }, + + data() { + return { result: '', testData: this.testData }; + } + }, true); + }; + + it('select', done => { + const vm = createTable('select'); + + setTimeout(_ => { + vm.$el.querySelectorAll('.el-checkbox')[1].click(); + expect(vm.result).to.length(2); + expect(vm.result[1]).to.have.property('name').to.equal(getTestData()[0].name); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('select-all', done => { + const vm = createTable('select-all'); + + setTimeout(_ => { + vm.$el.querySelector('.el-checkbox').click(); + setTimeout(_ => { + expect(vm.result).to.length(1); + expect(vm.result[0]).to.length(getTestData().length); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + + it('selection-change', done => { + const vm = createTable('selection-change'); + setTimeout(_ => { + vm.$el.querySelectorAll('.el-checkbox')[1].click(); + expect(vm.result).to.length(1); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('cell-mouse-enter', done => { + const vm = createTable('cell-mouse-enter'); + + setTimeout(_ => { + const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row + triggerEvent(cell.parentNode, 'mouseenter'); + expect(vm.result).to.length(4); // row, column, cell, event + expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('cell-mouse-leave', done => { + const vm = createTable('cell-mouse-leave'); + + setTimeout(_ => { + const cell = vm.$el.querySelectorAll('.el-table__body .cell')[7]; // second row + const cell2 = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row + + triggerEvent(cell2.parentNode, 'mouseenter'); + triggerEvent(cell.parentNode, 'mouseleave'); + expect(vm.result).to.length(4); // row, column, cell, event + expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('cell-click', done => { + const vm = createTable('cell-click'); + + setTimeout(_ => { + const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row + + cell.parentNode.click(); + expect(vm.result).to.length(4); // row, column, cell, event + expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('row-click', done => { + const vm = createTable('row-click'); + + setTimeout(_ => { + const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row + + triggerEvent(cell.parentNode.parentNode, 'click'); + expect(vm.result).to.length(3); // row, event, column + expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('row-dblclick', done => { + const vm = createTable('row-dblclick'); + + setTimeout(_ => { + const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row + + triggerEvent(cell.parentNode.parentNode, 'dblclick'); + expect(vm.result).to.length(3); // row, event, column + expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('current-change', done => { + const vm = createTable('current-change'); + + setTimeout(_ => { + const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row + + triggerEvent(cell.parentNode.parentNode, 'click'); + expect(vm.result).to.length(2); // currentRow, oldCurrentRow + expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name); + expect(vm.result[1]).to.equal(null); + + // clear data => current-change should fire again. + const oldRow = vm.result[0]; + vm.testData = []; + + setTimeout(() => { + expect(vm.result).to.length(2); // currentRow, oldCurrentRow + expect(vm.result[0]).to.equal(null); + expect(vm.result[1]).to.equal(oldRow); + + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + + it('header-click', done => { + const vm = createTable('header-click'); + + setTimeout(_ => { + const cell = vm.$el.querySelectorAll('.el-table__header th')[1]; // header[prop='name'] + + triggerEvent(cell, 'click'); + expect(vm.result).to.length(2); // column, event + expect(vm.result[0]).to.have.property('property').to.equal('name'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('sort-change', async() => { + const vm = createVue({ + template: ` + + + + + + + `, + + data() { + return { testData: getTestData() }; + } + }); + + const spy = sinon.spy(); + vm.$refs.table.$on('sort-change', spy); + await waitImmediate(); + expect(spy.notCalled).to.be.true;// not emit when mounted + + const elm = vm.$el.querySelector('.caret-wrapper'); + elm.click(); + await waitImmediate(); + expect(spy.calledOnce).to.be.true; + destroyVM(vm); + }); + }); + + describe('column attributes', () => { + const createTable = function(props1, props2, props3, props4, opts, tableProps) { + return createVue(Object.assign({ + template: ` + + + + + + + `, + + created() { + this.testData = getTestData(); + } + }, opts)); + }; + + it('label', done => { + const vm = createTable('label="啊哈哈哈"', 'label="啊啦啦啦"'); + setTimeout(_ => { + const ths = toArray(vm.$el.querySelectorAll('thead th')) + .map(node => node.textContent).filter(o => o); + + expect(ths).to.eql(['啊哈哈哈', '啊啦啦啦']); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('width', done => { + const vm = createTable('width="123px"', ':width="102"', 'width="39"'); + setTimeout(_ => { + const ths = toArray(vm.$el.querySelectorAll('.el-table__header-wrapper col')) + .map(node => node.width).filter(o => o); + + expect(ths).to.include('123').include('102').include('39'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('fixed', done => { + const vm = createTable( + 'fixed label="test1"', + 'fixed="right" label="test2"', + 'fixed="left" label="test3"'); + setTimeout(_ => { + expect(toArray(vm.$el.querySelectorAll('.el-table__fixed th:not(.is-hidden)')) + .map(node => node.textContent)) + .to.eql(['test1', 'test3']); + + expect(toArray(vm.$el.querySelectorAll('.el-table__fixed-right th:not(.is-hidden)')) + .map(node => node.textContent)) + .to.eql(['test2']); + expect(vm.$el.querySelector('.el-table__body-wrapper').style.height).to.equal(''); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('resizable', done => { + const vm = createTable( + 'resizable', + ':resizable="false"', + '', + '', + {}, + 'border'); + + setTimeout(_ => { + const firstCol = vm.$el.querySelector('thead th'); + triggerEvent(firstCol, 'mousemove'); + triggerEvent(firstCol, 'mousedown'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('formatter', done => { + const vm = createTable( + ':formatter="renderCell"', '', '', '', { + methods: { + renderCell(row, column) { + return `[${row.name}]`; + } + } + }); + + setTimeout(_ => { + const cells = toArray(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:first-child')); + expect(cells.map(n => n.textContent)).to.eql(getTestData().map(o => `[${o.name}]`)); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('show-overflow-tooltip', done => { + const vm = createTable('show-overflow-tooltip'); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-tooltip')).to.length(5); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('show-tooltip-when-overflow', done => { // old version prop name + const vm = createTable('show-tooltip-when-overflow'); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-tooltip')).to.length(5); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('render-header', done => { + const vm = createVue({ + template: ` + + + + + + + + + `, + + created() { + this.testData = getTestData(); + } + }); + + setTimeout(_ => { + const headerCell = vm.$el.querySelector('.el-table__header-wrapper thead tr th:first-child .cell'); + expect(headerCell.textContent.trim()).to.equal('0:name'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('align', done => { + const vm = createTable('align="left"', 'align="right"', 'align="center"'); + setTimeout(_ => { + var len = getTestData().length + 1; + expect(vm.$el.querySelectorAll('.is-left')).to.length(len); + expect(vm.$el.querySelectorAll('.is-right')).to.length(len); + expect(vm.$el.querySelectorAll('.is-center')).to.length(len); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('class-name', done => { + const vm = createTable('class-name="column-1"', 'class-name="column-2 column-class-a"', 'class-name="column-class-a"'); + setTimeout(_ => { + var len = getTestData().length + 1; + expect(vm.$el.querySelectorAll('.column-1')).to.length(len); + expect(vm.$el.querySelectorAll('.column-2')).to.length(len); + expect(vm.$el.querySelectorAll('.column-class-a')).to.length(len * 2); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('selectable', done => { + const vm = createVue({ + template: ` + + + + + + + + `, + + created() { + this.testData = getTestData(); + }, + + data() { + return { selected: [] }; + }, + + methods: { + change(rows) { + this.selected = rows; + }, + + filterSelect(row, index) { + return index > 2; + } + } + }, true); + + setTimeout(_ => { + vm.$el.querySelector('.el-checkbox').click(); + setTimeout(_ => { + expect(vm.selected).to.length(2); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + + it('selectable === false & check selectAll status', done => { + const vm = createVue({ + template: ` + + + + + + + + `, + + created() { + }, + + data() { + return { selected: [], testData: null }; + }, + + methods: { + change(rows) { + this.selected = rows; + }, + + filterSelect(row, index) { + return false; + } + } + }, true); + + vm.testData = getTestData(); + + setTimeout(_ => { + expect(vm.$el.querySelector('.el-checkbox').__vue__.checked).to.be.false; + setTimeout(_ => { + expect(vm.selected).to.length(0); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + + it('emit selection-change after row has been removed', done => { + const vm = createVue({ + template: ` + + + + + + + + `, + + created() { + this.testData = getTestData(); + }, + + data() { + return { selected: [], testData: null }; + }, + + methods: { + change(rows) { + this.selected = rows; + }, + + filterSelect(row, index) { + return index > 2; + } + } + }, true); + + setTimeout(_ => { + vm.$el.querySelector('.el-checkbox').click(); + setTimeout(_ => { + expect(vm.selected).to.length(5); + vm.testData.splice(0, 1); + setTimeout(_ => { + expect(vm.selected).to.length(4); + destroyVM(vm); + done(); + }); + }, DELAY); + }, DELAY); + }); + + describe('type', () => { + const createTable = function(type) { + return createVue({ + template: ` + + + + + + + + `, + + created() { + this.testData = getTestData(); + }, + + data() { + return { selected: [] }; + }, + + methods: { + change(rows) { + this.selected = rows; + } + } + }, true); + }; + + describe('= selection', () => { + const vm = createTable('selection'); + + it('render', done => { + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-checkbox')).to.length(getTestData().length + 1); + done(); + }, DELAY); + }); + + it('select all', done => { + vm.$el.querySelector('.el-checkbox').click(); + + setTimeout(_ => { + expect(vm.selected).to.length(getTestData().length); + done(); + }, DELAY); + }); + + it('cancel all', done => { + vm.$el.querySelector('.el-checkbox').click(); + + setTimeout(_ => { + expect(vm.selected).to.length(0); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('select one', done => { + const vm2 = createTable('selection'); + + setTimeout(_ => { + vm2.$el.querySelectorAll('.el-checkbox')[1].click(); + + setTimeout(_ => { + expect(vm2.selected).to.length(1); + expect(vm2.selected[0].name).to.equal(getTestData()[0].name); + destroyVM(vm2); + done(); + }, DELAY); + }, DELAY); + }); + }); + + describe('= index', () => { + const vm = createTable('index'); + + it('render', done => { + setTimeout(_ => { + expect(toArray(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:first-child')) + .map(node => node.textContent)).to.eql(['1', '2', '3', '4', '5']); + destroyVM(vm); + done(); + }, DELAY); + }); + }); + + describe('= expand', () => { + const createInstance = function(extra) { + extra = extra || ''; + return createVue({ + template: ` + + + + + + + + + `, + + data() { + return { expandCount: 0, expandRowKeys: [], testData: getTestData() }; + }, + + methods: { + handleExpand() { + this.expandCount++; + }, + refreshData() { + this.testData = getTestData(); + } + } + }, true); + }; + + it('works', done => { + const vm = createInstance(); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('td.el-table__expand-column').length).to.equal(5); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('should expand when click icon', done => { + const vm = createInstance(); + setTimeout(_ => { + vm.$el.querySelector('td.el-table__expand-column .el-table__expand-icon').click(); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(1); + expect(vm.expandCount).to.equal(1); + vm.$el.querySelector('td.el-table__expand-column .el-table__expand-icon').click(); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(0); + expect(vm.expandCount).to.equal(2); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }); + + it('should set expanded rows using expandRowKeys', done => { + const vm = createInstance(':expand-row-keys="expandRowKeys"'); + setTimeout(_ => { + vm.expandRowKeys = [1, 3]; + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(2); + vm.expandRowKeys = [2]; + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(1); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }); + + it('should default-expand-all when default-expand-all is true', done => { + const vm = createInstance('default-expand-all'); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(5); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('should unexpand after refresh data and click', function(done) { + const vm = createInstance(); + setTimeout(_ => { + vm.$el.querySelector('td.el-table__expand-column .el-table__expand-icon').click(); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(1); + expect(vm.expandCount).to.equal(1); + vm.refreshData(); + setTimeout(_ => { // wait until refreshed + expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(1); + vm.$el.querySelector('td.el-table__expand-column .el-table__expand-icon').click(); + setTimeout(_ => { + // should unexpand + expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(0); + expect(vm.expandCount).to.equal(2); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }, DELAY); + }); + }); + }); + + describe('sortable', () => { + + it('render', done => { + const vm = createTable('', '', '', 'sortable'); + setTimeout(_ => { + expect(vm.$el.querySelectorAll('.caret-wrapper')).to.length(1); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('sortable orders', done => { + const vm = createTable('', '', '', 'sortable :sort-orders="[\'descending\', \'ascending\']"', {}); + + setTimeout(_ => { + const elm = vm.$el.querySelector('.caret-wrapper'); + elm.click(); + + setTimeout(_ => { + const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child'); + expect(toArray(lastCells).map(node => node.textContent)).to.eql(['100', '95', '92', '92', '80']); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + + it('sortable method', done => { + const vm = createTable( + 'sortable :sort-method="sortMethod"', '', '', '', { + methods: { + sortMethod(a, b) { + // sort method should return number + if (a.runtime < b.runtime) { + return 1; + } + if (a.runtime > b.runtime) { + return -1; + } + return 0; + } + } + }); + + setTimeout(_ => { + const elm = vm.$el.querySelector('.caret-wrapper'); + elm.click(); + + setTimeout(_ => { + const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child'); + expect(toArray(lastCells).map(node => node.textContent)).to.eql(['100', '95', '92', '92', '80']); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + + it('sortable by method', done => { + const vm = createTable( + 'sortable :sort-by="sortBy"', '', '', '', { + methods: { + sortBy(a) { + return -a.runtime; + } + } + }); + + setTimeout(_ => { + const elm = vm.$el.querySelector('.caret-wrapper'); + elm.click(); + + setTimeout(_ => { + const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child'); + expect(toArray(lastCells).map(node => node.textContent)).to.eql(['100', '95', '92', '92', '80']); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + + it('sortable by property', done => { + const vm = createTable( + 'sortable sort-by="runtime"', '', '', '', {}); + + setTimeout(_ => { + const elm = vm.$el.querySelector('.caret-wrapper'); + elm.click(); + + setTimeout(_ => { + const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child'); + expect(toArray(lastCells).map(node => node.textContent)).to.eql(['80', '92', '92', '95', '100']); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + }); + + describe('click sortable column', () => { + const vm = createTable('', '', '', 'sortable'); + + it('ascending', done => { + const elm = vm.$el.querySelector('.caret-wrapper'); + + elm.click(); + setTimeout(_ => { + const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child'); + expect(toArray(lastCells).map(node => node.textContent)) + .to.eql(['80', '92', '92', '95', '100']); + done(); + }, DELAY); + }); + + it('descending', done => { + const elm = vm.$el.querySelector('.caret-wrapper'); + + elm.click(); + setTimeout(_ => { + const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child'); + expect(toArray(lastCells).map(node => node.textContent)) + .to.eql(['100', '95', '92', '92', '80']); + destroyVM(vm); + done(); + }, DELAY); + }); + }); + }); + + describe('summary row', () => { + it('should render', done => { + const vm = createVue({ + template: ` + + + + + + + `, + + created() { + this.testData = getTestData(); + } + }, true); + + setTimeout(_ => { + const footer = vm.$el.querySelector('.el-table__footer'); + expect(footer).to.exist; + const cells = toArray(footer.querySelectorAll('.cell')); + expect(cells[cells.length - 1].innerText).to.equal('459'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('custom sum text', done => { + const vm = createVue({ + template: ` + + + + + + + `, + + created() { + this.testData = getTestData(); + } + }, true); + + setTimeout(_ => { + const cells = toArray(vm.$el.querySelectorAll('.el-table__footer .cell')); + expect(cells[0].innerText).to.equal('Time'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('custom summary method', done => { + const vm = createVue({ + template: ` + + + + + + + `, + + created() { + this.testData = getTestData(); + }, + + methods: { + getSummary(param) { + const { columns, data } = param; + const result = []; + columns.forEach(column => { + const prop = column.property; + if (prop === 'release') { + const dates = data.map(item => item[prop]); + const releaseYears = dates.map(date => Number(date.slice(0, 4))); + result.push(releaseYears.reduce((prev, curr) => { + return prev + curr; + })); + } else { + result.push(''); + } + }); + return result; + } + } + }, true); + + setTimeout(_ => { + const cells = toArray(vm.$el.querySelectorAll('.el-table__footer .cell')); + expect(cells[1].innerText).to.equal('9996'); + destroyVM(vm); + done(); + }, DELAY); + }); + }); + + describe('multi level column', () => { + it('should works', done => { + const vm = createVue({ + template: ` + + + + + + + + + `, + + created() { + this.testData = null; + } + }, true); + + setTimeout(_ => { + const trs = vm.$el.querySelectorAll('.el-table__header tr'); + expect(trs.length).equal(2); + const firstRowHeader = trs[0].querySelectorAll('th .cell').length; + const secondRowHeader = trs[1].querySelectorAll('th .cell').length; + expect(firstRowHeader).to.equal(3); + expect(secondRowHeader).to.equal(2); + + expect(trs[0].querySelector('th:first-child').getAttribute('rowspan')).to.equal('2'); + expect(trs[0].querySelector('th:nth-child(2)').getAttribute('colspan')).to.equal('2'); + destroyVM(vm); + done(); + }, DELAY); + }); + + it('should works', done => { + const vm = createVue({ + template: ` + + + + + + + + + + + + `, + + created() { + this.testData = null; + } + }, true); + + setTimeout(_ => { + const trs = vm.$el.querySelectorAll('.el-table__header tr'); + expect(trs.length).equal(3); + const firstRowHeader = trs[0].querySelectorAll('th .cell').length; + const secondRowHeader = trs[1].querySelectorAll('th .cell').length; + const thirdRowHeader = trs[2].querySelectorAll('th .cell').length; + expect(firstRowHeader).to.equal(3); + expect(secondRowHeader).to.equal(2); + expect(thirdRowHeader).to.equal(2); + + expect(trs[0].querySelector('th:first-child').getAttribute('rowspan')).to.equal('3'); + expect(trs[0].querySelector('th:nth-child(2)').getAttribute('colspan')).to.equal('3'); + expect(trs[1].querySelector('th:first-child').getAttribute('colspan')).to.equal('2'); + expect(trs[1].querySelector('th:nth-child(2)').getAttribute('rowspan')).to.equal('2'); + + destroyVM(vm); + done(); + }, DELAY); + }); + + it('should work in one column', done => { + const vm = createVue({ + template: ` + + + + + + `, + + created() { + this.testData = null; + } + }, true); + + setTimeout(_ => { + const trs = vm.$el.querySelectorAll('.el-table__header tr'); + expect(trs.length).equal(2); + const firstRowLength = trs[0].querySelectorAll('th .cell').length; + const secondRowLength = trs[1].querySelectorAll('th .cell').length; + expect(firstRowLength).to.equal(1); + expect(secondRowLength).to.equal(1); + + expect(trs[0].querySelector('th:first-child').getAttribute('rowspan')).to.equal('1'); + expect(trs[0].querySelector('th:first-child').getAttribute('colspan')).to.equal('1'); + destroyVM(vm); + done(); + }, DELAY); + }); + }); + + describe('dynamic column attribtes', () => { + const DELAY = 50; + + it('label', (done) => { + const vm = createVue({ + template: ` + + + + + + + `, + + data() { + return { + label: 'name' + }; + }, + + created() { + this.testData = getTestData(); + } + }, true); + + setTimeout(() => { + expect(vm.$el.querySelector('.el-table__header th .cell').textContent).to.equal('name'); + vm.label = 'NAME'; + vm.$nextTick(() => { + expect(vm.$el.querySelector('.el-table__header th .cell').textContent).to.equal('NAME'); + destroyVM(vm); + done(); + }); + }, DELAY); + }); + + it('align', (done) => { + const vm = createVue({ + template: ` + + + + `, + + data() { + return { + align: 'left' + }; + }, + + created() { + this.testData = getTestData(); + } + }, true); + + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-table__body td.is-right').length === 0).to.be.true; + vm.align = 'right'; + vm.$nextTick(() => { + expect(vm.$el.querySelectorAll('.el-table__body td.is-right').length > 0).to.be.true; + destroyVM(vm); + done(); + }); + }, DELAY); + }); + + it('header-align', (done) => { + const vm = createVue({ + template: ` + + + + `, + + data() { + return { + align: 'left', + headerAlign: null + }; + }, + + created() { + this.testData = getTestData(); + } + }, true); + + vm.$nextTick(() => { + expect(vm.$el.querySelectorAll('.el-table__header th.is-left').length).to.above(0); + expect(vm.$el.querySelectorAll('.el-table__header th.is-center').length).to.equal(0); + expect(vm.$el.querySelectorAll('.el-table__header th.is-right').length).to.equal(0); + vm.align = 'right'; + vm.$nextTick(() => { + expect(vm.$el.querySelectorAll('.el-table__header th.is-left').length).to.equal(0); + expect(vm.$el.querySelectorAll('.el-table__header th.is-center').length).to.equal(0); + expect(vm.$el.querySelectorAll('.el-table__header th.is-right').length).to.above(0); + vm.headerAlign = 'center'; + vm.$nextTick(() => { + expect(vm.$el.querySelectorAll('.el-table__header th.is-left').length).to.equal(0); + expect(vm.$el.querySelectorAll('.el-table__header th.is-center').length).to.above(0); + expect(vm.$el.querySelectorAll('.el-table__header th.is-right').length).to.equal(0); + vm.headerAlign = null; + vm.$nextTick(() => { + expect(vm.$el.querySelectorAll('.el-table__header th.is-left').length).to.equal(0); + expect(vm.$el.querySelectorAll('.el-table__header th.is-center').length).to.equal(0); + expect(vm.$el.querySelectorAll('.el-table__header th.is-right').length).to.above(0); + destroyVM(vm); + done(); + }); + }); + }); + }); + }); + + it('width', (done) => { + const vm = createVue({ + template: ` + + + + `, + + data() { + return { + width: 100 + }; + }, + + created() { + this.testData = getTestData(); + } + }, true); + + setTimeout(() => { + expect(vm.$el.querySelector('.el-table__body col').getAttribute('width')).to.equal('100'); + vm.width = 200; + setTimeout(() => { + expect(vm.$el.querySelector('.el-table__body col').getAttribute('width')).to.equal('200'); + destroyVM(vm); + done(); + }, 100); + }, DELAY); + }); + + it('min-width', (done) => { + const vm = createVue({ + template: ` + + + + `, + + data() { + return { + width: 100 + }; + }, + + created() { + this.testData = getTestData(); + } + }, true); + + setTimeout(() => { + expect(vm.$el.querySelector('.el-table__body col').getAttribute('width')).to.equal('100'); + vm.width = 200; + setTimeout(() => { + expect(vm.$el.querySelector('.el-table__body col').getAttribute('width')).to.equal('200'); + destroyVM(vm); + done(); + }, 100); + }, DELAY); + }); + + it('fixed', (done) => { + const vm = createVue({ + template: ` + + + + + + + `, + + data() { + return { + fixed: false + }; + }, + + created() { + this.testData = getTestData(); + } + }, true); + + setTimeout(() => { + expect(!vm.$el.querySelector('.el-table__fixed')).to.be.true; + vm.fixed = true; + setTimeout(() => { + expect(!!vm.$el.querySelector('.el-table__fixed')).to.be.true; + destroyVM(vm); + done(); + }, 100); + }, DELAY); + }); + + it('prop', (done) => { + const vm = createVue({ + template: ` + + + + + + + `, + + data() { + return { + prop: 'name' + }; + }, + + created() { + this.testData = getTestData(); + } + }, true); + + setTimeout(() => { + let firstColumnContent = vm.$el.querySelector('.el-table__body td .cell').textContent; + let secondColumnContent = vm.$el.querySelector('.el-table__body td:nth-child(2) .cell').textContent; + expect(firstColumnContent !== secondColumnContent).to.be.true; + vm.prop = 'release'; + setTimeout(() => { + firstColumnContent = vm.$el.querySelector('.el-table__body td .cell').textContent; + secondColumnContent = vm.$el.querySelector('.el-table__body td:nth-child(2) .cell').textContent; + expect(firstColumnContent === secondColumnContent).to.be.true; + destroyVM(vm); + done(); + }, 100); + }, DELAY); + }); + }); + + describe('methods', () => { + const createTable = function(prop = '', opts) { + return createVue({ + template: ` + + + + + + + + `, + + methods: { + handleEvent(selection) { + this.fireCount++; + this.selection = selection; + } + }, + + created() { + this.testData = getTestData(); + }, + + data() { + return { selection: null, testData: this.testData, fireCount: 0 }; + } + }, true); + }; + + it('toggleRowSelection', () => { + const vm = createTable('selection-change'); + vm.$refs.table.toggleRowSelection(vm.testData[0]); + expect(vm.selection).to.length(1); + expect(vm.fireCount).to.equal(1); + + // test use second parameter + vm.$refs.table.toggleRowSelection(vm.testData[0], true); + expect(vm.fireCount).to.equal(1); + + vm.$refs.table.toggleRowSelection(vm.testData[0], false); + expect(vm.fireCount).to.equal(2); + expect(vm.selection).to.length(0); + + destroyVM(vm); + }); + + it('toggleAllSelection', done => { + const vm = createTable('selection-change'); + vm.$refs.table.toggleAllSelection(); + setTimeout(() => { + expect(vm.selection).to.length(5); + + vm.$refs.table.toggleAllSelection(); + setTimeout(() => { + expect(vm.selection).to.length(0); + destroyVM(vm); + done(); + }, 50); + }, 50); + }); + + it('toggleAllSelection debounce', async() => { + const spy = sinon.spy(); + const vm = createVue({ + template: ` +
+ + + + + + + + +
+ `, + + data() { + return { + testData: getTestData(), + testData1: getTestData() + }; + }, + + methods: { + change(selection) { + spy(selection); + } + }, + + mounted() { + this.$refs.table.toggleAllSelection(); + this.$refs.table1.toggleAllSelection(); + } + }, true); + + await wait(50); + expect(spy.callCount).to.be.equal(2); + expect(spy.args[0][0].length).to.be.equal(5); + expect(spy.args[1][0].length).to.be.equal(5); + destroyVM(vm); + }); + + it('clearSelection', () => { + const vm = createTable('selection-change'); + vm.$refs.table.toggleRowSelection(vm.testData[0]); + expect(vm.selection).to.length(1); + expect(vm.fireCount).to.equal(1); + + // clear selection + vm.$refs.table.clearSelection(); + expect(vm.fireCount).to.equal(2); + expect(vm.selection).to.length(0); + + vm.$refs.table.clearSelection(); + expect(vm.fireCount).to.equal(2); + + destroyVM(vm); + }); + + it('sort', done => { + const vm = createVue({ + template: ` + + + + + + + `, + + created() { + this.testData = getTestData(); + }, + + data() { + return { testData: this.testData }; + } + }); + + setTimeout(() => { + const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child'); + expect(toArray(lastCells).map(node => node.textContent)) + .to.eql(['80', '92', '92', '95', '100']); + + vm.$nextTick(() => { + vm.testData = vm.testData.map(data => Object.assign(data, { runtime: -data.runtime })); + vm.$refs.table.sort('runtime', 'ascending'); + vm.$nextTick(() => { + expect(toArray(lastCells).map(node => node.textContent)) + .to.eql(['-100', '-95', '-92', '-92', '-80']); + destroyVM(vm); + done(); + }); + }); + }, DELAY); + }); + + it('sort correct change icon', async() => { + function assertSortIconCount($el, msg, count = 1) { + const sortIconCount = $el.querySelectorAll('th.ascending, th.descending').length; + expect(sortIconCount).to.equal(count, msg); + } + + const vm = createVue({ + template: ` + + + + + + + `, + data() { + return { testData: getTestData() }; + } + }); + await waitImmediate(); + assertSortIconCount(vm.$el, 'sorting icon is not empty after mount', 0); + // manual click first column header + const elm = vm.$el.querySelector('.caret-wrapper'); + elm.click(); + await waitImmediate(); + assertSortIconCount(vm.$el, 'sorting icon is not one after click header'); + vm.$refs.table.sort('director', 'descending'); + await waitImmediate(); + assertSortIconCount(vm.$el, 'sorting icon is not one after call sort'); + vm.$refs.table.sort('director', 'ascending'); + await waitImmediate(); + assertSortIconCount(vm.$el, 'sorting icon is not one after sort same column'); + destroyVM(vm); + }); + + it('setCurrentRow', async() => { + const vm = createVue({ + template: ` +
+ + + + + + + +
+ `, + data() { + return { testData: getTestData() }; + }, + methods: { + clear() { + this.$refs.table.setCurrentRow(); + } + } + }); + + vm.$refs.table.setCurrentRow(vm.testData[1]); + await waitImmediate(); + const secondRow = vm.$el.querySelectorAll('.el-table__row')[1]; + expect(secondRow.classList.contains('current-row')).to.true; + + vm.$el.querySelector('.clear').click(); + await waitImmediate(); + expect(secondRow.classList.contains('current-row')).to.false; + + destroyVM(vm); + }); + }); + + it('hover', async() => { + const vm = createVue({ + template: ` + + + + + + + `, + data() { + return { + testData: getTestData() + }; + } + }, true); + await waitImmediate(); + const tr = vm.$el.querySelector('.el-table__body-wrapper tbody tr'); + triggerEvent(tr, 'mouseenter', true, false); + + await wait(50); + expect(tr.classList.contains('hover-row')).to.true; + triggerEvent(tr, 'mouseleave', true, false); + + await wait(50); + expect(tr.classList.contains('hover-row')).to.false; + destroyVM(vm); + }); + + it('highlight-current-row', done => { + const vm = createVue({ + template: ` + + + + + + + `, + + created() { + this.testData = getTestData(); + } + }, true); + setTimeout(_ => { + const tr = vm.$el.querySelector('.el-table__body-wrapper tbody tr'); + triggerEvent(tr, 'click', true, false); + setTimeout(_ => { + expect(tr.classList.contains('current-row')).to.be.true; + const rows = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr'); + + triggerEvent(rows[1], 'click', true, false); + setTimeout(_ => { + expect(tr.classList.contains('current-row')).to.be.false; + expect(rows[1].classList.contains('current-row')).to.be.true; + + const ths = vm.$el.querySelectorAll('.el-table__header-wrapper thead th'); + triggerEvent(ths[3], 'click', true, false); + + setTimeout(_ => { + const rows = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr'); + + expect(rows[1].classList.contains('current-row')).to.be.false; + expect(rows[3].classList.contains('current-row')).to.be.true; + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }, DELAY); + }); + + it('keep highlight row when data change', done => { + const vm = createVue({ + template: ` + + + + + + + `, + data() { + return { + testData: getTestData() + }; + } + }, true); + setTimeout(() => { + let rows = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr'); + triggerEvent(rows[2], 'click', true, false); + setTimeout(() => { + expect(rows[2].classList.contains('current-row')).to.be.true; + const data = getTestData(); + data.splice(0, 0, { + id: 8, + name: 'Monsters, Inc.', + release: '2018-02-01', + director: 'Peter Docter', + runtime: 92 + }); + data[2].name = 'Modified Name'; + vm.testData = data; + + setTimeout(() => { + rows = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr'); + expect(rows[3].classList.contains('current-row')).to.be.true; + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }); + + it('keep highlight row after sort', done => { + const vm = createVue({ + template: ` + + + + + + + `, + data() { + return { + testData: getTestData() + }; + } + }, true); + setTimeout(() => { + let rows = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr'); + triggerEvent(rows[1], 'click', true, false); + setTimeout(() => { + expect(rows[1].classList.contains('current-row')).to.be.true; + const cells = vm.$el.querySelectorAll('.el-table__header-wrapper thead th > .cell'); + triggerEvent(cells[3], 'click', true, false); + + setTimeout(() => { + rows = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr'); + expect(rows[3].classList.contains('current-row')).to.be.true; + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }, DELAY); + }); + + it('table append is visible in viewport if height is 100%', async() => { + const vm = createVue({ + template: ` + + + + + + + + ` + }, true); + await waitImmediate(); + const emptyBlockEl = vm.$el.querySelector('.el-table__empty-block'); + expect(emptyBlockEl.style.height).to.be.equal('calc(100% - 48px)'); + destroyVM(vm); + }); + + describe('tree', () => { + let vm; + afterEach(() => destroyVM(vm)); + it('render tree structual data', async() => { + vm = createVue({ + template: ` + + + + + + + `, + data() { + const testData = getTestData(); + testData[1].children = [ + { + name: 'A Bug\'s Life copy 1', release: '1998-11-25-1', director: 'John Lasseter', runtime: 95 + }, + { + name: 'A Bug\'s Life copy 2', release: '1998-11-25-2', director: 'John Lasseter', runtime: 95 + } + ]; + return { + testData: testData + }; + } + }, true); + await waitImmediate(); + + const rows = vm.$el.querySelectorAll('.el-table__row'); + expect(rows.length).to.equal(7); + const childRows = vm.$el.querySelectorAll('.el-table__row--level-1'); + expect(childRows.length).to.equal(2); + childRows.forEach(item => { + expect(item.style.display).to.equal('none'); + }); + vm.$el.querySelector('.el-table__expand-icon').click(); + + await waitImmediate(); + childRows.forEach(item => { + expect(item.style.display).to.equal(''); + }); + }); + + it('load substree row data', async() => { + vm = createVue({ + template: ` + + + + + + + `, + data() { + const testData = getTestData(); + testData[testData.length - 1].children = [ + { + name: 'A Bug\'s Life copy 1', release: '2008-1-25-1', director: 'John Lasseter', runtime: 95 + } + ]; + testData[1].hasChildren = true; + return { + testData: testData + }; + }, + methods: { + load(row, treeNode, resolve) { + resolve([ + { + name: 'A Bug\'s Life copy 1', release: '1998-11-25-1', director: 'John Lasseter', runtime: 95 + }, + { + name: 'A Bug\'s Life copy 2', release: '1998-11-25-2', director: 'John Lasseter', runtime: 95 + } + ]); + } + } + }, true); + await waitImmediate(); + + const expandIcon = vm.$el.querySelector('.el-table__expand-icon'); + expandIcon.click(); + + await waitImmediate(); + + expect(expandIcon.classList.contains('el-table__expand-icon--expanded')).to.be.true; + expect(vm.$el.querySelectorAll('.el-table__row').length).to.equal(8); + }); + + it('tree-props & default-expand-all & expand-change', async() => { + const spy = sinon.spy(); + vm = createVue({ + template: ` + + + + + + + `, + data() { + const testData = getTestData(); + testData[testData.length - 1].childrenTest = [ + { + name: 'A Bug\'s Life copy 1', release: '2008-1-25-1', director: 'John Lasseter', runtime: 95 + } + ]; + testData[1].hasChildrenTest = true; + return { + testData: testData + }; + }, + methods: { + load(row, treeNode, resolve) { + resolve([ + { + name: 'A Bug\'s Life copy 1', release: '1998-11-25-1', director: 'John Lasseter', runtime: 95 + }, + { + name: 'A Bug\'s Life copy 2', release: '1998-11-25-2', director: 'John Lasseter', runtime: 95 + } + ]); + }, + change: spy + } + }, true); + await waitImmediate(); + const childRows = vm.$el.querySelectorAll('.el-table__row--level-1'); + childRows.forEach(item => { + expect(item.style.display).to.equal(''); + }); + const expandIcon = vm.$el.querySelector('.el-table__expand-icon'); + expandIcon.click(); + + await waitImmediate(); + + expect(expandIcon.classList.contains('el-table__expand-icon--expanded')).to.be.true; + expect(vm.$el.querySelectorAll('.el-table__row').length).to.equal(8); + expect(spy.args[0][0]).to.be.an('object'); + expect(spy.args[0][1]).to.be.true; + }); + + it('expand-row-keys & toggleRowExpansion', async() => { + vm = createVue({ + template: ` + + + + + + + `, + data() { + const testData = getTestData(); + testData[testData.length - 1].children = [ + { + name: 'A Bug\'s Life copy 1', release: '2003-5-30-1', director: 'John Lasseter', runtime: 95, + hasChildren: true + } + ]; + return { + testData: testData + }; + }, + methods: { + load(row, treeNode, resolve) { + resolve([ + { + name: 'A Bug\'s Life copy 1', release: '2003-5-30-2', director: 'John Lasseter', runtime: 95 + } + ]); + }, + closeExpandRow() { + const testData = this.testData; + const row = testData[testData.length - 1].children[0]; + this.$refs.table.toggleRowExpansion(row); + } + } + }, true); + await waitImmediate(); + const childRows = vm.$el.querySelectorAll('.el-table__row--level-1'); + childRows.forEach(item => { + expect(item.style.display).to.equal(''); + }); + const expandIcon = childRows[0].querySelector('.el-table__expand-icon'); + expandIcon.click(); + + await waitImmediate(); + + expect(expandIcon.classList.contains('el-table__expand-icon--expanded')).to.be.true; + vm.closeExpandRow(); + + await waitImmediate(); + expect(expandIcon.classList.contains('el-table__expand-icon--expanded')).to.be.false; + }); + }); +}); diff --git a/test/unit/specs/tabs.spec.js b/test/unit/specs/tabs.spec.js new file mode 100644 index 0000000..75702fc --- /dev/null +++ b/test/unit/specs/tabs.spec.js @@ -0,0 +1,609 @@ +import { createVue, destroyVM, triggerKeyDown } from '../util'; + +describe('Tabs', () => { + let vm; + let hasPromise = true; + before(() => { + if (!window.Promise) { + hasPromise = false; + window.Promise = require('es6-promise').Promise; + } + }); + + after(() => { + if (!hasPromise) { + window.Promise = undefined; + } + }); + + afterEach(() => { + destroyVM(vm); + }); + + it('create', done => { + vm = createVue({ + template: ` + + A + B + C + D + + ` + }, true); + + let paneList = vm.$el.querySelector('.el-tabs__content').children; + let spy = sinon.spy(); + + vm.$refs.tabs.$on('tab-click', spy); + + setTimeout(_ => { + const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs; + expect(tabList[0].classList.contains('is-active')).to.be.true; + expect(paneList[0].style.display).to.not.ok; + + tabList[2].click(); + vm.$nextTick(_ => { + expect(spy.withArgs(vm.$refs['pane-click']).calledOnce).to.true; + expect(tabList[2].classList.contains('is-active')).to.be.true; + expect(paneList[2].style.display).to.not.ok; + done(); + }); + }, 100); + }); + it('active-name', done => { + vm = createVue({ + template: ` + + A + B + C + D + + `, + data() { + return { + activeName: 'tab-B' + }; + }, + methods: { + handleClick(tab) { + this.activeName = tab.name; + } + } + }, true); + setTimeout(_ => { + const paneList = vm.$el.querySelector('.el-tabs__content').children; + const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs; + + expect(tabList[1].classList.contains('is-active')).to.be.true; + expect(paneList[1].style.display).to.not.ok; + + tabList[3].click(); + vm.$nextTick(_ => { + expect(tabList[3].classList.contains('is-active')).to.be.true; + expect(paneList[3].style.display).to.not.ok; + expect(vm.activeName === 'tab-D'); + done(); + }); + }, 100); + }); + it('card', () => { + vm = createVue({ + template: ` + + A + B + C + D + + ` + }, true); + + expect(vm.$el.classList.contains('el-tabs--card')).to.be.true; + }); + it('border card', () => { + vm = createVue({ + template: ` + + A + B + C + D + + ` + }, true); + + expect(vm.$el.classList.contains('el-tabs--border-card')).to.be.true; + }); + it('dynamic', (done) => { + vm = createVue({ + template: ` + + Test Content + + `, + data() { + return { + tabs: [{ + label: 'tab1', + name: 'tab1' + }, { + label: 'tab2', + name: 'tab2' + }, { + label: 'tab3', + name: 'tab3' + }, { + label: 'tab4', + name: 'tab4' + }] + }; + } + }, true); + + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-tab-pane').length).to.equal(4); + vm.tabs.push({ + label: 'tab5', + name: 'tab5' + }); + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-tab-pane').length).to.equal(5); + done(); + }); + }, 100); + }); + it('editable', done => { + vm = createVue({ + template: ` + + + {{item.content}} + + + `, + data() { + return { + editableTabsValue: '2', + editableTabs: [{ + title: 'Tab 1', + name: '1', + content: 'Tab 1 content' + }, { + title: 'Tab 2', + name: '2', + content: 'Tab 2 content' + }, { + title: 'Tab 3', + name: '3', + content: 'Tab 3 content' + }], + tabIndex: 3 + }; + }, + methods: { + handleTabsEdit(targetName, action) { + if (action === 'add') { + let newTabName = ++this.tabIndex + ''; + this.editableTabs.push({ + title: 'New Tab', + name: newTabName, + content: 'New Tab content' + }); + this.editableTabsValue = newTabName; + } + if (action === 'remove') { + let tabs = this.editableTabs; + let activeName = this.editableTabsValue; + if (activeName === targetName) { + tabs.forEach((tab, index) => { + if (tab.name === targetName) { + let nextTab = tabs[index + 1] || tabs[index - 1]; + if (nextTab) { + activeName = nextTab.name; + } + } + }); + } + this.editableTabsValue = activeName; + this.editableTabs = tabs.filter(tab => tab.name !== targetName); + } + } + } + }, true); + + setTimeout(_ => { + const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs; + const paneList = vm.$el.querySelector('.el-tabs__content').children; + + tabList[1].querySelector('.el-icon-close').click(); + setTimeout(_ => { + expect(tabList.length).to.be.equal(2); + expect(paneList.length).to.be.equal(2); + expect(tabList[1].classList.contains('is-active')).to.be.true; + + vm.$refs.tabs.$el.querySelector('.el-tabs__new-tab').click(); + setTimeout(_ => { + expect(tabList.length).to.be.equal(3); + expect(paneList.length).to.be.equal(3); + expect(tabList[2].classList.contains('is-active')).to.be.true; + done(); + }, 100); + }, 100); + }, 100); + }); + it('addable & closable', done => { + vm = createVue({ + template: ` + + + {{item.content}} + + + `, + data() { + return { + editableTabsValue: '2', + editableTabs: [{ + title: 'Tab 1', + name: '1', + content: 'Tab 1 content' + }, { + title: 'Tab 2', + name: '2', + content: 'Tab 2 content' + }], + tabIndex: 2 + }; + }, + methods: { + addTab(targetName) { + let newTabName = ++this.tabIndex + ''; + this.editableTabs.push({ + title: 'New Tab', + name: newTabName, + content: 'New Tab content' + }); + this.editableTabsValue = newTabName; + }, + removeTab(targetName) { + let tabs = this.editableTabs; + let activeName = this.editableTabsValue; + if (activeName === targetName) { + tabs.forEach((tab, index) => { + if (tab.name === targetName) { + let nextTab = tabs[index + 1] || tabs[index - 1]; + if (nextTab) { + activeName = nextTab.name; + } + } + }); + } + this.editableTabsValue = activeName; + this.editableTabs = tabs.filter(tab => tab.name !== targetName); + } + } + }, true); + + setTimeout(_ => { + const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs; + const paneList = vm.$el.querySelector('.el-tabs__content').children; + + vm.$refs.tabs.$el.querySelector('.el-tabs__new-tab').click(); + + setTimeout(_ => { + expect(tabList.length).to.be.equal(3); + expect(paneList.length).to.be.equal(3); + expect(tabList[2].classList.contains('is-active')).to.be.true; + + tabList[2].querySelector('.el-icon-close').click(); + setTimeout(_ => { + expect(tabList.length).to.be.equal(2); + expect(paneList.length).to.be.equal(2); + expect(tabList[1].classList.contains('is-active')).to.be.true; + done(); + }, 100); + }, 100); + }, 100); + }); + it('closable in tab-pane', (done) => { + vm = createVue({ + template: ` + + A + B + C + D + + ` + }, true); + + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-icon-close').length).to.equal(2); + done(); + }, 100); + }); + it('disabled', done => { + vm = createVue({ + template: ` + + A + B + C + D + + ` + }, true); + + vm.$nextTick(_ => { + const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs; + + tabList[1].click(); + vm.$nextTick(_ => { + expect(tabList[1].classList.contains('is-active')).to.not.true; + done(); + }); + }); + }); + it('tab-position', done => { + vm = createVue({ + template: ` + + A + B + C + D + + ` + }, true); + + let paneList = vm.$el.querySelector('.el-tabs__content').children; + let spy = sinon.spy(); + + vm.$refs.tabs.$on('tab-click', spy); + + setTimeout(_ => { + const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs; + expect(tabList[0].classList.contains('is-active')).to.be.true; + expect(paneList[0].style.display).to.not.ok; + + tabList[2].click(); + vm.$nextTick(_ => { + expect(spy.withArgs(vm.$refs['pane-click']).calledOnce).to.true; + expect(tabList[2].classList.contains('is-active')).to.be.true; + expect(paneList[2].style.display).to.not.ok; + done(); + }); + }, 100); + }); + it('stretch', done => { + vm = createVue({ + template: ` + + A + B + C + D + + `, + data() { + return { + tabPosition: 'bottom' + }; + } + }, true); + + setTimeout(_ => { + expect(vm.$el.querySelector('[role=tablist]').classList.contains('is-stretch')).to.be.true; + + vm.tabPosition = 'left'; + + vm.$nextTick(_ => { + expect(vm.$el.querySelector('[role=tablist]').classList.contains('is-stretch')).not.to.be.true; + done(); + }); + }, 100); + }); + it('horizonal-scrollable', done => { + vm = createVue({ + template: ` + + A + B + A + B + A + B + D + + ` + }, true); + + setTimeout(_ => { + const btnPrev = vm.$el.querySelector('.el-tabs__nav-prev'); + btnPrev.click(); + vm.$nextTick(_ => { + const tabNav = vm.$el.querySelector('.el-tabs__nav-wrap'); + expect(tabNav.__vue__.navOffset).to.be.equal(0); + + const btnNext = vm.$el.querySelector('.el-tabs__nav-next'); + btnNext.click(); + + vm.$nextTick(_ => { + expect(tabNav.__vue__.navOffset).to.not.be.equal(0); + + btnPrev.click(); + + vm.$nextTick(_ => { + expect(tabNav.__vue__.navOffset).to.be.equal(0); + done(); + }); + }); + }); + }, 100); + }); + it('vertical-scrollable', done => { + vm = createVue({ + template: ` + + A + B + A + B + A + B + D + + ` + }, true); + + setTimeout(_ => { + const btnPrev = vm.$el.querySelector('.el-tabs__nav-prev'); + btnPrev.click(); + vm.$nextTick(_ => { + const tabNav = vm.$el.querySelector('.el-tabs__nav-wrap'); + expect(tabNav.__vue__.navOffset).to.be.equal(0); + + const btnNext = vm.$el.querySelector('.el-tabs__nav-next'); + btnNext.click(); + + vm.$nextTick(_ => { + expect(tabNav.__vue__.navOffset).to.not.be.equal(0); + + btnPrev.click(); + + vm.$nextTick(_ => { + expect(tabNav.__vue__.navOffset).to.be.equal(0); + done(); + }); + }); + }); + }, 100); + }); + it('should work with lazy', done => { + vm = createVue({ + template: ` + + A + B + C + D + + ` + }, true); + + expect(vm.$el.querySelector('.el-tabs__content').children.length).to.be.equal(3); + expect(vm.$el.querySelector('.el-tabs__content > #pane-D')).to.be.equal(null); + + setTimeout(_ => { + vm.$el.querySelector('.el-tabs__nav > #tab-D').click(); + vm.$nextTick(() => { + expect(vm.$el.querySelector('.el-tabs__content').children.length).to.be.equal(4); + expect(vm.$el.querySelector('.el-tabs__content > #pane-D')).not.to.be.equal(null); + + vm.$el.querySelector('.el-tabs__nav > #tab-A').click(); + vm.$nextTick(() => { + expect(vm.$el.querySelector('.el-tabs__content').children.length).to.be.equal(4); + expect(vm.$el.querySelector('.el-tabs__content > #pane-D')).not.to.be.equal(null); + done(); + }); + }); + }, 100); + }); + it('before leave', done => { + vm = createVue({ + template: ` + + A + B + C + D + + `, + data() { + return { + activeName: 'tab-B' + }; + }, + methods: { + beforeLeave() { + return new window.Promise((resolve, reject) => { + reject(); + }); + } + } + }, true); + setTimeout(_ => { + const paneList = vm.$el.querySelector('.el-tabs__content').children; + const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs; + + expect(tabList[1].classList.contains('is-active')).to.be.true; + expect(paneList[1].style.display).to.not.ok; + + tabList[3].click(); + vm.$nextTick(_ => { + setTimeout(() => { + expect(tabList[1].classList.contains('is-active')).to.be.true; + expect(paneList[1].style.display).to.not.ok; + expect(vm.activeName === 'tab-B'); + done(); + }, 200); + }); + }, 100); + }); + it('keyboard event', done => { + vm = createVue({ + template: ` + + A + B + C + D + + `, + data() { + return { + activeName: 'second' + }; + } + }, true); + + expect(vm.activeName).to.be.equal('second'); + vm.$nextTick(() => { + triggerKeyDown(vm.$el.querySelector('#tab-second'), 39); + expect(vm.activeName).to.be.equal('third'); + + triggerKeyDown(vm.$el.querySelector('#tab-third'), 39); + expect(vm.activeName).to.be.equal('fourth'); + + triggerKeyDown(vm.$el.querySelector('#tab-fourth'), 39); + expect(vm.activeName).to.be.equal('first'); + + triggerKeyDown(vm.$el.querySelector('#tab-first'), 37); + expect(vm.activeName).to.be.equal('fourth'); + + triggerKeyDown(vm.$el.querySelector('#tab-fourth'), 37); + expect(vm.activeName).to.be.equal('third'); + done(); + }); + }); +}); diff --git a/test/unit/specs/tag.spec.js b/test/unit/specs/tag.spec.js new file mode 100644 index 0000000..b0ddcf1 --- /dev/null +++ b/test/unit/specs/tag.spec.js @@ -0,0 +1,125 @@ +import { createTest, createVue, destroyVM } from '../util'; +import Tag from 'packages/tag'; + +describe('Tag', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.classList.contains('el-tag')).to.be.true; + expect(vm.$el.classList.contains('el-tag__close')).to.be.false; + expect(vm.$el.classList.contains('is-hit')).to.be.false; + expect(vm.$el.classList.contains('md-fade-center')).to.be.false; + }); + + it('text', () => { + vm = createVue({ + template: ` + 标签 + ` + }, true); + expect(vm.$el.textContent.length).to.be.at.least(2); + }); + + it('type', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.classList.contains('el-tag--primary')).to.be.true; + }); + + it('hit', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.classList.contains('is-hit')).to.be.true; + }); + + it('closable', done => { + vm = createVue({ + template: ` + 关闭标签 + `, + data() { + return { + isClose: false + }; + }, + methods: { + handleClose() { + this.isClose = true; + } + } + }, true); + var closeBtn = vm.$el.querySelector('.el-tag .el-tag__close'); + expect(closeBtn).to.exist; + closeBtn.click(); + vm.$nextTick(_ => { + expect(vm.isClose).to.true; + done(); + }); + }); + + it('closeTransition', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.classList.contains('md-fade-center')).to.be.false; + }); + + it('color', () => { + vm = createVue({ + template: ` + + ` + }, true); + expect(vm.$el.style.backgroundColor).to.equal('rgb(0, 0, 0)'); + }); + + it('click', done => { + vm = createVue({ + template: ` + 点击标签 + `, + data() { + return { + clicksCount: 0 + }; + }, + methods: { + handleClick() { + this.clicksCount = this.clicksCount + 1; + } + } + }, true); + + let tag = vm.$refs.tag; + tag.$el.click(); + + setTimeout(_ => { + expect(vm.clicksCount).to.be.equal(1); + done(); + }, 20); + }); + + it('theme', () => { + vm = createTest(Tag, { effect: 'dark' }, true); + const el = vm.$el; + expect(el.className).to.includes('el-tag--dark'); + expect(el.className).to.not.includes('el-tag--light'); + expect(el.className).to.not.includes('el-tag--plain'); + }); +}); diff --git a/test/unit/specs/time-picker.spec.js b/test/unit/specs/time-picker.spec.js new file mode 100644 index 0000000..27248f7 --- /dev/null +++ b/test/unit/specs/time-picker.spec.js @@ -0,0 +1,352 @@ +import { createTest, destroyVM, createVue } from '../util'; +import TimePicker from 'packages/time-picker'; + +const DELAY = 100; + +describe('TimePicker', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(TimePicker, { + placeholder: 'test', + readonly: true + }); + expect(vm.$el.querySelector('input').getAttribute('placeholder')).to.equal('test'); + expect(vm.$el.querySelector('input').getAttribute('readonly')).to.ok; + }); + + it('format', () => { + vm = createTest(TimePicker, { + format: 'HH-mm-ss', + value: new Date(2016, 9, 10, 18, 40) + }); + 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) + }, true); + + const input = vm.$el.querySelector('input'); + + input.blur(); + input.focus(); + input.blur(); + + setTimeout(_ => { + const times = vm.picker.$el.querySelectorAll('.active'); + + expect(times[0].textContent).to.equal('18'); + expect(times[1].textContent).to.equal('40'); + expect(times[2].textContent).to.equal('00'); + done(); + }, DELAY); + }); + + it('select time', done => { + vm = createVue({ + template: '', + data() { + return { + value: '' + }; + } + }, true); + const timePicker = vm.$refs.compo; + const input = timePicker.$el.querySelector('input'); + + input.blur(); + input.focus(); + + setTimeout(_ => { + const list = timePicker.picker.$el.querySelectorAll('.el-time-spinner__list'); + + const hoursEl = list[0]; + const minutesEl = list[1]; + const secondsEl = list[2]; + const hourEl = hoursEl.querySelectorAll('.el-time-spinner__item')[4]; + const minuteEl = minutesEl.querySelectorAll('.el-time-spinner__item')[36]; + const secondEl = secondsEl.querySelectorAll('.el-time-spinner__item')[20]; + + // click hour, minute, second one at a time. + hourEl.click(); + vm.$nextTick(_ => { + minuteEl.click(); + vm.$nextTick(_ => { + secondEl.click(); + setTimeout(_ => { + const date = timePicker.picker.date; + expect(hourEl.classList.contains('active')).to.true; + expect(minuteEl.classList.contains('active')).to.true; + expect(secondEl.classList.contains('active')).to.true; + expect(date.getHours()).to.equal(4); + expect(date.getMinutes()).to.equal(36); + expect(date.getSeconds()).to.equal(20); + done(); + }, DELAY); + }); + }); + }, DELAY); + }); + + it('click cancel button', done => { + vm = createVue({ + template: '', + data() { + return { + value: '' + }; + } + }, true); + const timePicker = vm.$refs.compo; + const input = timePicker.$el.querySelector('input'); + + input.blur(); + input.focus(); + + setTimeout(_ => { + timePicker.picker.$el.querySelector('.el-time-panel__btn.cancel').click(); + + setTimeout(_ => { + expect(vm.value).to.equal(''); + done(); + }, DELAY); + }, DELAY); + }); + + it('click confirm button', done => { + vm = createVue({ + template: '', + data() { + return { + value: '' + }; + } + }, true); + const timePicker = vm.$refs.compo; + const input = timePicker.$el.querySelector('input'); + + input.blur(); + input.focus(); + + setTimeout(_ => { + timePicker.picker.$el.querySelector('.el-time-panel__btn.confirm').click(); + + setTimeout(_ => { + expect(vm.value.toISOString()).to.exist; + done(); + }, DELAY); + }, DELAY); + }); + + it('set format', done => { + vm = createTest(TimePicker, { + pickerOptions: { + format: 'HH:mm' + } + }, true); + const input = vm.$el.querySelector('input'); + input.blur(); + input.focus(); + + setTimeout(_ => { + expect(vm.picker.$el.querySelectorAll('.el-time-spinner__wrapper')[2].style.display).to.equal('none'); + done(); + }, 20); + }); + + it('set format to empty', done => { + vm = createTest(TimePicker, { + pickerOptions: { + format: '' + } + }, true); + const input = vm.$el.querySelector('input'); + input.blur(); + input.focus(); + + setTimeout(_ => { + expect(vm.picker.$el.querySelectorAll('.el-time-spinner__wrapper')[2].style.display).to.equal('none'); + done(); + }, DELAY); + }); + + it('selectableRange', done => { + vm = createTest(TimePicker, { + pickerOptions: { + selectableRange: ['17:30:00 - 18:30:00', '18:50:00 - 20:30:00', '21:00:00 - 22:00:00'] + } + }, true); + const input = vm.$el.querySelector('input'); + + input.blur(); + input.focus(); + + setTimeout(_ => { + const list = vm.picker.$el.querySelectorAll('.el-time-spinner__list'); + const hoursEl = list[0]; + const disabledHours = [].slice + .call(hoursEl.querySelectorAll('.disabled')) + .map(node => Number(node.textContent)); + + hoursEl.querySelectorAll('.disabled')[0].click(); + expect(disabledHours).to.not.include.members([17, 18, 19, 20, 21, 22]); + + const minutesEl = list[1]; + hoursEl.querySelectorAll('.el-time-spinner__item')[18].click(); + setTimeout(_ => { + const disabledMinutes = [].slice + .call(minutesEl.querySelectorAll('.disabled')) + .map(node => Number(node.textContent)); + expect(disabledMinutes.every(t => t > 30 && t < 50)).to.equal(true); + expect(disabledMinutes.length).to.equal(19); + done(); + }, DELAY); + }, DELAY); + }); + + it('event focus and blur', done => { + vm = createVue({ + template: ` + + + ` + }, true); + + const spyFocus = sinon.spy(); + const spyBlur = sinon.spy(); + + vm.$refs.picker.$on('focus', spyFocus); + vm.$refs.picker.$on('blur', spyBlur); + vm.$el.querySelector('input').focus(); + + vm.$nextTick(_ => { + expect(spyFocus.calledOnce).to.be.true; + vm.$refs.picker.pickerVisible = false; + vm.$nextTick(_ => { + expect(spyBlur.calledOnce).to.be.true; + done(); + }); + }); + }); + + it('focus', done => { + vm = createVue({ + template: ` + + + ` + }, true); + + const spy = sinon.spy(); + + vm.$refs.picker.$on('focus', spy); + vm.$refs.picker.focus(); + + vm.$nextTick(_ => { + expect(spy.calledOnce).to.be.true; + done(); + }); + }); + +}); + +describe('TimePicker(range)', () => { + let vm; + + afterEach(() => destroyVM(vm)); + + it('create', done => { + vm = createTest(TimePicker, { + isRange: true, + value: [new Date(2016, 9, 10, 18, 40), new Date(2016, 9, 10, 19, 40)] + }, true); + + vm.$el.querySelector('input').click(); + + setTimeout(_ => { + expect(vm.picker.$el.querySelectorAll('.el-time-range-picker__cell')).to.length(2); + expect(vm.picker.minDate.getTime()).to.equal(new Date(2016, 9, 10, 18, 40).getTime()); + expect(vm.picker.maxDate.getTime()).to.equal(new Date(2016, 9, 10, 19, 40).getTime()); + done(); + }, DELAY); + }); + + it('default value', done => { + const defaultValue = [new Date(2000, 9, 1, 10, 0, 0), new Date(2000, 9, 1, 11, 0, 0)]; + vm = createVue({ + template: '', + data() { + return { + value: '', + defaultValue + }; + } + }, true); + + const timePicker = vm.$refs.compo; + timePicker.$el.querySelector('input').click(); + + setTimeout(_ => { + expect(timePicker.picker.minDate.getTime()).to.equal(defaultValue[0].getTime()); + expect(timePicker.picker.maxDate.getTime()).to.equal(defaultValue[1].getTime()); + done(); + }, DELAY); + }); + + it('cancel button', done => { + vm = createVue({ + template: '', + data() { + return { + value: '' + }; + } + }, true); + + const timePicker = vm.$refs.compo; + timePicker.$el.querySelector('input').click(); + setTimeout(_ => { + timePicker.picker.$el.querySelector('.cancel').click(); + setTimeout(_ => { + expect(timePicker.picker.visible).to.false; + expect(vm.value).to.equal(''); + done(); + }, DELAY); + }, DELAY); + }); +}); diff --git a/test/unit/specs/time-select.spec.js b/test/unit/specs/time-select.spec.js new file mode 100644 index 0000000..d784dc5 --- /dev/null +++ b/test/unit/specs/time-select.spec.js @@ -0,0 +1,243 @@ +import { createTest, createVue, destroyVM } from '../util'; +import TimeSelect from 'packages/time-select'; +import Vue from 'vue'; + +describe('TimeSelect', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('should render correct contents', done => { + vm = createTest(TimeSelect, { + pickerOptions: { + start: '08:30', + step: '00:15', + end: '18:30' + }, + placeholder: 'test' + }, true); + const input = vm.$el.querySelector('input'); + + input.focus(); + input.blur(); + + Vue.nextTick(_ => { + expect(vm.picker.start).to.equal('08:30'); + expect(vm.picker.end).to.equal('18:30'); + expect(vm.picker.step).to.equal('00:15'); + expect(vm.$el.querySelector('input').getAttribute('placeholder')).to.equal('test'); + done(); + }); + }); + + it('select time', done => { + vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + value: '' + }; + } + }, true); + const input = vm.$el.querySelector('input'); + + input.focus(); + input.blur(); + + Vue.nextTick(_ => { + const items = vm.$refs.compo.picker.$el.querySelectorAll('.time-select-item'); + const target = items[4]; + const time = target.textContent; + + target.click(); + Vue.nextTick(_ => { + expect(vm.value).to.equal(time); + done(); + }); + }); + }); + + it('set default value', done => { + vm = createTest(TimeSelect, { + value: '14:30' + }, true); + const input = vm.$el.querySelector('input'); + + input.focus(); + input.blur(); + + setTimeout(_ => { + expect(input.value).to.equal('14:30'); + expect(vm.picker.$el.querySelector('.selected')).to.be.ok; + expect(vm.picker.$el.querySelector('.selected').textContent).to.equal('14:30'); + done(); + }, 50); + }); + + it('set minTime', done => { + vm = createVue(` + + + `, true); + const input = vm.$el.querySelector('input'); + const picker = vm.$refs.picker; + + input.focus(); + input.blur(); + + setTimeout(_ => { + const elms = picker.picker.$el.querySelectorAll('.disabled'); + const elm = elms[elms.length - 1]; + + expect(elm.textContent).to.equal('14:30'); + done(); + }, 50); + }); + + it('minTime < value', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { value: '09:30' }; + } + }, true); + const input = vm.$el.querySelector('input'); + const picker = vm.$refs.picker; + + input.focus(); + input.blur(); + + setTimeout(_ => { + vm.value = '10:30'; + + setTimeout(_ => { + expect(picker.picker.value).to.equal('10:30'); + done(); + }, 50); + }, 50); + }); + + it('set maxTime', done => { + vm = createVue(` + + + `, true); + const input = vm.$el.querySelector('input'); + const picker = vm.$refs.picker; + + input.focus(); + input.blur(); + + setTimeout(_ => { + const elm = picker.picker.$el.querySelector('.disabled'); + + expect(elm.textContent).to.equal('14:30'); + done(); + }, 50); + }); + + it('maxTime > value', done => { + vm = createVue({ + template: ` + + + `, + data() { + return { value: '09:30' }; + } + }, true); + const input = vm.$el.querySelector('input'); + const picker = vm.$refs.picker; + + input.focus(); + input.blur(); + + setTimeout(_ => { + vm.value = '10:30'; + + setTimeout(_ => { + expect(picker.picker.value).to.equal('10:30'); + done(); + }, 50); + }, 50); + }); + + it('event focus and blur', done => { + vm = createVue({ + template: ` + + + ` + }, true); + + const spyFocus = sinon.spy(); + const spyBlur = sinon.spy(); + + vm.$refs.picker.$on('focus', spyFocus); + vm.$refs.picker.$on('blur', spyBlur); + vm.$el.querySelector('input').focus(); + + vm.$nextTick(_ => { + expect(spyFocus.calledOnce).to.be.true; + vm.$refs.picker.pickerVisible = false; + vm.$nextTick(_ => { + expect(spyBlur.calledOnce).to.be.true; + done(); + }); + }); + }); + + it('focus', done => { + vm = createVue({ + template: ` + + ` + }, true); + + const spy = sinon.spy(); + + vm.$refs.picker.$on('focus', spy); + vm.$refs.picker.focus(); + + vm.$nextTick(_ => { + expect(spy.calledOnce).to.be.true; + done(); + }); + }); +}); diff --git a/test/unit/specs/timeline.spec.js b/test/unit/specs/timeline.spec.js new file mode 100644 index 0000000..69b4446 --- /dev/null +++ b/test/unit/specs/timeline.spec.js @@ -0,0 +1,228 @@ +import { createVue, destroyVM } from '../util'; + +describe('Timeline', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createVue({ + template: ` + + + {{activity.content}} + + + `, + data() { + return { + activities: [{ + content: '创建成功', + timestamp: '2018-04-11' + }, { + content: '通过审核', + timestamp: '2018-04-13' + }, { + content: '活动按期开始', + timestamp: '2018-04-15' + }] + }; + } + }, true); + let contentElms = vm.$el.querySelectorAll('.el-timeline-item__content'); + contentElms.forEach((elm, index) => { + expect(elm.innerText).to.equal(vm.activities[index].content); + }); + let timestampElms = vm.$el.querySelectorAll('.el-timeline-item__timestamp'); + timestampElms.forEach((elm, index) => { + expect(elm.innerText).to.equal(vm.activities[index].timestamp); + }); + }); + + it('reverse', done => { + vm = createVue({ + template: ` + + + {{activity.content}} + + + `, + + data() { + return { + reverse: true, + activities: [{ + content: '创建成功', + timestamp: '2018-04-11' + }, { + content: '通过审核', + timestamp: '2018-04-13' + }, { + content: '活动按期开始', + timestamp: '2018-04-15' + }] + }; + } + }, true); + + const contentElms = vm.$el.querySelectorAll('.el-timeline-item__content'); + contentElms.forEach((elm, index) => { + expect(elm.innerText).to.equal(vm.activities[vm.activities.length - index - 1].content); + }); + + vm.reverse = false; + vm.$nextTick(() => { + const contentElms = vm.$el.querySelectorAll('.el-timeline-item__content'); + contentElms.forEach((elm, index) => { + expect(elm.innerText).to.equal(vm.activities[index].content); + }); + done(); + }); + }); + + it('placement', () => { + vm = createVue({ + template: ` + + + {{activity.content}} + + + `, + + data() { + return { + activities: [{ + content: '创建成功', + timestamp: '2018-04-11', + placement: 'top' + }, { + content: '通过审核', + timestamp: '2018-04-13' + }, { + content: '活动按期开始', + timestamp: '2018-04-15' + }] + }; + } + }, true); + + const timestampElm = vm.$el.querySelectorAll('.el-timeline-item__timestamp')[0]; + expect(timestampElm.classList.contains('is-top')).to.true; + }); + + it('hide-timestamp', () => { + vm = createVue({ + template: ` + + + {{activity.content}} + + + `, + + data() { + return { + activities: [{ + content: '创建成功', + timestamp: '2018-04-11', + hideTimestamp: true + }, { + content: '通过审核', + timestamp: '2018-04-13' + }, { + content: '活动按期开始', + timestamp: '2018-04-15' + }] + }; + } + }, true); + + const timestampElms = vm.$el.querySelectorAll('.el-timeline-item__timestamp'); + expect(timestampElms.length).to.equal(2); + }); + + it('color', () => { + vm = createVue({ + template: ` + + + 创建成功 + + + ` + }, true); + + const nodeElm = vm.$el.querySelector('.el-timeline-item__node'); + expect(nodeElm.style.backgroundColor).to.equal('rgb(255, 0, 0)'); + }); + + it('type', () => { + vm = createVue({ + template: ` + + + 创建成功 + + + ` + }, true); + + const nodeElm = vm.$el.querySelector('.el-timeline-item__node'); + expect(nodeElm.classList.contains('el-timeline-item__node--primary')).to.true; + }); + + it('size', () => { + vm = createVue({ + template: ` + + + 创建成功 + + + ` + }, true); + + const nodeElm = vm.$el.querySelector('.el-timeline-item__node'); + expect(nodeElm.classList.contains('el-timeline-item__node--large')).to.true; + }); + + it('icon', () => { + vm = createVue({ + template: ` + + + 创建成功 + + + ` + }, true); + + const nodeElm = vm.$el.querySelector('.el-timeline-item__icon'); + expect(nodeElm.classList.contains('el-icon-more')).to.true; + }); +}); diff --git a/test/unit/specs/tooltip.spec.js b/test/unit/specs/tooltip.spec.js new file mode 100644 index 0000000..7a5dffa --- /dev/null +++ b/test/unit/specs/tooltip.spec.js @@ -0,0 +1,164 @@ +import { createVue, triggerEvent, destroyVM } from '../util'; + +describe('Tooltip', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + it('create', done => { + vm = createVue(` + + + `); + + vm.$nextTick(_ => { + expect(vm.$refs.tooltip.popperVM.$el).to.have.property('textContent', '提示文字'); + done(); + }); + }); + + it('custom popper class', done => { + vm = createVue(` + + + `); + vm.$nextTick(_ => { + expect(vm.$refs.tooltip.popperVM.$el.classList.contains('custom-popper')).to.true; + done(); + }); + }); + + describe('manual', () => { + const vm = createVue({ + template: ` + + + + `, + + data() { + return { show: false }; + } + }, true); + const tooltip = vm.$refs.tooltip; + + it('showPopper is false', () => { + triggerEvent(tooltip.$el, 'mouseenter'); + expect(tooltip.showPopper).to.false; + }); + it('show', done => { + vm.show = true; + vm.$nextTick(_ => { + expect(tooltip.showPopper).to.true; + done(); + }); + }); + it('still show when trigger mouseleave', () => { + triggerEvent(tooltip.$el, 'mouseleave'); + expect(tooltip.showPopper).to.true; + }); + it('hidden', done => { + vm.show = false; + vm.$nextTick(_ => { + expect(tooltip.showPopper).to.false; + done(); + }); + }); + }); + + describe('hover', () => { + const vm = createVue(` + + + + `); + const tooltip = vm.$refs.tooltip; + + triggerEvent(tooltip.$el, 'mouseenter'); + it('popperElm is exist', () => expect(tooltip.popperElm).to.exist); + it('showPopper is true', () => expect(tooltip.showPopper).to.true); + it('close popper', done => { + triggerEvent(tooltip.$el, 'mouseleave'); + setTimeout(() => { + expect(tooltip.showPopper).to.false; + done(); + }, 300); + }); + }); + + it('light mode', done => { + vm = createVue(` + + + + `); + vm.$nextTick(_ => { + expect(vm.$refs.tooltip.popperVM.$el.classList.contains('is-light')).to.exist; + done(); + }); + }); + it('hide after', done => { + vm = createVue(` + + + `); + const tooltip = vm.$refs.tooltip; + vm.$nextTick(_ => { + triggerEvent(tooltip.$el, 'mouseenter'); + setTimeout(() => { + expect(tooltip.showPopper).to.be.true; + setTimeout(() => { + expect(tooltip.showPopper).to.be.false; + done(); + }, 300); + }, 100); + }); + }); + it('remove focus', done => { + vm = createVue(` + + + `); + const tooltip = vm.$refs.tooltip; + vm.$nextTick(_ => { + triggerEvent(tooltip.$el, 'mouseenter'); + setTimeout(() => { + tooltip.focusing = true; + tooltip.$el.click(); + setTimeout(() => { + expect(tooltip.showPopper).to.be.false; + done(); + }, 300); + }, 100); + }); + }); + it('reference element focus', done => { + vm = createVue(` + + + `); + const tooltip = vm.$refs.tooltip; + vm.$nextTick(_ => { + triggerEvent(tooltip.$el, 'focus'); + setTimeout(() => { + expect(tooltip.showPopper).to.be.true; + expect(tooltip.focusing).to.be.true; + triggerEvent(tooltip.$el, 'blur'); + setTimeout(() => { + expect(tooltip.showPopper).to.be.false; + expect(tooltip.focusing).to.be.false; + done(); + }, 300); + }, 100); + }); + }); + it('custom tabindex', () => { + vm = createVue(` + + + + `, true); + expect(vm.$el.getAttribute('tabindex')).to.be.equal('-1'); + }); +}); diff --git a/test/unit/specs/transfer.spec.js b/test/unit/specs/transfer.spec.js new file mode 100644 index 0000000..79ce729 --- /dev/null +++ b/test/unit/specs/transfer.spec.js @@ -0,0 +1,184 @@ +import { createTest, createVue, destroyVM } from '../util'; +import Transfer from 'packages/transfer'; + +describe('Transfer', () => { + let vm; + const getTestData = () => { + const data = []; + for (let i = 1; i <= 15; i++) { + data.push({ + key: i, + label: `备选项 ${ i }`, + disabled: i % 4 === 0 + }); + } + return data; + }; + const createTransfer = (props, opts) => { + return createVue(Object.assign({ + template: ` + + + `, + + created() { + this.testData = getTestData(); + } + }, opts)); + }; + + afterEach(() => { + destroyVM(vm); + }); + + it('create', () => { + vm = createTest(Transfer, true); + expect(vm.$el).to.exist; + }); + + it('default target list', () => { + vm = createTransfer('v-model="value"', { + data() { + return { + value: [1, 4] + }; + } + }); + expect(vm.$refs.transfer.sourceData.length).to.equal(13); + }); + + it('filterable', done => { + vm = createTransfer('v-model="value" filterable :filter-method="method"', { + data() { + return { + value: [], + method(query, option) { + return option.key === Number(query); + } + }; + } + }); + const transfer = vm.$refs.transfer; + const leftList = transfer.$el.querySelector('.el-transfer-panel').__vue__; + leftList.query = '1'; + setTimeout(_ => { + expect(leftList.filteredData.length).to.equal(1); + done(); + }, 50); + }); + + it('transfer', done => { + vm = createTransfer('v-model="value" :left-default-checked="[2, 3]" :right-default-checked="[1]"', { + data() { + return { + value: [1, 4] + }; + } + }); + const transfer = vm.$refs.transfer; + + setTimeout(_ => { + transfer.addToLeft(); + setTimeout(_ => { + expect(transfer.sourceData.length).to.equal(14); + transfer.addToRight(); + setTimeout(_ => { + expect(transfer.sourceData.length).to.equal(12); + done(); + }, 50); + }, 50); + }, 50); + }); + + it('customize', () => { + vm = createTransfer('v-model="value" :titles="titles" :render-content="renderFunc" :format="format"', { + data() { + return { + value: [2], + titles: ['表1', '表2'], + format: { noChecked: 'no', hasChecked: 'has' }, + renderFunc(h, option) { + return { option.key } - { option.label }; + } + }; + } + }); + const transfer = vm.$refs.transfer.$el; + const label = transfer.querySelector('.el-transfer-panel__header .el-checkbox__label'); + expect(label.innerText.indexOf('表1') > -1).to.true; + expect(transfer.querySelector('.el-transfer-panel__list .el-checkbox__label span').innerText).to.equal('1 - 备选项 1'); + expect(label.querySelector('span').innerText).to.equal('no'); + }); + + it('check', () => { + vm = createTransfer('v-model="value"', { + data() { + return { + value: [] + }; + } + }); + const leftList = vm.$refs.transfer.$el.querySelector('.el-transfer-panel').__vue__; + leftList.handleAllCheckedChange({ target: { checked: true } }); + expect(leftList.checked.length).to.equal(12); + }); + + describe('target order', () => { + it('original(default)', done => { + vm = createTransfer('v-model="value" :left-default-checked="[2, 3]"', { + data() { + return { + value: [1, 4] + }; + } + }); + const transfer = vm.$refs.transfer; + setTimeout(() => { + transfer.addToRight(); + setTimeout(() => { + const targetItems = [].slice.call(vm.$el.querySelectorAll('.el-transfer__buttons + .el-transfer-panel .el-transfer-panel__body .el-checkbox__label span')); + expect(targetItems.map(item => item.innerText)).to.deep.equal(['备选项 1', '备选项 2', '备选项 3', '备选项 4']); + done(); + }, 50); + }, 50); + }); + + it('push', done => { + vm = createTransfer('v-model="value" :left-default-checked="[2, 3]" target-order="push"', { + data() { + return { + value: [1, 4] + }; + } + }); + const transfer = vm.$refs.transfer; + setTimeout(() => { + transfer.addToRight(); + setTimeout(() => { + const targetItems = [].slice.call(vm.$el.querySelectorAll('.el-transfer__buttons + .el-transfer-panel .el-transfer-panel__body .el-checkbox__label span')); + expect(targetItems.map(item => item.innerText)).to.deep.equal(['备选项 1', '备选项 4', '备选项 2', '备选项 3']); + done(); + }, 50); + }, 50); + }); + + it('unshift', done => { + vm = createTransfer('v-model="value" :left-default-checked="[2, 3]" target-order="unshift"', { + data() { + return { + value: [1, 4] + }; + } + }); + const transfer = vm.$refs.transfer; + setTimeout(() => { + transfer.addToRight(); + setTimeout(() => { + const targetItems = [].slice.call(vm.$el.querySelectorAll('.el-transfer__buttons + .el-transfer-panel .el-transfer-panel__body .el-checkbox__label span')); + expect(targetItems.map(item => item.innerText)).to.deep.equal(['备选项 2', '备选项 3', '备选项 1', '备选项 4']); + done(); + }, 50); + }, 50); + }); + }); +}); diff --git a/test/unit/specs/tree.spec.js b/test/unit/specs/tree.spec.js new file mode 100644 index 0000000..403d51c --- /dev/null +++ b/test/unit/specs/tree.spec.js @@ -0,0 +1,893 @@ +import { createVue, destroyVM, waitImmediate, wait } from '../util'; + +const DELAY = 10; + +describe('Tree', () => { + let vm; + afterEach(() => { + destroyVM(vm); + }); + + const getTreeVm = (props, options) => { + return createVue(Object.assign({ + template: ` + + `, + + data() { + return { + defaultExpandedKeys: [], + defaultCheckedKeys: [], + clickedNode: null, + count: 1, + data: [{ + id: 1, + label: '一级 1', + children: [{ + id: 11, + label: '二级 1-1', + children: [{ + id: 111, + label: '三级 1-1' + }] + }] + }, { + id: 2, + label: '一级 2', + children: [{ + id: 21, + label: '二级 2-1' + }, { + id: 22, + label: '二级 2-2' + }] + }, { + id: 3, + label: '一级 3', + children: [{ + id: 31, + label: '二级 3-1' + }, { + id: 32, + label: '二级 3-2' + }] + }], + defaultProps: { + children: 'children', + label: 'label' + } + }; + } + }, options), true); + }; + + const getDisableTreeVm = (props, options) => { + return createVue(Object.assign({ + template: ` + + `, + + data() { + return { + defaultExpandedKeys: [], + defaultCheckedKeys: [], + clickedNode: null, + count: 1, + data: [{ + id: 1, + label: '一级 1', + children: [{ + id: 11, + label: '二级 1-1', + children: [{ + id: 111, + label: '三级 1-1', + disabled: true + }] + }] + }, { + id: 2, + label: '一级 2', + children: [{ + id: 21, + label: '二级 2-1' + }, { + id: 22, + label: '二级 2-2' + }] + }, { + id: 3, + label: '一级 3', + children: [{ + id: 31, + label: '二级 3-1' + }, { + id: 32, + label: '二级 3-2' + }] + }], + defaultProps: { + children: 'children', + label: 'label', + disabled: 'disabled' + } + }; + } + }, options), true); + }; + + const ALL_NODE_COUNT = 9; + + it('create', () => { + vm = getTreeVm(':props="defaultProps" default-expand-all'); + expect(document.querySelector('.el-tree')).to.exist; + expect(document.querySelectorAll('.el-tree > .el-tree-node').length).to.equal(3); + expect(document.querySelectorAll('.el-tree .el-tree-node').length).to.equal(ALL_NODE_COUNT); + vm.data[1].children = [{ label: '二级 2-1' }]; + const tree = vm.$children[0]; + expect(tree.children).to.deep.equal(vm.data); + }); + + it('click node', done => { + vm = getTreeVm(':props="defaultProps" @node-click="handleNodeClick"', { + methods: { + handleNodeClick(data) { + this.clickedNode = data; + } + } + }); + const firstNode = vm.$el.querySelector('.el-tree-node__content'); + firstNode.click(); + expect(vm.clickedNode.label).to.equal('一级 1'); + setTimeout(() => { + expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.true; + firstNode.click(); + setTimeout(() => { + expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.false; + done(); + }, DELAY); + }, DELAY); + }); + + it('current change', done => { + vm = getTreeVm(':props="defaultProps" @current-change="handleCurrentChange"', { + methods: { + handleCurrentChange(data) { + this.currentNode = data; + } + } + }); + const firstNode = vm.$el.querySelector('.el-tree-node__content'); + firstNode.click(); + expect(vm.currentNode.label).to.equal('一级 1'); + done(); + }); + + it('emptyText', (done) => { + vm = getTreeVm(':props="defaultProps"'); + vm.data = []; + vm.$nextTick(() => { + expect(vm.$el.querySelectorAll('.el-tree__empty-block').length).to.equal(1); + done(); + }); + }); + + it('highlight current', done => { + vm = getTreeVm(':props="defaultProps" highlight-current'); + const firstNode = document.querySelector('.el-tree-node'); + firstNode.click(); + vm.$nextTick(() => { + expect(firstNode.className.indexOf('is-current')).to.not.equal(-1); + done(); + }); + }); + + it('expandOnNodeClick', done => { + vm = getTreeVm(':props="defaultProps" :expand-on-click-node="false"'); + const firstNode = document.querySelector('.el-tree-node'); + firstNode.click(); + vm.$nextTick(() => { + expect(firstNode.className.indexOf('is-expanded')).to.equal(-1); + done(); + }); + }); + + it('checkOnNodeClick', done => { + vm = getTreeVm(':props="defaultProps" show-checkbox check-on-click-node'); + const firstNode = document.querySelector('.el-tree-node'); + firstNode.click(); + vm.$nextTick(() => { + expect(firstNode.querySelector('input').checked).to.true; + done(); + }); + }); + + it('current-node-key', () => { + vm = getTreeVm(':props="defaultProps" default-expand-all highlight-current node-key="id" :current-node-key="11"'); + const currentNodeLabel = document.querySelector('.is-current .el-tree-node__label').textContent; + + expect(currentNodeLabel).to.be.equal('二级 1-1'); + }); + + it('defaultExpandAll', () => { + vm = getTreeVm(':props="defaultProps" default-expand-all'); + expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(ALL_NODE_COUNT); + }); + + it('defaultExpandedKeys', () => { + vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id"', { + created() { + this.defaultExpandedKeys = [1, 3]; + } + }); + expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(2); + }); + + it('defaultExpandedKeys set', (done) => { + vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id"', { + created() { + this.defaultExpandedKeys = [1, 3]; + } + }); + expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(2); + vm.defaultExpandedKeys = [2]; + vm.data = JSON.parse(JSON.stringify(vm.data)); + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(1); + done(); + }, 50); + }); + + it('filter-node-method', (done) => { + vm = getTreeVm(':props="defaultProps" :filter-node-method="filterNode"', { + methods: { + filterNode(value, data) { + if (!value) return true; + return data.label.indexOf(value) !== -1; + } + } + }); + + const tree = vm.$refs.tree; + tree.filter('2-1'); + + setTimeout(() => { + expect(tree.$el.querySelectorAll('.el-tree-node.is-hidden').length).to.equal(3); + done(); + }, 100); + }); + + it('autoExpandParent = true', () => { + vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id"', { + created() { + this.defaultExpandedKeys = [111]; + } + }); + expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(3); + }); + + it('autoExpandParent = false', (done) => { + vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id" :auto-expand-parent="false"', { + created() { + this.defaultExpandedKeys = [11]; + } + }); + expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(0); + const firstNode = document.querySelector('.el-tree-node__content'); + firstNode.querySelector('.el-tree-node__expand-icon').click(); + setTimeout(() => { + expect(document.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(2); + done(); + }, 100); + }); + + it('defaultCheckedKeys & check-strictly = false', () => { + vm = getTreeVm(':props="defaultProps" default-expand-all show-checkbox :default-checked-keys="defaultCheckedKeys" node-key="id"', { + created() { + this.defaultCheckedKeys = [1]; + } + }); + expect(vm.$el.querySelectorAll('.el-checkbox .is-checked').length).to.equal(3); + }); + + it('defaultCheckedKeys & check-strictly', () => { + vm = getTreeVm(':props="defaultProps" default-expand-all show-checkbox :default-checked-keys="defaultCheckedKeys" node-key="id" check-strictly', { + created() { + this.defaultCheckedKeys = [1]; + } + }); + expect(vm.$el.querySelectorAll('.el-checkbox .is-checked').length).to.equal(1); + }); + + it('show checkbox', done => { + vm = getTreeVm(':props="defaultProps" show-checkbox'); + const tree = vm.$children[0]; + const secondNode = document.querySelectorAll('.el-tree-node__content')[1]; + const nodeCheckbox = secondNode.querySelector('.el-checkbox'); + expect(nodeCheckbox).to.be.exist; + nodeCheckbox.click(); + setTimeout(() => { + expect(tree.getCheckedNodes().length).to.equal(3); + expect(tree.getCheckedNodes(true).length).to.equal(2); + secondNode.querySelector('.el-tree-node__expand-icon').click(); + setTimeout(() => { + const firstLeaf = secondNode.nextElementSibling.querySelector('.el-tree-node__content'); + const leafCheckbox = firstLeaf.querySelector('.el-checkbox'); + leafCheckbox.click(); + setTimeout(() => { + expect(tree.getCheckedNodes().length).to.equal(1); + done(); + }, 10); + }, 10); + }, 10); + }); + + it('check', done => { + const spy = sinon.spy(); + vm = getTreeVm(':props="defaultProps" show-checkbox @check="handleCheck"', { + methods: { + handleCheck: spy + } + }); + const secondNode = document.querySelectorAll('.el-tree-node__content')[1]; + const nodeCheckbox = secondNode.querySelector('.el-checkbox'); + expect(nodeCheckbox).to.be.exist; + nodeCheckbox.click(); + setTimeout(() => { + expect(spy.calledOnce).to.be.true; + const [data, args] = spy.args[0]; + expect(data.id).to.equal(2); + expect(args.checkedNodes.length).to.equal(3); + done(); + }, 10); + }); + + it('setCheckedNodes', (done) => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); + const tree = vm.$children[0]; + const secondNode = document.querySelectorAll('.el-tree-node__content')[1]; + const nodeCheckbox = secondNode.querySelector('.el-checkbox'); + nodeCheckbox.click(); + setTimeout(() => { + expect(tree.getCheckedNodes().length).to.equal(3); + expect(tree.getCheckedNodes(true).length).to.equal(2); + setTimeout(() => { + tree.setCheckedNodes([]); + expect(tree.getCheckedNodes().length).to.equal(0); + done(); + }, 10); + }, 10); + }); + + it('setCheckedKeys', async() => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); + const tree = vm.$children[0]; + tree.setCheckedKeys([111]); + await waitImmediate(); + expect(tree.getCheckedNodes().length).to.equal(3); + expect(tree.getCheckedKeys().length).to.equal(3); + + tree.setCheckedKeys([1]); + await waitImmediate(); + expect(tree.getCheckedNodes().length).to.equal(3); + expect(tree.getCheckedKeys().length).to.equal(3); + + tree.setCheckedKeys([2]); + await waitImmediate(); + expect(tree.getCheckedNodes().length).to.equal(3); + expect(tree.getCheckedKeys().length).to.equal(3); + + tree.setCheckedKeys([21]); + await waitImmediate(); + expect(tree.getCheckedNodes().length).to.equal(1); + expect(tree.getCheckedKeys().length).to.equal(1); + }); + + it('setCheckedKeys with checkStrictly', async() => { + vm = getTreeVm(':props="defaultProps" checkStrictly show-checkbox node-key="id"'); + const tree = vm.$children[0]; + tree.setCheckedKeys([111]); + expect(tree.getCheckedNodes().length).to.equal(1); + expect(tree.getCheckedKeys().length).to.equal(1); + + tree.setCheckedKeys([1]); + await waitImmediate(); + expect(tree.getCheckedNodes().length).to.equal(1); + expect(tree.getCheckedKeys().length).to.equal(1); + + tree.setCheckedKeys([2]); + await waitImmediate(); + expect(tree.getCheckedNodes().length).to.equal(1); + expect(tree.getCheckedKeys().length).to.equal(1); + + tree.setCheckedKeys([21, 22]); + await waitImmediate(); + expect(tree.getCheckedNodes().length).to.equal(2); + expect(tree.getCheckedKeys().length).to.equal(2); + }); + + it('method setChecked', () => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); + const tree = vm.$children[0]; + tree.setChecked(111, true, true); + expect(tree.getCheckedNodes().length).to.equal(3); + expect(tree.getCheckedKeys().length).to.equal(3); + + tree.setChecked(vm.data[0], false, true); + expect(tree.getCheckedNodes().length).to.equal(0); + expect(tree.getCheckedKeys().length).to.equal(0); + }); + + it('setCheckedKeys with leafOnly=false', async() => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); + const tree = vm.$children[0]; + tree.setCheckedKeys([1, 11, 111, 2], false); + await waitImmediate(); + expect(tree.getCheckedNodes().length).to.equal(6); + expect(tree.getCheckedKeys().length).to.equal(6); + }); + + it('setCheckedKeys with leafOnly=true', async() => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); + const tree = vm.$children[0]; + tree.setCheckedKeys([2], true); + await waitImmediate(); + expect(tree.getCheckedNodes().length).to.equal(2); + expect(tree.getCheckedKeys().length).to.equal(2); + }); + + it('setCurrentKey', (done) => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); + const tree = vm.$children[0]; + tree.setCurrentKey(111); + vm.$nextTick(() => { + expect(tree.store.currentNode.data.id).to.equal(111); + // cancel highlight + tree.setCurrentKey(null); + vm.$nextTick(() => { + expect(tree.store.currentNode).to.equal(null); + done(); + }); + }); + }); + + it('setCurrentNode', (done) => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); + const tree = vm.$children[0]; + tree.setCurrentNode({ + id: 111, + label: '三级 1-1' + }); + vm.$nextTick(() => { + expect(tree.store.currentNode.data.id).to.equal(111); + done(); + }); + }); + + it('getCurrentKey', (done) => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); + const tree = vm.$children[0]; + tree.setCurrentKey(111); + vm.$nextTick(() => { + expect(tree.getCurrentKey()).to.equal(111); + done(); + }); + }); + + it('getCurrentNode', (done) => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); + const tree = vm.$children[0]; + tree.setCurrentKey(111); + vm.$nextTick(() => { + expect(tree.getCurrentNode().id).to.equal(111); + done(); + }); + }); + + it('getNode', () => { + vm = getTreeVm(':props="defaultProps" node-key="id"'); + const tree = vm.$children[0]; + const node = tree.getNode(111); + expect(node.data.id).to.equal(111); + }); + + it('remove', (done) => { + vm = getTreeVm(':props="defaultProps" node-key="id"'); + const tree = vm.$children[0]; + tree.setCurrentKey(1); + expect(tree.getCurrentNode().id).to.equal(1); + tree.remove(1); + vm.$nextTick(() => { + expect(vm.data[0].id).to.equal(2); + expect(tree.getNode(1)).to.equal(null); + expect(tree.getCurrentNode()).to.equal(null); + done(); + }); + }); + + it('append', () => { + vm = getTreeVm(':props="defaultProps" node-key="id"'); + const tree = vm.$children[0]; + const nodeData = { id: 88, label: '88' }; + tree.append(nodeData, tree.getNode(1)); + + expect(vm.data[0].children.length).to.equal(2); + expect(tree.getNode(88).data).to.equal(nodeData); + }); + + it('insertBefore', () => { + vm = getTreeVm(':props="defaultProps" node-key="id"'); + const tree = vm.$children[0]; + const nodeData = { id: 88, label: '88' }; + tree.insertBefore(nodeData, tree.getNode(11)); + expect(vm.data[0].children.length).to.equal(2); + expect(vm.data[0].children[0]).to.equal(nodeData); + expect(tree.getNode(88).data).to.equal(nodeData); + }); + + it('insertAfter', () => { + vm = getTreeVm(':props="defaultProps" node-key="id"'); + const tree = vm.$children[0]; + const nodeData = { id: 88, label: '88' }; + tree.insertAfter(nodeData, tree.getNode(11)); + expect(vm.data[0].children.length).to.equal(2); + expect(vm.data[0].children[1]).to.equal(nodeData); + expect(tree.getNode(88).data).to.equal(nodeData); + }); + + it('set disabled checkbox', done => { + vm = getDisableTreeVm(':props="defaultProps" show-checkbox node-key="id" default-expand-all'); + const node = document.querySelectorAll('.el-tree-node__content')[2]; + const nodeCheckbox = node.querySelector('.el-checkbox input'); + vm.$nextTick(() => { + expect(nodeCheckbox.disabled).to.equal(true); + done(); + }); + }); + + it('check strictly', (done) => { + vm = getTreeVm(':props="defaultProps" show-checkbox check-strictly default-expand-all'); + const tree = vm.$children[0]; + const secondNode = document.querySelectorAll('.el-tree-node__content')[3]; + const nodeCheckbox = secondNode.querySelector('.el-checkbox'); + nodeCheckbox.click(); + expect(tree.getCheckedNodes().length).to.equal(1); + expect(tree.getCheckedNodes(true).length).to.equal(0); + const firstLeaf = secondNode.nextElementSibling.querySelector('.el-tree-node__content'); + const leafCheckbox = firstLeaf.querySelector('.el-checkbox'); + vm.$nextTick(() => { + leafCheckbox.click(); + expect(tree.getCheckedNodes().length).to.equal(2); + done(); + }); + }); + + it('render content', () => { + vm = getTreeVm(':props="defaultProps" :render-content="renderContent"', { + methods: { + renderContent(h, node) { + return ( + + { node.node.label } + + ); + } + } + }); + const firstNode = document.querySelector('.el-tree-node__content'); + expect(firstNode.querySelector('.custom-content')).to.exist; + const button = firstNode.querySelector('.custom-content .el-button'); + expect(button).to.exist; + expect(button.querySelector('span').textContent).to.equal('一级 1'); + }); + + it('scoped slot', () => { + vm = createVue({ + template: ` + +
+ {{ scope.node.label }} + +
+
+ `, + + data() { + return { + data: [{ + id: 1, + label: '一级 1', + children: [{ + id: 11, + label: '二级 1-1', + children: [{ + id: 111, + label: '三级 1-1' + }] + }] + }, { + id: 2, + label: '一级 2', + children: [{ + id: 21, + label: '二级 2-1' + }, { + id: 22, + label: '二级 2-2' + }] + }, { + id: 3, + label: '一级 3', + children: [{ + id: 31, + label: '二级 3-1' + }, { + id: 32, + label: '二级 3-2' + }] + }] + }; + } + }, true); + const firstNode = document.querySelector('.custom-tree-template'); + expect(firstNode).to.exist; + const span = firstNode.querySelector('span'); + const button = firstNode.querySelector('.el-button'); + expect(span).to.exist; + expect(span.innerText).to.equal('一级 1'); + expect(button).to.exist; + }); + + it('load node', done => { + vm = getTreeVm(':props="defaultProps" lazy :load="loadNode" show-checkbox', { + methods: { + loadNode(node, resolve) { + if (node.level === 0) { + return resolve([{ label: 'region1' }, { label: 'region2' }]); + } + if (node.level > 4) return resolve([]); + setTimeout(() => { + resolve([{ + label: 'zone' + this.count++ + }, { + label: 'zone' + this.count++ + }]); + }, 50); + } + } + }); + const nodes = document.querySelectorAll('.el-tree-node__content'); + expect(nodes.length).to.equal(2); + nodes[0].click(); + setTimeout(() => { + expect(document.querySelectorAll('.el-tree-node__content').length).to.equal(4); + done(); + }, 100); + }); + + it('lazy defaultChecked', done => { + vm = getTreeVm(':props="defaultProps" node-key="id" lazy :load="loadNode" show-checkbox', { + methods: { + loadNode(node, resolve) { + if (node.level === 0) { + return resolve([{ label: 'region1', id: this.count++ }, { label: 'region2', id: this.count++ }]); + } + if (node.level > 4) return resolve([]); + setTimeout(() => { + resolve([{ + label: 'zone' + this.count, + id: this.count++ + }, { + label: 'zone' + this.count, + id: this.count++ + }]); + }, 50); + } + } + }); + const tree = vm.$children[0]; + const firstNode = document.querySelector('.el-tree-node__content'); + const initStatus = firstNode.querySelector('.is-indeterminate'); + expect(initStatus).to.equal(null); + tree.store.setCheckedKeys([3]); + firstNode.querySelector('.el-tree-node__expand-icon').click(); + setTimeout(() => { + const clickStatus = firstNode.querySelector('.is-indeterminate'); + expect(clickStatus).to.not.equal(null); + const child = document.querySelectorAll('.el-tree-node__content')[1]; + expect(child.querySelector('input').checked).to.equal(true); + done(); + }, 300); + }); + + it('lazy expandOnChecked', done => { + vm = getTreeVm(':props="defaultProps" node-key="id" lazy :load="loadNode" show-checkbox check-descendants', { + methods: { + loadNode(node, resolve) { + if (node.level === 0) { + return resolve([{ label: 'region1', id: this.count++ }, { label: 'region2', id: this.count++ }]); + } + if (node.level > 2) return resolve([]); + setTimeout(() => { + resolve([{ + label: 'zone' + this.count, + id: this.count++ + }, { + label: 'zone' + this.count, + id: this.count++ + }]); + }, 10); + } + } + }); + const tree = vm.$children[0]; + tree.store.setCheckedKeys([1]); + setTimeout(() => { + const checkedKeys = tree.getCheckedKeys(); + expect(checkedKeys.length).to.equal(7); + done(); + }, 400); + }); + + it('lazy without expandOnChecked', done => { + vm = getTreeVm(':props="defaultProps" node-key="id" lazy :load="loadNode" show-checkbox', { + methods: { + loadNode(node, resolve) { + if (node.level === 0) { + return resolve([{ label: 'region1', id: this.count++ }, { label: 'region2', id: this.count++ }]); + } + if (node.level > 4) return resolve([]); + setTimeout(() => { + resolve([{ + label: 'zone' + this.count, + id: this.count++ + }, { + label: 'zone' + this.count, + id: this.count++ + }]); + }, 50); + } + } + }); + const tree = vm.$children[0]; + tree.store.setCheckedKeys([1]); + setTimeout(() => { + const nodes = document.querySelectorAll('.el-tree-node__content'); + expect(nodes[0].querySelector('input').checked).to.equal(true); + expect(nodes.length).to.equal(2); + done(); + }, 300); + }); + + it('accordion', done => { + vm = getTreeVm(':props="defaultProps" accordion'); + const firstNode = vm.$el.querySelector('.el-tree-node__content'); + const secondNode = vm.$el.querySelector('.el-tree-node:nth-child(2) .el-tree-node__content'); + firstNode.click(); + setTimeout(() => { + expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.true; + secondNode.click(); + setTimeout(() => { + expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.false; + done(); + }, DELAY); + }, DELAY); + }); + + it('handleNodeOpen & handleNodeClose', (done) => { + vm = getTreeVm(':props="defaultProps" lazy :load="loadNode" @node-expand="handleNodeOpen" @node-collapse="handleNodeClose"', { + methods: { + loadNode(node, resolve) { + if (node.level === 0) { + return resolve([{label: 'region1'}, {label: 'region2'}]); + } + if (node.level > 4) return resolve([]); + setTimeout(() => { + resolve([{ + label: 'zone' + this.count++ + }, { + label: 'zone' + this.count++ + }]); + }, 50); + }, + handleNodeOpen(data, node, vm) { + this.currentNode = data; + this.nodeExpended = true; + }, + handleNodeClose(data, node, vm) { + this.currentNode = data; + this.nodeExpended = false; + } + } + }); + const firstNode = document.querySelector('.el-tree-node__content'); + expect(firstNode.nextElementSibling).to.not.exist; + firstNode.click(); + setTimeout(() => { + expect(vm.nodeExpended).to.equal(true); + expect(vm.currentNode.label).to.equal('region1'); + firstNode.click(); + setTimeout(() => { + expect(vm.nodeExpended).to.equal(false); + expect(vm.currentNode.label).to.equal('region1'); + done(); + }, 100); + }, 100); + }); + + it('updateKeyChildren', (done) => { + vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id" default-expand-all'); + const tree = vm.$children[0]; + tree.updateKeyChildren(1, [{ + id: 111, + label: '三级 1-1' + }]); + const node = document.querySelectorAll('.el-tree-node__content')[2]; + const label = node.querySelector('.el-tree-node__label'); + vm.$nextTick(() => { + expect(tree.store.nodesMap['11']).to.equal(undefined); + expect(tree.store.nodesMap['1'].childNodes[0].data.id).to.equal(111); + expect(label.textContent).to.equal('三级 1-1'); + done(); + }); + }); + + it('update multi tree data', async() => { + const vm = createVue({ + template: ` +
+ + +
+ `, + + data() { + return { + data: [{ + id: 1, + label: '一级 1', + children: [{ + id: 11, + label: '二级 1-1', + children: [{ + id: 111, + label: '三级 1-1' + }] + }] + }, { + id: 2, + label: '一级 2', + children: [{ + id: 21, + label: '二级 2-1' + }, { + id: 22, + label: '二级 2-2' + }] + }, { + id: 3, + label: '一级 3', + children: [{ + id: 31, + label: '二级 3-1' + }, { + id: 32, + label: '二级 3-2' + }] + }], + defaultProps: { + children: 'children', + label: 'label' + } + }; + } + }, true); + const nodeData = { label: '新增 1', id: 4 }; + vm.data.push(nodeData); + await wait(); + const tree1 = vm.$refs.tree1; + expect(tree1.getNode(4).data).to.equal(nodeData); + const tree2 = vm.$refs.tree2; + expect(tree2.getNode(4).data).to.equal(nodeData); + }); +}); diff --git a/test/unit/specs/upload.spec.js b/test/unit/specs/upload.spec.js new file mode 100644 index 0000000..834fcdb --- /dev/null +++ b/test/unit/specs/upload.spec.js @@ -0,0 +1,317 @@ +import { createVue, destroyVM } from '../util.js'; +import ajax from 'packages/upload/src/ajax'; + +const noop = () => {}; +const option = { + onSuccess: noop, + onProgress: noop, + data: { a: 'abc', b: 'bcd' }, + filename: 'file.png', + file: new File([JSON.stringify('foo')], {type: 'image/png'}), + action: '/upload', + headers: { region: 'shanghai' } +}; +let requests, xhr; +describe('ajax', () => { + beforeEach(() => { + xhr = sinon.useFakeXMLHttpRequest(); + requests = []; + xhr.onCreate = req => requests.push(req); + option.onError = noop; + option.onSuccess = noop; + }); + afterEach(() => { + xhr.restore(); + }); + it('request success', done => { + option.onError = done; + option.onSuccess = ret => { + expect(ret).to.eql({ success: true }); + done(); + }; + ajax(option); + requests[0].respond(200, {}, '{"success": true}'); + }); + it('request width header', done => { + ajax(option); + expect(requests[0].requestHeaders).to.eql({ + region: 'shanghai' + }); + done(); + }); + it('40x code should be error', done => { + option.onError = e => { + expect(e.toString()).to.contain('Not found'); + done(); + }; + + option.onSuccess = () => done('404 should throw error'); + ajax(option); + requests[0].respond(404, {}, 'Not found'); + }); + it('2xx code should be success', done => { + option.onError = done; + option.onSuccess = ret => { + expect(ret).to.equal(''); + done(); + }; + ajax(option); + requests[0].respond(204, {}); + }); +}); +describe('Upload', () => { + let requests; + let xhr; + + beforeEach(() => { + xhr = sinon.useFakeXMLHttpRequest(); + requests = []; + xhr.onCreate = req => requests.push(req); + }); + + afterEach(() => { + xhr.restore(); + }); + + describe('ajax upload', () => { + + let uploader; + let handlers = {}; + + const props = { + props: { + action: '/upload', + onSuccess(res, file, fileList) { + if (handlers.onSuccess) { + handlers.onSuccess(res, file, fileList); + } + }, + onError(err, file, fileList) { + if (handlers.onError) { + handlers.onError(err, file, fileList); + } + }, + onPreview(file) { + if (handlers.onPreview) { + handlers.onPreview(file); + } + }, + limit: 2, + onExceed(files, fileList) { + if (handlers.onExceed) { + handlers.onExceed(files, fileList); + } + }, + beforeUpload(file) { + if (handlers.beforeUpload) { + return handlers.beforeUpload(file); + } else { + return true; + } + }, + beforeRemove(file, fileList) { + if (handlers.beforeRemove) { + return handlers.beforeRemove(file); + } else { + return true; + } + } + } + }; + + beforeEach(() => { + uploader = createVue({ + render(h) { + return ( + + 点击上传 + + ); + } + }, true).$refs.upload; + }); + + afterEach(() => { + destroyVM(uploader); + handlers = {}; + }); + + it('upload success', done => { + const file = new Blob([JSON.stringify({}, null, 2)], { + type: 'application/json' + }); + file.name = 'success.png'; + const files = [file]; + + handlers.onSuccess = (res, file, fileList) => { + expect(file.name).to.equal('success.png'); + expect(fileList.length).to.equal(1); + expect(res).to.equal('success.png'); + done(); + }; + + uploader.$refs['upload-inner'].handleChange({ target: { files }}); + + setTimeout(() => { + requests[0].respond(200, {}, `${files[0].name}`); + }, 100); + }); + + it('upload fail', done => { + const file = new Blob([JSON.stringify({}, null, 2)], { + type: 'application/json' + }); + file.name = 'fail.png'; + const files = [file]; + + handlers.onError = (err, file, fileList) => { + expect(err instanceof Error).to.equal(true); + expect(file.name).to.equal('fail.png'); + done(); + }; + + uploader.$refs['upload-inner'].handleChange({ target: { files }}); + + setTimeout(() => { + requests[0].respond(400, {}, 'error 400'); + }, 100); + }); + it('preview file', done => { + const file = new Blob([JSON.stringify({}, null, 2)], { + type: 'application/json' + }); + file.name = 'success.png'; + const files = [file]; + + handlers.onPreview = (file) => { + expect(file.response).to.equal('success.png'); + done(); + }; + + handlers.onSuccess = (res, file, fileList) => { + uploader.$nextTick(_ => { + uploader.$el.querySelector('.el-upload-list .is-success a').click(); + }); + }; + + uploader.$refs['upload-inner'].handleChange({ target: { files }}); + + setTimeout(() => { + requests[0].respond(200, {}, `${files[0].name}`); + }, 100); + }); + it('file remove', done => { + const file = new Blob([JSON.stringify({}, null, 2)], { + type: 'application/json' + }); + file.name = 'success.png'; + const files = [file]; + + handlers.onSuccess = (res, file, fileList) => { + uploader.$el.querySelector('.el-upload-list .el-icon-close').click(); + uploader.$nextTick(_ => { + expect(uploader.fileList.length).to.equal(0); + done(); + }); + }; + + uploader.$refs['upload-inner'].handleChange({ target: { files }}); + + setTimeout(() => { + requests[0].respond(200, {}, `${files[0].name}`); + }, 100); + }); + it('clear files', done => { + const file = new Blob([JSON.stringify({}, null, 2)], { + type: 'application/json' + }); + file.name = 'success.png'; + const files = [file]; + + handlers.onSuccess = (res, file, fileList) => { + uploader.clearFiles(); + uploader.$nextTick(_ => { + expect(uploader.fileList.length).to.equal(0); + done(); + }); + }; + + uploader.$refs['upload-inner'].handleChange({ target: { files }}); + + setTimeout(() => { + requests[0].respond(200, {}, `${files[0].name}`); + }, 100); + }); + it('beforeUpload return promise', done => { + const spy = sinon.spy(); + const file = new Blob([JSON.stringify({}, null, 2)], { + type: 'application/json' + }); + const files = [file]; + handlers.onSuccess = () => { + expect(spy.calledOnce).to.equal(true); + done(); + }; + handlers.beforeUpload = (file) => { + return new window.Promise((resolve) => { + spy(); + resolve(file); + }); + }; + uploader.$refs['upload-inner'].handleChange({ target: { files }}); + setTimeout(() => { + requests[0].respond(200, {}, `${files[0].name}`); + }, 100); + }); + it('beforeRemove return rejected promise', done => { + const spy = sinon.spy(); + handlers.beforeRemove = (file) => { + return new window.Promise((resolve, reject) => { + spy(); + reject(); + }); + }; + const file = new Blob([JSON.stringify({}, null, 2)], { + type: 'application/json' + }); + file.name = 'success.png'; + const files = [file]; + + handlers.onSuccess = (res, file, fileList) => { + uploader.$el.querySelector('.el-upload-list .el-icon-close').click(); + setTimeout(() => { + expect(spy.calledOnce).to.equal(true); + expect(uploader.uploadFiles.length).to.equal(1); + done(); + }, 200); + }; + uploader.$refs['upload-inner'].handleChange({ target: { files }}); + setTimeout(() => { + requests[0].respond(200, {}, `${files[0].name}`); + }, 100); + }); + it('limit files', done => { + const files = [{ + name: 'exceed2.png', + type: 'xml' + }, { + name: 'exceed3.png', + type: 'xml' + }]; + + uploader.uploadFiles = [{ + name: 'exceed1.png', + type: 'xml' + }]; + + handlers.onExceed = (files, fileList) => { + uploader.$nextTick(_ => { + expect(uploader.uploadFiles.length).to.equal(1); + done(); + }); + }; + + uploader.$nextTick(_ => uploader.$refs['upload-inner'].handleChange({ target: { files }})); + }); + }); +}); diff --git a/test/unit/specs/util.clickoutside.spec.js b/test/unit/specs/util.clickoutside.spec.js new file mode 100644 index 0000000..3b7f351 --- /dev/null +++ b/test/unit/specs/util.clickoutside.spec.js @@ -0,0 +1,170 @@ +import Clickoutside from 'element-ui/src/utils/clickoutside'; +const ctx = '@@clickoutsideContext'; + +import { triggerEvent, triggerClick } from '../util'; + +describe('Utils:Clickoutside', () => { + it('create', () => { + let count = 0; + const el = document.createElement('div'); + const vnode = { + context: { + handleClick: () => ++count + } + }; + const binding = { + expression: 'handleClick' + }; + + Clickoutside.bind(el, binding, vnode); + expect(el[ctx]).to.exist; + }); + + it('cotext not exist', () => { + const el = document.createElement('div'); + const vnode = {}; + const binding = { + expression: 'handleClick' + }; + + Clickoutside.bind(el, binding, vnode); + expect(el[ctx]).to.exist; + }); + + it('binding expression', () => { + const el = document.createElement('div'); + let count = 0; + const vnode = { + context: { + handleClick: () => ++count + } + }; + const binding = { + expression: 'handleClick' + }; + + Clickoutside.bind(el, binding, vnode); + triggerClick(document); + expect(count).to.equal(1); + }); + + it('click inside', () => { + const el = document.createElement('div'); + const insideElm = document.createElement('div'); + let count = 0; + const vnode = { + context: { + handleClick: () => ++count + } + }; + const binding = { + expression: 'handleClick' + }; + + el.appendChild(insideElm); + Clickoutside.bind(el, binding, vnode); + triggerClick(insideElm); + expect(count).to.equal(0); + triggerClick(document); + expect(count).to.equal(1); + }); + + it('tigger event in popperElm', () => { + const el = document.createElement('div'); + const insideElm = document.createElement('div'); + let count = 0; + const vnode = { + context: { + handleClick: () => ++count, + popperElm: document.createElement('div') + } + }; + const binding = { + expression: 'handleClick' + }; + + vnode.context.popperElm.appendChild(insideElm); + Clickoutside.bind(el, binding, vnode); + triggerClick(insideElm); + expect(count).to.equal(0); + triggerClick(document); + expect(count).to.equal(1); + }); + + it('binding value', () => { + const el = document.createElement('div'); + let count = 0; + const vnode = { + context: {} + }; + const binding = { + value: () => ++count + }; + + Clickoutside.bind(el, binding, vnode); + expect(count).to.equal(0); + triggerClick(document); + expect(count).to.equal(1); + }); + + it('update', () => { + let count = 0; + const el = document.createElement('div'); + const vnode = { + context: { + abc: () => ++count, + ddd: () => ++count + } + }; + const binding = { + expression: 'abc' + }; + + const newBinding = { + expression: 'ddd' + }; + + Clickoutside.bind(el, binding, vnode); + expect(el[ctx].methodName).to.equal('abc'); + Clickoutside.update(el, newBinding); + expect(el[ctx].methodName).to.equal('ddd'); + }); + + it('unbind', () => { + const el = document.createElement('div'); + let count = 0; + const vnode = { + context: {} + }; + const binding = { + value: () => ++count + }; + + Clickoutside.bind(el, binding, vnode); + triggerClick(document); + Clickoutside.unbind(el); + triggerClick(document); + expect(count).to.equal(1); + }); + + it('stays open on drag click', () => { + const el = document.createElement('div'); + const insideElm = document.createElement('div'); + let count = 0; + const vnode = { + context: { + handleClick: () => ++count + } + }; + const binding = { + expression: 'handleClick' + }; + + el.appendChild(insideElm); + Clickoutside.bind(el, binding, vnode); + triggerEvent(insideElm, 'mousedown'); + triggerEvent(document, 'mouseup'); + expect(count).to.equal(1); + }); +}); + diff --git a/test/unit/specs/util.vue-popper.spec.js b/test/unit/specs/util.vue-popper.spec.js new file mode 100644 index 0000000..8c62387 --- /dev/null +++ b/test/unit/specs/util.vue-popper.spec.js @@ -0,0 +1,179 @@ +import VuePopper from 'element-ui/src/utils/vue-popper'; +import { createTest } from '../util'; + +const Popper = Object.assign({}, VuePopper, { + render(h) { + return h('div'); + }, + + created() { + this.popperElm = document.createElement('div'); + this.referenceElm = document.createElement('div'); + } +}); + +const CleanPopper = Object.assign({}, VuePopper, { + render(h) { + return h('div'); + } +}); + +describe('Utils:VuePopper', () => { + it('set popper not reference', () => { + const vm = createTest(CleanPopper, { + popper: document.createElement('div') + }); + vm.createPopper(); + expect(vm.popperElm).to.exist; + expect(vm.referenceElm).to.not.exist; + expect(vm.popperJS).to.not.exist; + }); + + it('set reference not popper', () => { + const vm = createTest(CleanPopper, { + reference: document.createElement('div') + }); + vm.createPopper(); + expect(vm.referenceElm).to.exist; + expect(vm.popperElm).to.not.exist; + expect(vm.popperJS).to.not.exist; + }); + + it('set reference by slot', () => { + const vm = createTest(CleanPopper); + vm.$slots['reference'] = [{ + elm: document.createElement('div') + }]; + vm.createPopper(); + expect(vm.referenceElm).to.exist; + expect(vm.popperElm).to.not.exist; + expect(vm.popperJS).to.not.exist; + }); + + it('createPopper', () => { + const vm = createTest(Popper, { placement: 'top' }); + vm.createPopper(); + expect(vm.popperJS._popper.getAttribute('x-placement')).to.equal('top'); + }); + + it('destroy popper when calling createPopper twice', () => { + const vm = createTest(Popper); + vm.createPopper(); + const popperJS = vm.popperJS; + + expect(vm.popperJS).to.exist; + expect(vm.popperJS).to.equal(popperJS); + vm.createPopper(); + expect(vm.popperJS).to.not.equal(popperJS); + }); + + it('updatePopper', () => { + const vm = createTest(Popper); + vm.updatePopper(); + const popperJS = vm.popperJS; + + expect(vm.popperJS).to.exist; + vm.updatePopper(); + expect(vm.popperJS).to.equal(popperJS); + }); + + it('doDestroy', () => { + const vm = createTest(Popper, { placement: 'top' }); + vm.createPopper(); + expect(vm.popperJS._popper.getAttribute('x-placement')).to.equal('top'); + vm.doDestroy(); + expect(vm.popperJS).to.not.exist; + }); + + it('destroyPopper', () => { + const vm = createTest(Popper); + const vm2 = createTest(Popper); + + vm.createPopper(); + expect(() => vm.destroyPopper()).to.not.throw(); + expect(() => vm2.destroyPopper()).to.not.throw(); + }); + + it('placement', () => { + const vm = createTest(Popper, { placement: 'bottom-start' }); + const vm2 = createTest(Popper, { placement: 'bottom-abc' }); + + vm.createPopper(); + vm2.createPopper(); + expect(vm.popperJS._popper.getAttribute('x-placement')).to.equal('bottom-start'); + expect(vm2.popperJS).to.not.exist; + }); + + it('display arrow', () => { + const vm = createTest(Popper, { + visibleArrow: true + }); + + vm.createPopper(); + expect(vm.popperJS._popper.querySelector('div[x-arrow]')).to.exist; + }); + + it('update showPopper', done => { + const vm = createTest(Popper); + expect(vm.popperJS).to.not.exist; + vm.showPopper = true; + setTimeout(_ => { + expect(vm.popperJS).to.exist; + vm.showPopper = false; + setTimeout(_ => { + expect(vm.popperJS).to.exist; + }, 50); + done(); + }, 50); + }); + + it('resetTransformOrigin', () => { + const vm = createTest(Popper, { + placement: 'left' + }); + vm.createPopper(); + expect(vm.popperJS._popper.style.transformOrigin).to.include('right center'); + }); + + it('appendArrow', () => { + const vm = createTest(Popper, { + visibleArrow: true + }); + expect(vm.appended).to.be.undefined; + vm.createPopper(); + expect(vm.appended).to.true; + vm.appendArrow(); + expect(vm.popperJS._popper.querySelector('[x-arrow]')).to.exist; + expect(vm.appended).to.true; + }); + + it('appendArrow: add scoped', () => { + const popper = document.createElement('div'); + popper.setAttribute('_v-110', true); + const vm = createTest(CleanPopper, { + reference: document.createElement('div'), + visibleArrow: true, + popper + }); + expect(vm.appended).to.be.undefined; + vm.createPopper(); + expect(vm.popperJS._popper.querySelector('[x-arrow][_v-110]')).to.exist; + }); + + it('appendToBody set false', () => { + const vm = createTest(Popper, { + appendToBody: false + }); + vm.createPopper(); + expect(document.body.contains(vm.popperElm)).to.false; + }); + + it('destroy', () => { + const vm = createTest(Popper, true); + + vm.createPopper(); + expect(document.body.contains(vm.popperElm)).to.true; + vm.$destroy(); + expect(document.body.contains(vm.popperElm)).to.false; + }); +}); diff --git a/test/unit/util.js b/test/unit/util.js new file mode 100644 index 0000000..f2cc5bd --- /dev/null +++ b/test/unit/util.js @@ -0,0 +1,121 @@ +import Vue from 'vue'; +import Element from 'main/index.js'; + +Vue.use(Element); + +let id = 0; + +const createElm = function() { + const elm = document.createElement('div'); + + elm.id = 'app' + ++id; + document.body.appendChild(elm); + + return elm; +}; + +/** + * 回收 vm + * @param {Object} vm + */ +export const destroyVM = function(vm) { + vm.$destroy && vm.$destroy(); + vm.$el && + vm.$el.parentNode && + vm.$el.parentNode.removeChild(vm.$el); +}; + +/** + * 创建一个 Vue 的实例对象 + * @param {Object|String} Compo 组件配置,可直接传 template + * @param {Boolean=false} mounted 是否添加到 DOM 上 + * @return {Object} vm + */ +export const createVue = function(Compo, mounted = false) { + if (Object.prototype.toString.call(Compo) === '[object String]') { + Compo = { template: Compo }; + } + return new Vue(Compo).$mount(mounted === false ? null : createElm()); +}; + +/** + * 创建一个测试组件实例 + * @link http://vuejs.org/guide/unit-testing.html#Writing-Testable-Components + * @param {Object} Compo - 组件对象 + * @param {Object} propsData - props 数据 + * @param {Boolean=false} mounted - 是否添加到 DOM 上 + * @return {Object} vm + */ +export const createTest = function(Compo, propsData = {}, mounted = false) { + if (propsData === true || propsData === false) { + mounted = propsData; + propsData = {}; + } + const elm = createElm(); + const Ctor = Vue.extend(Compo); + return new Ctor({ propsData }).$mount(mounted === false ? null : elm); +}; + +/** + * 触发一个事件 + * mouseenter, mouseleave, mouseover, keyup, change, click 等 + * @param {Element} elm + * @param {String} name + * @param {*} opts + */ +export const triggerEvent = function(elm, name, ...opts) { + let eventName; + + if (/^mouse|click/.test(name)) { + eventName = 'MouseEvents'; + } else if (/^key/.test(name)) { + eventName = 'KeyboardEvent'; + } else { + eventName = 'HTMLEvents'; + } + const evt = document.createEvent(eventName); + + evt.initEvent(name, ...opts); + elm.dispatchEvent + ? elm.dispatchEvent(evt) + : elm.fireEvent('on' + name, evt); + + return elm; +}; + +/** + * 触发 “mouseup” 和 “mousedown” 事件 + * @param {Element} elm + * @param {*} opts + */ +export const triggerClick = function(elm, ...opts) { + triggerEvent(elm, 'mousedown', ...opts); + triggerEvent(elm, 'mouseup', ...opts); + + return elm; +}; + +/** + * 触发 keydown 事件 + * @param {Element} elm + * @param {keyCode} int + */ +export const triggerKeyDown = function(el, keyCode) { + const evt = document.createEvent('Events'); + evt.initEvent('keydown', true, true); + evt.keyCode = keyCode; + el.dispatchEvent(evt); +}; + +/** + * 等待 ms 毫秒,返回 Promise + * @param {Number} ms + */ +export const wait = function(ms = 50) { + return new Promise(resolve => setTimeout(() => resolve(), ms)); +}; + +/** + * 等待一个 Tick,代替 Vue.nextTick,返回 Promise + */ +export const waitImmediate = () => wait(0); diff --git a/types/alert.d.ts b/types/alert.d.ts new file mode 100644 index 0000000..1698119 --- /dev/null +++ b/types/alert.d.ts @@ -0,0 +1,31 @@ +import { ElementUIComponent } from './component' + +export type AlertType = 'success' | 'warning' | 'info' | 'error' +export type AlertEffect = 'dark' | 'light' + +/** Alert Component */ +export declare class ElAlert extends ElementUIComponent { + /** Title */ + title: string + + /** Component type */ + type: AlertType + + /** Descriptive text. Can also be passed with the default slot */ + description: string + + /** If closable or not */ + closable: boolean + + /** whether to center the text */ + center: boolean + + /** Customized close button text */ + closeText: string + + /** If a type icon is displayed */ + showIcon: boolean + + /** Choose effect */ + effect: AlertEffect +} diff --git a/types/aside.d.ts b/types/aside.d.ts new file mode 100644 index 0000000..1d51fea --- /dev/null +++ b/types/aside.d.ts @@ -0,0 +1,7 @@ +import { ElementUIComponent } from './component' + +/** Aside Component */ +export declare class ElAside extends ElementUIComponent { + /** Width of the side section */ + width: string +} diff --git a/types/autocomplete.d.ts b/types/autocomplete.d.ts new file mode 100644 index 0000000..a56e8f3 --- /dev/null +++ b/types/autocomplete.d.ts @@ -0,0 +1,78 @@ +import { ElementUIComponent } from './component' + +export type SuggestionPlacement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' + +export interface FetchSuggestionsCallback { + /** + * Callback function used in fetch-suggestions function + * + * @param data Suggestions to use + */ + (data: any[]): void +} + +export interface FetchSuggestions { + /** + * The function passed into the fetch-suggestions property + * + * @param queryString Current value of the text input + * @param callback Callback function used to indicate that suggestions have completely fetched + */ + (queryString: string, callback: FetchSuggestionsCallback): void +} + +/** Autocomplete Component */ +export declare class ElAutocomplete extends ElementUIComponent { + /** The placeholder of Autocomplete */ + placeholder: string + + /** Whether to show clear button */ + clearable: boolean + + /** Whether Autocomplete is disabled */ + disabled: boolean + + /** Binding value */ + value: string + + /** Debounce delay when typing */ + debounce: number + + /** Placement of the popup menu */ + placement: SuggestionPlacement + + /** Name for the inner native input */ + name: string + + /** Key name of the input suggestion object for display */ + valueKey: string + + /** Whether to emit select event on enter when there is no autocomplete match */ + selectWhenUnmatched: boolean + + /** A method to fetch input suggestions. When suggestions are ready, invoke callback(data:[]) to return them to Autocomplete */ + fetchSuggestions: FetchSuggestions + + /** Custom class name for autocomplete's dropdown */ + popperClass: string + + /** Whether show suggestions when input focus */ + triggerOnFocus: boolean + + /** Prefix icon class */ + prefixIcon: string + + /** Suffix icon class */ + suffixIcon: string + + /** Whether to hide the loading icon in remote search */ + hideLoading: boolean + + /** Whether to append the dropdown to body */ + popperAppendToBody: boolean + + /** + * Focus the Input component + */ + focus (): void +} diff --git a/types/avatar.d.ts b/types/avatar.d.ts new file mode 100644 index 0000000..4002e0e --- /dev/null +++ b/types/avatar.d.ts @@ -0,0 +1,20 @@ +import { ElementUIComponent } from './component' + +/** Avatar Component */ +export declare class ElAvatar extends ElementUIComponent { + icon: string; + + size: string | number; + + shape: string; + + src: string; + + error: () => false; + + srcSet: string; + + alt: string; + + fit: string; +} diff --git a/types/backtop.d.ts b/types/backtop.d.ts new file mode 100644 index 0000000..a171c76 --- /dev/null +++ b/types/backtop.d.ts @@ -0,0 +1,16 @@ +import { ElementUIComponent } from './component' + +/** Backtop Component */ +export declare class ElBacktop extends ElementUIComponent { + /** Backtop target */ + target: string + + /** Backtop visibility height */ + visibilityHeight: string | number + + /** Backtop right position */ + right: string | number + + /** Backtop bottom position */ + bottom: string | number +} diff --git a/types/badge.d.ts b/types/badge.d.ts new file mode 100644 index 0000000..38e763f --- /dev/null +++ b/types/badge.d.ts @@ -0,0 +1,16 @@ +import { ElementUIComponent } from './component' + +/** Badge Component */ +export declare class ElBadge extends ElementUIComponent { + /** Display value */ + value: string | number + + /** Maximum value, shows '{max}+' when exceeded. Only works if `value` is a number */ + max: number + + /** If a little dot is displayed */ + isDot: boolean + + /** Hidden badge */ + hidden: boolean +} diff --git a/types/breadcrumb-item.d.ts b/types/breadcrumb-item.d.ts new file mode 100644 index 0000000..fb55c25 --- /dev/null +++ b/types/breadcrumb-item.d.ts @@ -0,0 +1,10 @@ +import { ElementUIComponent } from './component' + +/** Breadcrumb Item Component */ +export declare class ElBreadcrumbItem extends ElementUIComponent { + /** Target route of the link, same as to of vue-router */ + to: string | object + + /** If true, the navigation will not leave a history record */ + replace: boolean +} diff --git a/types/breadcrumb.d.ts b/types/breadcrumb.d.ts new file mode 100644 index 0000000..24d5ef7 --- /dev/null +++ b/types/breadcrumb.d.ts @@ -0,0 +1,10 @@ +import { ElementUIComponent } from './component' + +/** Displays the location of the current page, making it easier to browser back */ +export declare class ElBreadcrumb extends ElementUIComponent { + /** Separator character */ + separator: string + + /** Class name of the icon separator */ + separatorClass: string +} diff --git a/types/button-group.d.ts b/types/button-group.d.ts new file mode 100644 index 0000000..e8738bd --- /dev/null +++ b/types/button-group.d.ts @@ -0,0 +1,4 @@ +import { ElementUIComponent } from './component' + +/** Button Group Component */ +export declare class ElButtonGroup extends ElementUIComponent {} diff --git a/types/button.d.ts b/types/button.d.ts new file mode 100644 index 0000000..b81b8f6 --- /dev/null +++ b/types/button.d.ts @@ -0,0 +1,37 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' + +/** Button type */ +export type ButtonType = 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'text' + +/** Same as native button's type */ +export type ButtonNativeType = 'button' | 'submit' | 'reset' | 'menu' + +/** Button Component */ +export declare class ElButton extends ElementUIComponent { + /** Button size */ + size: ElementUIComponentSize + + /** Button type */ + type: ButtonType + + /** Determine whether it's a plain button */ + plain: boolean + + /** Determine whether it's a round button */ + round: boolean + + /** Determine whether it's loading */ + loading: boolean + + /** Disable the button */ + disabled: boolean + + /** Button icon, accepts an icon name of Element icon component */ + icon: string + + /** Same as native button's autofocus */ + autofocus: boolean + + /** Same as native button's type */ + nativeType: ButtonNativeType +} diff --git a/types/calendar.d.ts b/types/calendar.d.ts new file mode 100644 index 0000000..d487867 --- /dev/null +++ b/types/calendar.d.ts @@ -0,0 +1,15 @@ +import { ElementUIComponent } from './component' + +export type DateType = Date | String | Number + +/** Calendar Component */ +export declare class ElCalendar extends ElementUIComponent { + /** Binding value */ + value: DateType + + /** Specify the display range of the calendar */ + range: DateType[] + + /** First day of week */ + firstDayOfWeek: number +} diff --git a/types/card.d.ts b/types/card.d.ts new file mode 100644 index 0000000..7c5f122 --- /dev/null +++ b/types/card.d.ts @@ -0,0 +1,26 @@ +import { VNode, VNodeDirective } from 'vue' +import { ElementUIComponent } from './component' + +export interface CardSlots { + /** Content of the card */ + default: VNode[], + + /** Title of the card */ + header: VNode[] + + [key: string]: VNode[] +} + +/** Integrate information in a card container */ +export declare class ElCard extends ElementUIComponent { + /** Title of the card */ + header: string + + /** CSS style of body */ + bodyStyle: object + + /** When to show card shadows */ + shadow: string + + $slots: CardSlots +} diff --git a/types/carousel-item.d.ts b/types/carousel-item.d.ts new file mode 100644 index 0000000..9ae7ce2 --- /dev/null +++ b/types/carousel-item.d.ts @@ -0,0 +1,10 @@ +import { ElementUIComponent } from './component' + +/** Carousel Item Component */ +export declare class ElCarouselItem extends ElementUIComponent { + /** Name of the item, can be used in setActiveItem */ + name: string + + /** Text content for the corresponding indicator */ + label: string +} diff --git a/types/carousel.d.ts b/types/carousel.d.ts new file mode 100644 index 0000000..994a048 --- /dev/null +++ b/types/carousel.d.ts @@ -0,0 +1,57 @@ +import { ElementUIComponent } from './component' + +export type CarouselIndicatorTrigger = 'hover' | 'click' +export type CarouselIndicatorPosition = 'outside' | 'none' +export type CarouselArrowVisibility = 'always' | 'hover' | 'never' +export type CarouselType = 'card' +export type CarouselDirection = 'horizontal' | 'vertical' + +/** Loop a series of images or texts in a limited space */ +export declare class ElCarousel extends ElementUIComponent { + /** Height of the carousel */ + height: number + + /** Index of the initially active slide (starting from 0) */ + initialIndex: number + + /** How indicators are triggered */ + trigger: CarouselIndicatorTrigger + + /** Whether automatically loop the slides */ + autoplay: boolean + + /** Interval of the auto loop, in milliseconds */ + interval: number + + /** Position of the indicators */ + indicatorPosition: CarouselIndicatorPosition + + /** When arrows are shown */ + arrow: CarouselArrowVisibility + + /** Type of the Carousel */ + type: CarouselType + + /** Display direction */ + direction: CarouselDirection + + /** + * Manually switch slide by index + * + * @param index Index of the slide to be switched to (starting from 0) + */ + setActiveItem (index: number): void + + /** + * Manually switch slide by carousel item's name + * + * @param name The name of the corresponding `el-carousel-item` + */ + setActiveItem (name: string): void + + /** Switch to the previous slide */ + prev (): void + + /** Switch to the next slide */ + next (): void +} diff --git a/types/cascader-panel.d.ts b/types/cascader-panel.d.ts new file mode 100644 index 0000000..5c2049c --- /dev/null +++ b/types/cascader-panel.d.ts @@ -0,0 +1,72 @@ +import { VNode, CreateElement } from 'vue'; +import { ElementUIComponent } from './component' + +/** Trigger mode of expanding current item */ +export type ExpandTrigger = 'click' | 'hover' + +/** Cascader Option */ +export interface CascaderOption { + label: string, + value: any, + children?: CascaderOption[], + disabled?: boolean, + leaf?: boolean +} + +/** Cascader Props */ +export interface CascaderProps { + expandTrigger?: ExpandTrigger, + multiple?: boolean, + checkStrictly?: boolean, + emitPath?: boolean, + lazy?: boolean, + lazyLoad?: (node: CascaderNode, resolve: Resolve) => void, + value?: string, + label?: string, + children?: string, + disabled?: string + leaf?: string +} + +/** Cascader Node */ +export interface CascaderNode { + uid: number, + data: D, + value: V, + label: string, + level: number, + isDisabled: boolean, + isLeaf: boolean, + parent: CascaderNode | null, + children: CascaderNode[] + config: CascaderProps +} + +type Resolve = (dataList?: D[]) => void + +export interface CascaderPanelSlots { + /** Custom label content */ + default: VNode[] + + [key: string]: VNode[] +} + +/** CascaderPanel Component */ +export declare class ElCascaderPanel extends ElementUIComponent { + /** Selected value */ + value: V | V[] + + /** Data of the options */ + options: D[] + + /** Configuration options */ + props: CascaderProps + + /** Whether to add border */ + border: boolean + + /** Render function of custom label content */ + renderLabel: (h: CreateElement, context: { node: CascaderNode; data: D }) => VNode + + $slots: CascaderPanelSlots +} diff --git a/types/cascader.d.ts b/types/cascader.d.ts new file mode 100644 index 0000000..4d79973 --- /dev/null +++ b/types/cascader.d.ts @@ -0,0 +1,65 @@ +import { VNode } from 'vue'; +import { ElementUIComponent, ElementUIComponentSize } from './component' +import { CascaderOption, CascaderProps, CascaderNode } from './cascader-panel'; + +export { CascaderOption, CascaderProps, CascaderNode }; + +export interface CascaderSlots { + /** Custom label content */ + default: VNode[], + + /** Empty content when no option matches */ + empty: VNode[] + + [key: string]: VNode[] +} + +/** Cascader Component */ +export declare class ElCascader extends ElementUIComponent { + /** Data of the options */ + options: CascaderOption[] + + /** Configuration options */ + props: CascaderProps + + /** Selected value */ + value: V | V[] + + /** Size of Input */ + size: ElementUIComponentSize + + /** Input placeholder */ + placeholder: string + + /** Whether Cascader is disabled */ + disabled: boolean + + /** Whether selected value can be cleared */ + clearable: boolean + + /** Whether to display all levels of the selected value in the input */ + showAllLevels: boolean + + /** Whether to collapse selected tags in multiple selection mode */ + collapseTags: boolean + + /** Separator of option labels */ + separator: string + + /** Whether the options can be searched */ + filterable: boolean + + /** filter method to match options according to input keyword */ + filterMethod: (node: CascaderNode, keyword: string) => boolean + + /** Debounce delay when typing filter keyword, in millisecond */ + debounce: number + + /** Custom class name for Cascader's dropdown */ + popperClass: string + + /** Hook function before filtering with the value to be filtered as its parameter */ + beforeFilter: (value: string) => boolean | Promise + + $slots: CascaderSlots +} diff --git a/types/checkbox-button.d.ts b/types/checkbox-button.d.ts new file mode 100644 index 0000000..dce7562 --- /dev/null +++ b/types/checkbox-button.d.ts @@ -0,0 +1,22 @@ +import { ElementUIComponent } from './component' + +/** Checkbox Button Component */ +export declare class ElCheckboxButton extends ElementUIComponent { + /** Value of the checkbox when used inside a checkbox-group */ + label: string | number | boolean + + /** Value of the checkbox if it's checked */ + trueLabel: string | number + + /** Value of the checkbox if it's not checked */ + falseLabel: string | number + + /** Native 'name' attribute */ + name: string + + /** If the checkbox is disabled */ + disabled: boolean + + /** If the checkbox is checked */ + checked: boolean +} diff --git a/types/checkbox-group.d.ts b/types/checkbox-group.d.ts new file mode 100644 index 0000000..250554c --- /dev/null +++ b/types/checkbox-group.d.ts @@ -0,0 +1,22 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' + +/** Checkbox Group Component */ +export declare class ElCheckboxGroup extends ElementUIComponent { + /** Size of checkbox buttons or bordered checkboxes */ + size: ElementUIComponentSize + + /** Whether the nesting checkboxes are disabled */ + disabled: boolean + + /** Minimum number of checkbox checked */ + min: number + + /** Maximum number of checkbox checked */ + max: number + + /** Font color when button is active */ + textColor: string + + /** Border and background color when button is active */ + fill: string +} diff --git a/types/checkbox.d.ts b/types/checkbox.d.ts new file mode 100644 index 0000000..aec7c57 --- /dev/null +++ b/types/checkbox.d.ts @@ -0,0 +1,34 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' + +/** Checkbox Component */ +export declare class ElCheckbox extends ElementUIComponent { + /** The form input value */ + value: string | string[] + + /** Value of the checkbox when used inside a checkbox-group */ + label: string | number | boolean + + /** Value of the checkbox if it's checked */ + trueLabel: string | number + + /** Value of the checkbox if it's not checked */ + falseLabel: string | number + + /** Native 'name' attribute */ + name: string + + /** Whether to add a border around Checkbox */ + border: boolean + + /** Size of the Checkbox, only works when border is true */ + size: ElementUIComponentSize + + /** If the checkbox is disabled */ + disabled: boolean + + /** If the checkbox is checked */ + checked: boolean + + /** Same as indeterminate in native checkbox */ + indeterminate: boolean +} diff --git a/types/col.d.ts b/types/col.d.ts new file mode 100644 index 0000000..bbdb332 --- /dev/null +++ b/types/col.d.ts @@ -0,0 +1,46 @@ +import { ElementUIComponent } from './component' + +/** Responsive column props */ +export interface ResponsiveColumnProperties { + /** Number of column the grid spans */ + span: number, + + /** Number of spacing on the left side of the grid */ + offset: number +} + +/** Responsive column property */ +export type ResponsiveColumn = number | ResponsiveColumnProperties + +/** Colunm Layout Component */ +export declare class ElCol extends ElementUIComponent { + /** Number of column the grid spans */ + span: number + + /** Number of spacing on the left side of the grid */ + offset: number + + /** Number of columns that grid moves to the right */ + push: number + + /** Number of columns that grid moves to the left */ + pull: number + + /** <768px Responsive columns or column props object */ + xs: ResponsiveColumn + + /** ≥768px Responsive columns or column props object */ + sm: ResponsiveColumn + + /** ≥992px Responsive columns or column props object */ + md: ResponsiveColumn + + /** ≥1200px Responsive columns or column props object */ + lg: ResponsiveColumn + + /** ≥1920px Responsive columns or column props object */ + xl: ResponsiveColumn + + /** custom element tag */ + tag: string +} diff --git a/types/collapse-item.d.ts b/types/collapse-item.d.ts new file mode 100644 index 0000000..f780dd7 --- /dev/null +++ b/types/collapse-item.d.ts @@ -0,0 +1,26 @@ +import { VNode } from 'vue' +import { ElementUIComponent } from './component' + +export interface CollapseItemSlots { + /** Content of the collapse item */ + default: VNode[], + + /** Title of the collapse item */ + title: VNode[] + + [key: string]: VNode[] +} + +/** Collapse Item Component */ +export declare class ElCollapseItem extends ElementUIComponent { + /** Unique identification of the panel */ + name: string | number + + /** Title of the panel */ + title: string + + $slots: CollapseItemSlots + + /** Disable the collapse item */ + disabled: boolean +} diff --git a/types/collapse.d.ts b/types/collapse.d.ts new file mode 100644 index 0000000..78af337 --- /dev/null +++ b/types/collapse.d.ts @@ -0,0 +1,10 @@ +import { ElementUIComponent } from './component' + +/** Use Collapse to store contents. */ +export declare class ElCollapse extends ElementUIComponent { + /** Whether to activate accordion mode */ + accordion: boolean + + /** Currently active panel */ + value: string | number | string[] | number[] +} diff --git a/types/color-picker.d.ts b/types/color-picker.d.ts new file mode 100644 index 0000000..a3bc53c --- /dev/null +++ b/types/color-picker.d.ts @@ -0,0 +1,21 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' + +export type ColorFormat = 'hsl' | 'hsv' | 'hex' | 'rgb' + +/** ColorPicker Component */ +export declare class ElColorPicker extends ElementUIComponent { + /** Whether to display the alpha slider */ + showAlpha: boolean + + /** Whether to disable the ColorPicker */ + disabled: boolean + + /** Size of ColorPicker */ + size: ElementUIComponentSize + + /** Whether to display the alpha slider */ + popperClass: string + + /** Custom class name for ColorPicker's dropdown */ + colorFormat: ColorFormat +} diff --git a/types/component.d.ts b/types/component.d.ts new file mode 100644 index 0000000..61bf6bc --- /dev/null +++ b/types/component.d.ts @@ -0,0 +1,13 @@ +import Vue from 'vue' + +/** ElementUI component common definition */ +export declare class ElementUIComponent extends Vue { + /** Install component into Vue */ + static install (vue: typeof Vue): void +} + +/** Component size definition for button, input, etc */ +export type ElementUIComponentSize = 'large' | 'medium' | 'small' | 'mini' + +/** Horizontal alignment */ +export type ElementUIHorizontalAlignment = 'left' | 'center' | 'right' diff --git a/types/container.d.ts b/types/container.d.ts new file mode 100644 index 0000000..b0fc5d5 --- /dev/null +++ b/types/container.d.ts @@ -0,0 +1,7 @@ +import { ElementUIComponent } from './component' + +/** Container Component */ +export declare class ElContainer extends ElementUIComponent { + /** Layout direction for child elements */ + direction: 'horizontal' | 'vertical' +} diff --git a/types/date-picker.d.ts b/types/date-picker.d.ts new file mode 100644 index 0000000..b4e9e6f --- /dev/null +++ b/types/date-picker.d.ts @@ -0,0 +1,124 @@ +import { ElementUIComponent, ElementUIComponentSize, ElementUIHorizontalAlignment } from './component' + +export type DatePickerType = 'year' | 'month' | 'date' | 'datetime' | 'week' | 'datetimerange' | 'daterange' | 'dates' +export type FirstDayOfWeek = 1 | 2 | 3 | 4 | 5 | 6 | 7 + +export interface DisabledDateChecker { + /** + * Determine if `date` will be disabled in the picker + * + * @param date The date to check + * @returns if `date` will be disabled in the picker + */ + (date: Date): boolean +} + +// Picked date range +export interface DateRange { + minDate: Date, + maxDate: Date +} + +export interface PickEventHandler { + /** + * Callback function that triggers when picks a date range + * + * @param dateRange The selected date range + */ + (dateRange: DateRange): void +} + +export interface ShortcutClickEventHandler { + /** + * Callback function that triggers when clicking on a shortcut. + * You can change the picker value by emitting the pick event. + * Example: `vm.$emit('pick', new Date())` + */ + (vm: ElDatePicker): void +} + +/** Shortcut options */ +export interface Shortcut { + /** Title of the shortcut */ + text: string, + + /** Callback function that triggers when picks a date range */ + onClick?: ShortcutClickEventHandler +} + +/** Options of el-date-picker */ +export interface DatePickerOptions { + /** An object array to set shortcut options */ + shortcuts?: Shortcut[] + + /** A function determining if a date is disabled. */ + disabledDate?: DisabledDateChecker + + /** First day of week */ + firstDayOfWeek?: FirstDayOfWeek + + /** A callback that triggers when the seleted date is changed. Only for daterange and datetimerange. */ + onPick?: PickEventHandler +} + +/** DatePicker Component */ +export declare class ElDatePicker extends ElementUIComponent { + /** The value of the date picker */ + value: Date | string | Date[] | string[] + + /** Whether DatePicker is read only */ + readonly: boolean + + /** Whether DatePicker is disabled */ + disabled: boolean + + /** Size of Input */ + size: ElementUIComponentSize + + /** Whether the input is editable */ + editable: boolean + + /** Whether to show clear button */ + clearable: boolean + + /** Placeholder */ + placeholder: string + + /** Placeholder for the start date in range mode */ + startPlaceholder: string + + /** Placeholder for the end date in range mode */ + endPlaceholder: string + + /** Type of the picker */ + type: DatePickerType + + /** Format of the picker */ + format: string + + /** Alignment */ + align: ElementUIHorizontalAlignment + + /** Custom class name for DatePicker's dropdown */ + popperClass: string + + /** Additional options, check the table below */ + pickerOptions: DatePickerOptions + + /** Range separator */ + rangeSeparator: string + + /** Default date of the calendar */ + defaultValue: Date | number | string + + /** Format of binding value. If not specified, the binding value will be a Date object */ + valueFormat: string + + /** name for the inner native input */ + name: string + + /** + * Focus the Input component + */ + focus (): void +} diff --git a/types/dialog.d.ts b/types/dialog.d.ts new file mode 100644 index 0000000..f4e218d --- /dev/null +++ b/types/dialog.d.ts @@ -0,0 +1,62 @@ +import { VNode } from 'vue' +import { ElementUIComponent } from './component' + +export interface DialogSlots { + /** Content of the Dialog */ + default: VNode[], + + /** Content of the Dialog title */ + title: VNode[], + + /** Content of the Dialog footer */ + footer: VNode[], + + [key: string]: VNode[] +} + +/** Informs users while preserving the current page state */ +export declare class ElDialog extends ElementUIComponent { + /** Title of Dialog */ + title: string + + /** Width of Dialog */ + width: string + + /** Whether the Dialog takes up full screen */ + fullscreen: boolean + + /** Value for margin-top of Dialog CSS */ + top: string + + /** Whether a mask is displayed */ + modal: boolean + + /** Whether to append modal to body element. If false, the modal will be appended to Dialog's parent element */ + modalAppendToBody: boolean + + /** Whether scroll of body is disabled while Dialog is displayed */ + lockScroll: boolean + + /** Custom class names for Dialog */ + customClass: string + + /** Whether the Dialog can be closed by clicking the mask */ + closeOnClickModal: boolean + + /** Whether the Dialog can be closed by pressing ESC */ + closeOnPressEscape: boolean + + /** Whether to show a close button */ + showClose: boolean + + /** Callback before Dialog closes, and it will prevent Dialog from closing */ + beforeClose: (done: Function) => void + + /** Whether to align the header and footer in center */ + center: boolean + + /** Whether to destroy elements in Dialog when closed */ + destroyOnClose: boolean + + $slots: DialogSlots +} diff --git a/types/divider.d.ts b/types/divider.d.ts new file mode 100644 index 0000000..c7d969c --- /dev/null +++ b/types/divider.d.ts @@ -0,0 +1,12 @@ +import { ElementUIComponent } from './component' + +export type ContentPosition = 'left' | 'center' | 'right' + +/** Divider Component */ +export declare class ElDivider extends ElementUIComponent { + /** enable vertical divider */ + vertical: boolean + + /** customize the content on the divider line */ + posiiton: ContentPosition +} diff --git a/types/drawer.d.ts b/types/drawer.d.ts new file mode 100644 index 0000000..8d2d7f3 --- /dev/null +++ b/types/drawer.d.ts @@ -0,0 +1,63 @@ +import { ElementUIComponent } from './component' +import { VNode } from 'vue' + +type hide = (shouldCancel: boolean) => void +declare enum Direction { + LTR = 'ltr', // left to right + RTL = 'rtl', // right to left + TTB = 'ttb', // top to bottom + BTT = 'btt' // bottom to top +} + +interface DrawerSlots { + /* Main Content Slots */ + default: VNode[]; + + /* Title Slots */ + title: VNode[]; + + [key: string]: VNode[] +} +/** Drawer Component */ +export declare class ElDrawer extends ElementUIComponent { + /* Equivalent to `Dialog`'s append to body attribute, when applying nested drawer, make sure this one is set to true */ + appendToBody: boolean + + /* Hook method called before close drawer, the first parameter is a function which should determine if the drawer should be closed */ + beforeClose: (done: hide) => void + + /** Whether the Drawer can be closed by pressing ESC */ + closeOnPressEscape: boolean + + /** Custom class names for Dialog */ + customClass: string + + /* Determine whether the wrapped children should be destroyed, if true, children's destroyed life cycle method will be called all local state will be destroyed */ + destroyOnClose: boolean + + /* Equivalent to `Dialog`'s modal attribute, determines whether the dark shadowing background should show */ + modal: boolean + + /* Equivalent to `Dialog`'s modal-append-to-body attribute, determines whether the shadowing background should be inserted direct to DocumentBody element */ + modalAppendToBody: boolean + + /* Attributes that controls the drawer's direction of display*/ + position: Direction + + /* Whether the close button should be rendered to control the drawer's visible state */ + showClose: boolean + + /* The size of the drawer component, supporting number with unit of pixel, string by percentage e.g. 30% */ + size: number | string + + /* The Drawer's title, also can be replaced by named slot `title` */ + title: string + + /* Whether the drawer component should show, also can be decorated by `.sync` */ + visible: boolean + + /* Flag attribute whi */ + wrapperClosable: boolean + + $slots: DrawerSlots +} diff --git a/types/dropdown-item.d.ts b/types/dropdown-item.d.ts new file mode 100644 index 0000000..7671424 --- /dev/null +++ b/types/dropdown-item.d.ts @@ -0,0 +1,16 @@ +import { ElementUIComponent } from './component' + +/** Toggleable menu for displaying lists of links and actions. */ +export declare class ElDropdownItem extends ElementUIComponent { + /** A command to be dispatched to Dropdown's command callback */ + command: string | number | object + + /** Whether the item is disabled */ + disabled: boolean + + /** Whether a divider is displayed */ + divided: boolean + + /** Icon to show on left side of text */ + icon: string +} diff --git a/types/dropdown-menu.d.ts b/types/dropdown-menu.d.ts new file mode 100644 index 0000000..74dc4b8 --- /dev/null +++ b/types/dropdown-menu.d.ts @@ -0,0 +1,4 @@ +import { ElementUIComponent } from './component' + +/** Dropdown Menu Component */ +export declare class ElDropdownMenu extends ElementUIComponent {} diff --git a/types/dropdown.d.ts b/types/dropdown.d.ts new file mode 100644 index 0000000..53df211 --- /dev/null +++ b/types/dropdown.d.ts @@ -0,0 +1,35 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' +import { ButtonType } from './button' + +export type DropdownMenuAlignment = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' +export type DropdownMenuTrigger = 'hover' | 'click' + +/** Toggleable menu for displaying lists of links and actions */ +export declare class ElDropdown extends ElementUIComponent { + /** Menu button type. only works when split-button is true */ + type: ButtonType + + /** Whether a button group is displayed */ + splitButton: boolean + + /** menu size, also works on the split button */ + size: ElementUIComponentSize + + /** Placement of the menu */ + placement: DropdownMenuAlignment + + /** How to trigger */ + trigger: DropdownMenuTrigger + + /** Whether to hide menu after clicking menu-item */ + hideOnClick: boolean + + /** Delay time before show a dropdown */ + showTimeout: number + + /** Delay time before hide a dropdown */ + hideTimeout: number + + /** Dropdown tabindex */ + tabindex: number +} diff --git a/types/element-ui.d.ts b/types/element-ui.d.ts new file mode 100644 index 0000000..ea819db --- /dev/null +++ b/types/element-ui.d.ts @@ -0,0 +1,346 @@ +import Vue, { PluginObject } 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 { ElCheckboxButton } from './checkbox-button' +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 { ElTimeline } from './timeline' +import { ElTimelineItem } from './timeline-item' +import { ElTimePicker } from './time-picker' +import { ElTimeSelect } from './time-select' +import { ElTooltip } from './tooltip' +import { ElTransfer } from './transfer' +import { ElTree, TreeData } from './tree' +import { ElUpload } from './upload' +import { ElLink } from './link' +import { ElDivider } from './divider' +import { ElIcon } from './icon' +import { ElCalendar } from './calendar' +import { ElImage } from './image' +import { ElBacktop } from './backtop' +import { ElInfiniteScroll } from './infinite-scroll' +import { ElPageHeader } from './page-header' +import { ElAvatar } from './avatar' +import { ElDrawer } from './drawer' +import { ElPopconfirm } from './popconfirm' + +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 Button Component */ +export class CheckboxButton extends ElCheckboxButton {} + +/** 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 {} + +/** Timeline Component */ +export class Timeline extends ElTimeline {} + +/** Timeline Item Component */ +export class TimelineItem extends ElTimelineItem {} + +/** TimePicker Component */ +export class TimePicker extends ElTimePicker {} + +/** TimeSelect Component */ +export class TimeSelect extends ElTimeSelect {} + +/** 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 {} + +/** Divider Component */ +export class Divider extends ElDivider {} + +/** Link Component */ +export class Link extends ElLink {} + +/** Image Component */ +export class Image extends ElImage {} + +/** Icon Component */ +export class Icon extends ElIcon {} + +/** Calendar Component */ +export class Calendar extends ElCalendar {} + +/** Backtop Component */ +export class Backtop extends ElBacktop {} + +/** InfiniteScroll Directive */ +export const InfiniteScroll: PluginObject; + +/** PageHeader Component */ +export class PageHeader extends ElPageHeader {} + +/** Avatar Component */ +export class Avatar extends ElAvatar {} + +/** Drawer Component */ +export class Drawer extends ElDrawer {} + +/** Popconfirm Component */ +export class Popconfirm extends ElPopconfirm {} diff --git a/types/footer.d.ts b/types/footer.d.ts new file mode 100644 index 0000000..16ea27d --- /dev/null +++ b/types/footer.d.ts @@ -0,0 +1,7 @@ +import { ElementUIComponent } from './component' + +/** Footer Component */ +export declare class ElFooter extends ElementUIComponent { + /** Height of the footer */ + height: string +} diff --git a/types/form-item.d.ts b/types/form-item.d.ts new file mode 100644 index 0000000..fdbd68e --- /dev/null +++ b/types/form-item.d.ts @@ -0,0 +1,37 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' + +/** FormItem Component */ +export declare class ElFormItem extends ElementUIComponent { + /** A key of `model` of the enclosing `el-form` component */ + prop: string + + /** Label */ + label: string + + /** Width of label, e.g. '50px' */ + labelWidth: string + + /** Whether the field is required or not, will be determined by validation rules if omitted */ + required: boolean + + /** Validation rules of form */ + rules: object + + /** Field error message, set its value and the field will validate error and show this message immediately */ + error: string + + /** Whether to show the error message */ + showMessage: boolean + + /** Whether to display the error message inline with the form item */ + inlineMessage: boolean + + /** Controls the size of components in this form */ + size: ElementUIComponentSize + + /** Reset current field and remove validation result */ + resetField (): void + + /** Remove validation status of the field */ + clearValidate (): void +} diff --git a/types/form.d.ts b/types/form.d.ts new file mode 100644 index 0000000..4b2b05a --- /dev/null +++ b/types/form.d.ts @@ -0,0 +1,82 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' + +export type FormItemLabelPosition = 'left' | 'right' | 'top' + +export interface ValidateCallback { + /** + * The callback to tell the validation result + * + * @param isValid Whether the form is valid + * @param invalidFields fields that fail validation + */ + (isValid: boolean, invalidFields: object): void +} + +export interface ValidateFieldCallback { + /** + * The callback to tell the field validation result + * + * @param errorMessage The error message. It will be empty if there is no error + */ + (errorMessage: string): void +} + +/** Form Component */ +export declare class ElForm extends ElementUIComponent { + /** Data of form component */ + model: object + + /** Validation rules of form */ + rules: object + + /** Whether the form is inline */ + inline: boolean + + /** Whether the form is disabled */ + disabled: boolean + + /** Position of label */ + labelPosition: FormItemLabelPosition + + /** Width of label, and all form items will inherit from Form */ + labelWidth: string + + /** Suffix of the label */ + labelSuffix: string + + /** Whether to show the error message */ + showMessage: boolean + + /** Whether to display the error message inline with the form item */ + inlineMessage: boolean + + /** Whether to display an icon indicating the validation result */ + statusIcon: boolean + + /** Whether to trigger validation when the `rules` prop is changed */ + validateOnRuleChange: boolean + + /** Controls the size of components in this form */ + size: ElementUIComponentSize + + /** + * Validate the whole form + * + * @param callback A callback to tell the validation result + */ + validate (callback: ValidateCallback): void + validate (): Promise + /** + * Validate certain form items + * + * @param props The property of `model` or array of prop which is going to validate + * @param callback A callback to tell the field validation result + */ + validateField (props: string | string[], callback?: ValidateFieldCallback): void + + /** reset all the fields and remove validation result */ + resetFields (): void + + /** clear validation message for certain fields */ + clearValidate (props?: string | string[]): void +} diff --git a/types/header.d.ts b/types/header.d.ts new file mode 100644 index 0000000..bb63b82 --- /dev/null +++ b/types/header.d.ts @@ -0,0 +1,7 @@ +import { ElementUIComponent } from './component' + +/** Header Component */ +export declare class ElHeader extends ElementUIComponent { + /** Height of the header */ + height: string +} diff --git a/types/icon.d.ts b/types/icon.d.ts new file mode 100644 index 0000000..ff3ed4d --- /dev/null +++ b/types/icon.d.ts @@ -0,0 +1,7 @@ +import { ElementUIComponent } from './component' + +/** Icon Component */ +export declare class ElIcon extends ElementUIComponent { + /** Icon name */ + name: string +} diff --git a/types/image.d.ts b/types/image.d.ts new file mode 100644 index 0000000..82b18dc --- /dev/null +++ b/types/image.d.ts @@ -0,0 +1,41 @@ +import { VNode } from 'vue' +import { ElementUIComponent } from './component' + +export type ObjectFit = 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' + +export interface ImageSlots { + /** Placeholder content when image hasn't loaded yet */ + placeholder: VNode[] + + /** Error content when error occurs to image load */ + error: VNode[] + + [key: string]: VNode[] +} + +/** Image Component */ +export declare class ElImage extends ElementUIComponent { + /** Image source */ + src: string + + /** Indicate how the image should be resized to fit its container, same as native 'object-fit' */ + fit: ObjectFit + + /** Whether to use lazy load */ + lazy: boolean + + /** Scroll container that to add scroll listener when using lazy load */ + scrollContainer: string | HTMLElement + + /** Native 'alt' attribute */ + alt: string + + /** Native 'referrerPolicy' attribute */ + referrerPolicy: string + + $slots: ImageSlots + + previewSrcList: string[] + + zIndex: number +} diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..b02a041 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,4 @@ +export * from './element-ui' + +import * as ElementUI from './element-ui' +export default ElementUI diff --git a/types/infinite-scroll.d.ts b/types/infinite-scroll.d.ts new file mode 100644 index 0000000..4fbeb3d --- /dev/null +++ b/types/infinite-scroll.d.ts @@ -0,0 +1,6 @@ +import { VNodeDirective } from 'vue' + +export interface ElInfiniteScroll extends VNodeDirective { + name: 'infinite-scroll', + value: Function +} \ No newline at end of file diff --git a/types/input-number.d.ts b/types/input-number.d.ts new file mode 100644 index 0000000..76288ff --- /dev/null +++ b/types/input-number.d.ts @@ -0,0 +1,47 @@ +import { ElementUIComponent } from './component' + +export type InputNumberSize = 'large' | 'small' + +/** InputNumber Component */ +export declare class ElInputNumber extends ElementUIComponent { + /** Binding value */ + value: number + + /** The minimum allowed value */ + min: number + + /** The maximum allowed value */ + max: number + + /** Incremental step */ + step: number + + /** Size of the component */ + size: InputNumberSize + + /** Whether the component is disabled */ + disabled: boolean + + /** Whether to enable the control buttons */ + controls: boolean + + /** Debounce delay when typing, in milliseconds */ + debounce: number + + /** Position of the control buttons */ + controlsPosition: string + + /** Same as name in native input */ + name: string + + /** Precision of input value */ + precision: number + + /** whether input value can only be multiple of step */ + stepStrictly: boolean + + /** + * Focus the Input component + */ + focus (): void +} diff --git a/types/input.d.ts b/types/input.d.ts new file mode 100644 index 0000000..a67ef88 --- /dev/null +++ b/types/input.d.ts @@ -0,0 +1,107 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' + +/** The resizability of el-input component */ +export type Resizability = 'none' | 'both' | 'horizontal' | 'vertical' +export type InputType = 'text' | 'textarea' + +/** Controls how el-input component automatically sets size */ +export interface AutoSize { + /** Minimum rows to show */ + minRows: number, + + /** Maximum rows to show */ + maxRows: number +} + +/** Input Component */ +export declare class ElInput extends ElementUIComponent { + /** Type of input */ + type: InputType + + /** Binding value */ + value: string | number + + /** Maximum Input text length */ + maxlength: number + + /** Minimum Input text length */ + minlength: number + + /** Placeholder of Input */ + placeholder: string + + /** Whether Input is disabled */ + disabled: boolean + + /** Size of Input, works when type is not 'textarea' */ + size: ElementUIComponentSize + + /** Prefix icon class */ + prefixIcon: string + + /** Suffix icon class */ + suffixIcon: string + + /** Number of rows of textarea, only works when type is 'textarea' */ + rows: number + + /** Whether textarea has an adaptive height, only works when type is 'textarea' */ + autosize: boolean | AutoSize + + /** @Deprecated in next major version */ + autoComplete: string + + /** Same as autocomplete in native input */ + autocomplete: string + + /** Same as name in native input */ + name: string + + /** Same as readonly in native input */ + readonly: boolean + + /** Same as max in native input */ + max: any + + /** Same as min in native input */ + min: any + + /** Same as step in native input */ + step: any + + /** Control the resizability */ + resize: Resizability + + /** Same as autofocus in native input */ + autofocus: boolean + + /** Same as form in native input */ + form: string + + /** Whether to trigger form validatio */ + validateEvent: boolean + + /** Whether the input is clearable */ + clearable: boolean + + /** Whether to show password */ + showPassword: boolean + + /** Whether to show wordCount when setting maxLength */ + showWordLimit: boolean + + /** + * Focus the Input component + */ + focus (): void + + /** + * Blur the Input component + */ + blur (): void + + /** + * Select the text in input element + */ + select (): void +} diff --git a/types/link.d.ts b/types/link.d.ts new file mode 100644 index 0000000..c7ed7dd --- /dev/null +++ b/types/link.d.ts @@ -0,0 +1,25 @@ +import { ElementUIComponent } from './component' + +/** Button type */ +export type LinkType = 'primary' | 'success' | 'warning' | 'danger' | 'info' + +/** Link Component */ +export declare class ElLink extends ElementUIComponent { + /** Link type */ + type: LinkType + + /** Disable the link */ + disabled: boolean + + /** Link underline */ + underline: boolean + + /** Link icon, accepts an icon name of Element icon component */ + icon: string + + /** Link href */ + href: string + + /** Link target */ + target: string +} diff --git a/types/loading.d.ts b/types/loading.d.ts new file mode 100644 index 0000000..45c1b98 --- /dev/null +++ b/types/loading.d.ts @@ -0,0 +1,62 @@ +import Vue, { VNodeDirective, PluginObject } from 'vue' + +/** Options used in Loading service */ +export interface LoadingServiceOptions { + /** The DOM node Loading needs to cover. Accepts a DOM object or a string. If it's a string, it will be passed to `document.querySelector` to get the corresponding DOM node */ + target?: HTMLElement | string + + /** Whether to make the mask append to the body element */ + body?: boolean + + /** Whether to show the loading mask in fullscreen */ + fullscreen?: boolean + + /** Whether to disable scrolling on body */ + lock?: boolean + + /** Loading text that displays under the spinner */ + text?: string + + /** Class name of the custom spinner */ + spinner?: string + + /** Background color of the mask */ + background?: string + + /** Custom class name for Loading */ + customClass?: string +} + +/** Loading Component */ +export declare class ElLoadingComponent extends Vue { + /** Close the Loading instance */ + close (): void +} + +/** Loading directive definition */ +export interface ElLoadingDirective extends VNodeDirective { + name: 'loading', + value: boolean, + modifiers: { + body: boolean, + fullscreen: boolean + } +} + +/** Show animation while loading data */ +export interface ElLoading { + /** Install Loading directive into Vue */ + install (vue: typeof Vue): void + + /** If you do not have a specific DOM node to attach the Loading directive, or if you simply prefer not to use Loading as a directive, you can call this service with some configs to open a Loading instance. */ + service (options: LoadingServiceOptions): ElLoadingComponent + + directive: PluginObject +} + +declare module 'vue/types/vue' { + interface Vue { + /** If you do not have a specific DOM node to attach the Loading directive, or if you simply prefer not to use Loading as a directive, you can call this service with some configs to open a Loading instance. */ + $loading (options: LoadingServiceOptions): ElLoadingComponent + } +} diff --git a/types/main.d.ts b/types/main.d.ts new file mode 100644 index 0000000..5b16bbc --- /dev/null +++ b/types/main.d.ts @@ -0,0 +1,4 @@ +import { ElementUIComponent } from './component' + +/** Main Component */ +export declare class ElMain extends ElementUIComponent {} diff --git a/types/menu-item-group.d.ts b/types/menu-item-group.d.ts new file mode 100644 index 0000000..cbdaa1a --- /dev/null +++ b/types/menu-item-group.d.ts @@ -0,0 +1,7 @@ +import { ElementUIComponent } from './component' + +/** Menu Item Group Component */ +export declare class ElMenuItemGroup extends ElementUIComponent { + /** Group title */ + title: string +} diff --git a/types/menu-item.d.ts b/types/menu-item.d.ts new file mode 100644 index 0000000..30d3db5 --- /dev/null +++ b/types/menu-item.d.ts @@ -0,0 +1,10 @@ +import { ElementUIComponent } from './component' + +/** Menu Item Component */ +export declare class ElMenuItem extends ElementUIComponent { + /** Unique identification */ + index: string + + /** Vue Router object */ + route: object +} diff --git a/types/menu.d.ts b/types/menu.d.ts new file mode 100644 index 0000000..0f04d24 --- /dev/null +++ b/types/menu.d.ts @@ -0,0 +1,46 @@ +import { ElementUIComponent } from './component' + +export type MenuDisplayMode = 'horizontal' | 'vertical' +export type MenuTheme = 'light' | 'dark' + +/** Menu that provides navigation for your website */ +export declare class ElMenu extends ElementUIComponent { + /** Menu display mode */ + mode: MenuDisplayMode + + /** Whether the menu is collapsed (available only in vertical mode) */ + collapse: boolean + + /** Background color of Menu (hex format) */ + backgroundColor: string + + /** Text color of Menu (hex format) */ + textColor: string + + /** Text color of currently active menu item (hex format) */ + activeTextColor: string + + /** Index of currently active menu */ + defaultActive: string + + /** Array that contains keys of currently active sub-menus */ + defaultOpeneds: string[] + + /** Whether only one sub-menu can be active */ + uniqueOpened: boolean + + /** How sub-menus are triggered, only works when mode is 'horizontal' */ + menuTrigger: string + + /** Whether vue-router mode is activated. If true, index will be used as 'path' to activate the route action */ + router: boolean + + /** Whether the menu collapse transition is active */ + collapseTransition: boolean + + /** Open the specified sub-menu */ + open (index: string): void + + /** Close the specified sub-menu */ + close (index: string): void +} diff --git a/types/message-box.d.ts b/types/message-box.d.ts new file mode 100644 index 0000000..c3acc3e --- /dev/null +++ b/types/message-box.d.ts @@ -0,0 +1,176 @@ +import Vue, { VNode } from 'vue' +import { MessageType } from './message' + +export type MessageBoxCloseAction = 'confirm' | 'cancel' | 'close' +export type MessageBoxData = MessageBoxInputData | MessageBoxCloseAction + +export interface MessageBoxInputData { + value: string, + action: MessageBoxCloseAction +} + +export interface MessageBoxInputValidator { + (value: string): boolean | string +} + +export declare class ElMessageBoxComponent extends Vue { + title: string + message: string + type: MessageType + iconClass: string + customClass: string + showInput: boolean + showClose: boolean + inputValue: string + inputPlaceholder: string + inputType: string + inputPattern: RegExp + inputValidator: MessageBoxInputValidator + inputErrorMessage: string + showConfirmButton: boolean + showCancelButton: boolean + action: MessageBoxCloseAction + dangerouslyUseHTMLString: boolean + confirmButtonText: string + cancelButtonText: string + confirmButtonLoading: boolean + cancelButtonLoading: boolean + confirmButtonClass: string + confirmButtonDisabled: boolean + cancelButtonClass: string + editorErrorMessage: string +} + +/** Options used in MessageBox */ +export interface ElMessageBoxOptions { + /** Title of the MessageBox */ + title?: string + + /** Content of the MessageBox */ + message?: string | VNode + + /** Message type, used for icon display */ + type?: MessageType + + /** Custom icon's class */ + iconClass?: string + + /** Custom class name for MessageBox */ + customClass?: string + + /** MessageBox closing callback if you don't prefer Promise */ + callback?: (action: MessageBoxCloseAction, instance: ElMessageBoxComponent) => void + + /** Callback before MessageBox closes, and it will prevent MessageBox from closing */ + beforeClose?: (action: MessageBoxCloseAction, instance: ElMessageBoxComponent, done: (() => void)) => void + + /** Whether to lock body scroll when MessageBox prompts */ + lockScroll?: boolean + + /** Whether to show a cancel button */ + showCancelButton?: boolean + + /** Whether to show a confirm button */ + showConfirmButton?: boolean + + /** Whether to show a close button */ + showClose?: boolean + + /** Text content of cancel button */ + cancelButtonText?: string + + /** Text content of confirm button */ + confirmButtonText?: string + + /** Custom class name of cancel button */ + cancelButtonClass?: string + + /** Custom class name of confirm button */ + confirmButtonClass?: string + + /** Whether to align the content in center */ + center?: boolean + + /** Whether message is treated as HTML string */ + dangerouslyUseHTMLString?: boolean + + /** Whether to use round button */ + roundButton?: boolean + + /** Whether MessageBox can be closed by clicking the mask */ + closeOnClickModal?: boolean + + /** Whether MessageBox can be closed by pressing the ESC */ + closeOnPressEscape?: boolean + + /** Whether to close MessageBox when hash changes */ + closeOnHashChange?: boolean + + /** Whether to show an input */ + showInput?: boolean + + /** Placeholder of input */ + inputPlaceholder?: string + + /** Initial value of input */ + inputValue?: string + + /** Regexp for the input */ + inputPattern?: RegExp + + /** Input Type: text, textArea, password or number */ + inputType?: string + + /** Validation function for the input. Should returns a boolean or string. If a string is returned, it will be assigned to inputErrorMessage */ + inputValidator?: MessageBoxInputValidator + + /** Error message when validation fails */ + inputErrorMessage?: string + + /** Whether to distinguish canceling and closing */ + distinguishCancelAndClose?: boolean +} + +export interface ElMessageBoxShortcutMethod { + (message: string, title: string, options?: ElMessageBoxOptions): Promise + (message: string, options?: ElMessageBoxOptions): Promise +} + +export interface ElMessageBox { + /** Show a message box */ + (message: string, title?: string, type?: string): Promise + + /** Show a message box */ + (options: ElMessageBoxOptions): Promise + + /** Show an alert message box */ + alert: ElMessageBoxShortcutMethod + + /** Show a confirm message box */ + confirm: ElMessageBoxShortcutMethod + + /** Show a prompt message box */ + prompt: ElMessageBoxShortcutMethod + + /** Set default options of message boxes */ + setDefaults (defaults: ElMessageBoxOptions): void + + /** Close current message box */ + close (): void +} + +declare module 'vue/types/vue' { + interface Vue { + /** Show a message box */ + $msgbox: ElMessageBox + + /** Show an alert message box */ + $alert: ElMessageBoxShortcutMethod + + /** Show a confirm message box */ + $confirm: ElMessageBoxShortcutMethod + + /** Show a prompt message box */ + $prompt: ElMessageBoxShortcutMethod + } +} diff --git a/types/message.d.ts b/types/message.d.ts new file mode 100644 index 0000000..6302327 --- /dev/null +++ b/types/message.d.ts @@ -0,0 +1,90 @@ +import Vue, {VNode} from 'vue' + +export type MessageType = 'success' | 'warning' | 'info' | 'error' + +/** Message Component */ +export declare class ElMessageComponent extends Vue { + /** Close the Loading instance */ + close (): void +} + +export interface CloseEventHandler { + /** + * Triggers when a message is being closed + * + * @param instance The message component that is being closed + */ + (instance: ElMessageComponent): void +} + +/** Options used in Message */ +export interface ElMessageOptions { + /** Message text */ + message: string | VNode + + /** Message type */ + type?: MessageType + + /** Custom icon's class, overrides type */ + iconClass?: string + + /** Custom class name for Message */ + customClass?: string + + /** Display duration, millisecond. If set to 0, it will not turn off automatically */ + duration?: number + + /** Whether to show a close button */ + showClose?: boolean + + /** Whether to center the text */ + center?: boolean + + /** Whether message is treated as HTML string */ + dangerouslyUseHTMLString?: boolean + + /** Callback function when closed with the message instance as the parameter */ + onClose?: CloseEventHandler + + /** Set the distance to the top of viewport. Default is 20 px. */ + offset?: number +} + +export interface ElMessage { + /** Show an info message */ + (text: string): ElMessageComponent + + /** Show message */ + (options: ElMessageOptions): ElMessageComponent + + /** Show a success message */ + success (text: string): ElMessageComponent + + /** Show a success message with options */ + success (options: ElMessageOptions): ElMessageComponent + + /** Show a warning message */ + warning (text: string): ElMessageComponent + + /** Show a warning message with options */ + warning (options: ElMessageOptions): ElMessageComponent + + /** Show an info message */ + info (text: string): ElMessageComponent + + /** Show an info message with options */ + info (options: ElMessageOptions): ElMessageComponent + + /** Show an error message */ + error (text: string): ElMessageComponent + + /** Show an error message with options */ + error (options: ElMessageOptions): ElMessageComponent +} + +declare module 'vue/types/vue' { + interface Vue { + /** 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. */ + $message: ElMessage + } +} diff --git a/types/notification.d.ts b/types/notification.d.ts new file mode 100644 index 0000000..a2cf871 --- /dev/null +++ b/types/notification.d.ts @@ -0,0 +1,84 @@ +import Vue, { VNode } from 'vue' +import { MessageType } from './message' + +export type NotificationPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' + +/** Notification Component */ +export declare class ElNotificationComponent extends Vue { + /** Close the Notification instance */ + close (): void +} + +export interface ElNotificationOptions { + /** Title */ + title: string + + /** Description text */ + message: string | VNode + + /** Notification type */ + type?: MessageType + + /** Custom icon's class. It will be overridden by type */ + iconClass?: string + + /** Custom class name for Notification */ + customClass?: string + + /** Duration before close. It will not automatically close if set 0 */ + duration?: number + + /** Whether to show a close button */ + showClose?: boolean + + /** Whether message is treated as HTML string */ + dangerouslyUseHTMLString?: boolean + + /** Callback function when closed */ + onClose?: () => void + + /** Callback function when notification clicked */ + onClick?: () => void + + /** Offset from the top edge of the screen. Every Notification instance of the same moment should have the same offset */ + offset?: number + + /** custom position */ + position?: NotificationPosition +} + +export interface ElNotification { + /** Show a notification */ + (options: ElNotificationOptions): ElNotificationComponent + + /** Show a success notification */ + success (message: string | VNode): ElNotificationComponent + + /** Show a success notification */ + success (options: ElNotificationOptions): ElNotificationComponent + + /** Show a warning notification */ + warning (message: string | VNode): ElNotificationComponent + + /** Show a warning notification */ + warning (options: ElNotificationOptions): ElNotificationComponent + + /** Show an info notification */ + info (message: string | VNode): ElNotificationComponent + + /** Show an info notification */ + info (options: ElNotificationOptions): ElNotificationComponent + + /** Show an error notification */ + error (message: string | VNode): ElNotificationComponent + + /** Show an error notification */ + error (options: ElNotificationOptions): ElNotificationComponent +} + +declare module 'vue/types/vue' { + interface Vue { + /** Displays a global notification message at the upper right corner of the page */ + $notify: ElNotification + } +} diff --git a/types/option-group.d.ts b/types/option-group.d.ts new file mode 100644 index 0000000..1530965 --- /dev/null +++ b/types/option-group.d.ts @@ -0,0 +1,10 @@ +import { ElementUIComponent } from './component' + +/** Dropdown Select Option Group Component */ +export declare class ElOptionGroup extends ElementUIComponent { + /** Name of the group */ + label: string + + /** Whether to disable all options in this group */ + disabled: boolean +} diff --git a/types/option.d.ts b/types/option.d.ts new file mode 100644 index 0000000..d949a54 --- /dev/null +++ b/types/option.d.ts @@ -0,0 +1,13 @@ +import { ElementUIComponent } from './component' + +/** Dropdown Select Option Component */ +export declare class ElOption extends ElementUIComponent { + /** Value of option */ + value: any + + /** Label of option, same as value if omitted */ + label: string + + /** Whether option is disabled */ + disabled: boolean +} diff --git a/types/page-header.d.ts b/types/page-header.d.ts new file mode 100644 index 0000000..2831983 --- /dev/null +++ b/types/page-header.d.ts @@ -0,0 +1,10 @@ +import { ElementUIComponent } from './component' + +/** PageHeader Component */ +export declare class ElPageHeader extends ElementUIComponent { + /** title */ + title: String + + /** content */ + content: String +} diff --git a/types/pagination.d.ts b/types/pagination.d.ts new file mode 100644 index 0000000..61f0baa --- /dev/null +++ b/types/pagination.d.ts @@ -0,0 +1,43 @@ +import { ElementUIComponent } from './component' + +/** Pagination Component */ +export declare class ElPagination extends ElementUIComponent { + /** Whether to use small pagination */ + small: boolean + + /** Item count of each page */ + pageSize: number + + /** Total item count */ + total: number + + /** Total page count. Set either total or page-count and pages will be displayed; if you need page-sizes, total is required */ + pageCount: number + + /** Number of pagers */ + pagerCount: number + + /** Current page number */ + currentPage: number + + /** + * Layout of Pagination. Elements separated with a comma. + * Accepted values: `sizes`, `prev`, `pager`, `next`, `jumper`, `->`, `total`, `slot` + */ + layout: string + + /** Options of item count per page */ + pageSizes: number[] + + /** Custom class name for the page size Select's dropdown */ + popperClass: string + + /** Text for the prev button */ + prevText: string + + /** Text for the prev button */ + nextText: string + + /** Whether to hide when thers's only one page */ + hideOnSinglePage: boolean +} diff --git a/types/popconfirm.d.ts b/types/popconfirm.d.ts new file mode 100644 index 0000000..b3bee53 --- /dev/null +++ b/types/popconfirm.d.ts @@ -0,0 +1,29 @@ +import { ElementUIComponent } from './component' +import { ElPopover } from './popover' + +/** Popconfirm Component */ +export declare class ElPopconfirm extends ElPopover { + /** Popconfirm title */ + title: string + + /** Popconfirm ok text */ + confirmButtonText: string + + /** Popconfirm cancel text */ + cancelButtonText: string + + /** Popconfirm ok type */ + confirmButtonType: string + + /** Popconfirm cancal type */ + cancelButtonType: string + + /** Popconfirm icon */ + icon: string + + /** Popconfirm icon color */ + iconColor: string + + /** Popconfirm hide icon */ + hideIcon: boolean +} diff --git a/types/popover.d.ts b/types/popover.d.ts new file mode 100644 index 0000000..5ad4812 --- /dev/null +++ b/types/popover.d.ts @@ -0,0 +1,71 @@ +import { VNode, VNodeDirective } from 'vue' +import { ElementUIComponent } from './component' + +export type PopoverTrigger = 'click' | 'focus' | 'hover' | 'manual' +export type PopoverPlacement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end' + +export interface PopoverSlots { + /** Content of popover */ + default: VNode[], + + /** HTML element that triggers popover */ + reference: VNode[] + + [key: string]: VNode[] +} + +/** Popover directive definition */ +export interface ElPopoverDirective extends VNodeDirective { + name: 'popover', + arg: string +} + +/** Popover Component */ +export declare class ElPopover extends ElementUIComponent { + /** How the popover is triggered */ + trigger: PopoverTrigger + + /** Popover title */ + title: string + + /** Popover content, can be replaced with a default slot */ + content: string + + /** Popover width */ + width: string | number + + /** Popover placement */ + placement: PopoverPlacement + + /** Whether Popover is disabled */ + disabled: boolean + + /** Whether popover is visible */ + value: boolean + + /** Popover offset */ + offset: number + + /** Popover transition animation */ + transition: string + + /** Whether a tooltip arrow is displayed or not. For more info, please refer to Vue-popper */ + visibleArrow: boolean + + /** Parameters for popper.js */ + popperOptions: object + + /** Custom class name for popover */ + popperClass: string + + /** Delay before appearing when trigger is hover, in milliseconds */ + openDelay: number + + /** Delay before disappearing when trigger is hover, in milliseconds */ + closeDelay: number + + /** Popover tabindex */ + tabindex: number + + $slots: PopoverSlots +} diff --git a/types/progress.d.ts b/types/progress.d.ts new file mode 100644 index 0000000..780a8d4 --- /dev/null +++ b/types/progress.d.ts @@ -0,0 +1,37 @@ +import { ElementUIComponent } from './component' + +export type ProgressType = 'line' | 'circle' +export type ProgressStatus = 'success' | 'exception' + +/** Progress Component */ +export declare class ElProgress extends ElementUIComponent { + /** Percentage, required */ + percentage: number + + /** The type of progress bar */ + type: ProgressType + + /** The width of progress bar */ + strokeWidth: number + + /** Circle progress bar stroke line cap */ + strokeLinecap: string + + /** Whether to place the percentage inside progress bar, only works when type is 'line' */ + textInside: boolean + + /** The current status of progress bar */ + status: ProgressStatus + + /** Background color of progress bar. Overrides `status` prop */ + color: string | Function | Array + + /** The canvas width of circle progress bar */ + width: number + + /** Whether to show percentage */ + showText: boolean + + /** Template function of the content */ + format(percentage: number): string +} diff --git a/types/radio-button.d.ts b/types/radio-button.d.ts new file mode 100644 index 0000000..0b7df8a --- /dev/null +++ b/types/radio-button.d.ts @@ -0,0 +1,16 @@ +import { ElementUIComponent } from './component' + +/** Radio Button Component */ +export declare class ElRadioButton extends ElementUIComponent { + /** The form input value */ + value: string + + /** The value of radio */ + label: string | number + + /** Whether radio is disabled */ + disabled: boolean + + /** Native 'name' attribute */ + name: string +} diff --git a/types/radio-group.d.ts b/types/radio-group.d.ts new file mode 100644 index 0000000..f61144b --- /dev/null +++ b/types/radio-group.d.ts @@ -0,0 +1,18 @@ +import { ElementUIComponent } from './component' + +export type RadioGroupSize = 'large' | 'small' + +/** Radio Group Component */ +export declare class ElRadioGroup extends ElementUIComponent { + /** The size of radio buttons */ + size: RadioGroupSize + + /** Border and background color when button is active */ + fill: string + + /** Whether the nesting radios are disabled */ + disabled: boolean + + /** Font color when button is active */ + textColor: string +} diff --git a/types/radio.d.ts b/types/radio.d.ts new file mode 100644 index 0000000..22826ea --- /dev/null +++ b/types/radio.d.ts @@ -0,0 +1,19 @@ +import { ElementUIComponent } from './component' + +/** Radio Component */ +export declare class ElRadio extends ElementUIComponent { + /** The form input value */ + value: string + + /** The value of radio */ + label: string | number | boolean + + /** Whether radio is disabled */ + disabled: boolean + + /** Whether to add a border around Radio */ + border: boolean + + /** Native 'name' attribute */ + name: string +} diff --git a/types/rate.d.ts b/types/rate.d.ts new file mode 100644 index 0000000..ca655f5 --- /dev/null +++ b/types/rate.d.ts @@ -0,0 +1,64 @@ +import { ElementUIComponent } from './component' + +interface Option { + value: string, + excluded?: boolean +} + +interface Options { + [threshold: number]: string | Option +} + +export type RateColors = Options +export type RateIconClasses = Options + +/** Rate Component */ +export declare class ElRate extends ElementUIComponent { + /** Max rating score */ + max: number + + /** Whether Rate is read-only */ + disabled: boolean + + /** Whether picking half start is allowed */ + allowHalf: boolean + + /** Threshold value between low and medium level. The value itself will be included in low level */ + lowThreshold: number + + /** Threshold value between medium and high level. The value itself will be included in high level */ + highThreshold: number + + /** Colors for icons. If array, it should have 3 elements, each of which corresponds with a score level, else if object, the key should be threshold value between two levels, and the value should be corresponding color */ + colors: string[] | RateColors + + /** Color of unselected icons */ + voidColor: string + + /** Color of unselected read-only icons */ + disabledVoidColor: string + + /** Class names of icons. If array, it should have 3 elements, each of which corresponds with a score level, else if object, the key should be threshold value between two levels, and the value should be corresponding class name */ + iconClasses: string[] | RateIconClasses + + /** Class name of unselected icons */ + voidIconClass: string + + /** Class name of unselected read-only icons */ + disabledVoidIconClass: string + + /** Whether to display texts */ + showText: boolean + + /** Whether to display current score. show-score and show-text cannot be true at the same time */ + showScore: boolean + + /** Color of texts */ + textColor: string + + /** Text array */ + texts: string[] + + /** Text template when the component is read-only */ + scoreTemplate: string +} diff --git a/types/row.d.ts b/types/row.d.ts new file mode 100644 index 0000000..4769de7 --- /dev/null +++ b/types/row.d.ts @@ -0,0 +1,25 @@ +import { ElementUIComponent } from './component' + +/** Horizontal alignment of flex layout */ +export type HorizontalAlignment = 'start' | 'end' | 'center' | 'space-around' | 'space-between' + +/** vertical alignment of flex layout */ +export type VertialAlignment = 'top' | 'middle' | 'bottom' + +/** Row Layout Component */ +export declare class ElRow extends ElementUIComponent { + /** Grid spacing */ + gutter: number + + /** Layout mode. You can use flex. Works in modern browsers */ + type: string + + /** Horizontal alignment of flex layout */ + justify: HorizontalAlignment + + /** Vertical alignment of flex layout */ + align: VertialAlignment + + /** Custom element tag */ + tag: string +} diff --git a/types/select.d.ts b/types/select.d.ts new file mode 100644 index 0000000..110835e --- /dev/null +++ b/types/select.d.ts @@ -0,0 +1,90 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' + +export interface QueryChangeHandler { + /** + * @param queryString Current value of the text input + */ + (queryString: string): void +} + +/** Dropdown Select Component */ +export declare class ElSelect extends ElementUIComponent { + /** The form input value */ + value: any + + /** Whether multiple-select is activated */ + multiple: boolean + + /** Whether Select is disabled */ + disabled: boolean + + /** Unique identity key name for value, required when value is an object */ + valueKey: string + + /** Size of Input */ + size: ElementUIComponentSize + + /** Whether single select can be cleared */ + clearable: boolean + + /** Maximum number of options user can select when multiple is true. No limit when set to 0 */ + multipleLimit: number + + /** @Deprecated in next major version */ + autoComplete: string + + /** Same as autocomplete in native input */ + autocomplete: string + + /** The name attribute of select input */ + name: string + + /** Placeholder */ + placeholder: string + + /** Whether Select is filterable */ + filterable: boolean + + /** Whether creating new items is allowed. To use this, filterable must be true */ + allowCreate: boolean + + /** Custom filter method */ + filterMethod: QueryChangeHandler + + /** Whether options are loaded from server */ + remote: boolean + + /** Custom remote search method */ + remoteMethod: QueryChangeHandler + + /** Whether Select is loading data from server */ + loading: boolean + + /** Displayed text while loading data from server */ + loadingText: string + + /** Displayed text when no data matches the filtering query */ + noMatchText: string + + /** Displayed text when there is no options */ + noDataText: string + + /** Custom class name for Select's dropdown */ + popperClass: string + + /** Select first matching option on enter key. Use with filterable or remote */ + defaultFirstOption: boolean + + /** Whether to append the popper menu to body */ + popperAppendToBody: boolean + + /** + * Focus the Input component + */ + focus (): void + + /** + * Blur the Input component, and hide the dropdown + */ + blur (): void +} diff --git a/types/slider.d.ts b/types/slider.d.ts new file mode 100644 index 0000000..d7790b9 --- /dev/null +++ b/types/slider.d.ts @@ -0,0 +1,68 @@ +import { VNode } from 'vue'; +import { ElementUIComponent } from './component' + +export interface SliderTooltipFormat { + /** + * Format the displayed value of Slider + * + * @param value Value of the Slider + * @returns formatted value + */ + (value: number): string +} + +/** Slider Component */ +export declare class ElSlider extends ElementUIComponent { + /** Current value of the slider */ + value: number | number[] + + /** Minimum value */ + min: number + + /** Maximum value */ + max: number + + /** Whether Slider is disabled */ + disabled: boolean + + /** Step size */ + step: number + + /** Whether to display an input box, works when range is false */ + showInput: boolean + + /** Format of displayed tooltip value */ + formatTooltip: SliderTooltipFormat + + /** Whether to display control buttons when show-input is true */ + showInputControls: boolean + + /** Size of the input box */ + inputSize: string + + /** Whether to display breakpoints */ + showStops: boolean + + /** Whether to display tooltip value */ + showTooltip: boolean + + /** Whether to select a range */ + range: boolean + + /** Vertical mode */ + vertical: boolean + + /** Slider height, required in vertical mode */ + height: boolean + + /** Debounce delay when typing, in milliseconds, works when show-input is true */ + debounce: number + + /** Custom class name for the tooltip */ + tooltipClass: string + + /** Custom marks */ + marks: { + [key: number]: string | { style: object; label: string | VNode } + } +} diff --git a/types/step.d.ts b/types/step.d.ts new file mode 100644 index 0000000..68ed2b3 --- /dev/null +++ b/types/step.d.ts @@ -0,0 +1,34 @@ +import { VNode } from 'vue' +import { ElementUIComponent } from './component' + +export type StepStatus = 'wait' | 'process' | 'finish' | 'error' | 'success' + +export interface StepRenderSlots { + /** Custom icon */ + icon: VNode[], + + /** Step title */ + title: VNode[], + + /** Step description */ + description: VNode[], + + [key: string]: VNode[] +} + +/** Step Component */ +export declare class ElStep extends ElementUIComponent { + /** Step title */ + title: string + + /** Step description */ + description: string + + /** Step icon */ + icon: string + + /** Current status. It will be automatically set by Steps if not configured. */ + status: StepStatus + + readonly $slots: StepRenderSlots +} diff --git a/types/steps.d.ts b/types/steps.d.ts new file mode 100644 index 0000000..ed40ab6 --- /dev/null +++ b/types/steps.d.ts @@ -0,0 +1,28 @@ +import { ElementUIComponent } from './component' +import { StepStatus } from './step' + +export type StepsDirection = 'vertical' | 'horizontal' + +/** Guide the user to complete tasks in accordance with the process. Its steps can be set according to the actual application scenario and the number of the steps can't be less than 2. */ +export declare class ElSteps extends ElementUIComponent { + /** The spacing of each step, will be responsive if omitted. Support percentage. */ + space: number | string + + /** Display direction */ + direction: StepsDirection + + /** Current activation step */ + active: number + + /** Status of current step */ + processStatus: StepStatus + + /** Status of end step */ + finishStatus: StepStatus + + /** Whether step description is centered */ + alignCenter: boolean + + /** Whether to apply simple theme */ + simple: boolean +} diff --git a/types/submenu.d.ts b/types/submenu.d.ts new file mode 100644 index 0000000..5594450 --- /dev/null +++ b/types/submenu.d.ts @@ -0,0 +1,22 @@ +import { ElementUIComponent } from './component' + +/** Submenu Component */ +export declare class ElSubmenu extends ElementUIComponent { + /** Unique identification */ + index: string | null + + /** Delay time before showing a sub-menu */ + showTimeout: number + + /** Delay time before hiding a sub-menu */ + hideTimeout: number + + /** Custom class name for the popup menu */ + popperClass: string + + /** Whether the sub-menu is disabled */ + disabled: boolean + + /** Whether to append the popper menu to body */ + popperAppendToBody: boolean +} diff --git a/types/switch.d.ts b/types/switch.d.ts new file mode 100644 index 0000000..4489c01 --- /dev/null +++ b/types/switch.d.ts @@ -0,0 +1,43 @@ +import { ElementUIComponent } from './component' + +/** Switch Component */ +export declare class ElSwitch extends ElementUIComponent { + /** Whether Switch is on */ + value: boolean + + /** Whether Switch is disabled */ + disabled: boolean + + /** Width of Switch */ + width: number + + /** Class name of the icon displayed when in on state, overrides on-text */ + activeIconClass: string + + /** Class name of the icon displayed when in off state, overrides off-text */ + inactiveIconClass: string + + /** Text displayed when in on state */ + activeText: string + + /** Text displayed when in off state */ + inactiveText: string + + /** Background color when in on state */ + activeColor: string + + /** Background color when in off state */ + inactiveColor: string + + /** Switch value when in on state */ + activeValue: string | boolean | number + + /** Switch value when in off state */ + inactiveValue: string | boolean | number + + /** Input name of Switch */ + name: string + + /** Whether to trigger form validation */ + validateEvent: boolean +} diff --git a/types/tab-pane.d.ts b/types/tab-pane.d.ts new file mode 100644 index 0000000..b4f6999 --- /dev/null +++ b/types/tab-pane.d.ts @@ -0,0 +1,19 @@ +import { ElementUIComponent } from './component' + +/** Tab Pane Component */ +export declare class ElTabPane extends ElementUIComponent { + /** Title of the tab */ + label: string + + /** Whether Tab is disabled */ + disabled: boolean + + /** Identifier corresponding to the activeName of Tabs, representing the alias of the tab-pane */ + name: string + + /** Whether Tab is closable */ + closable: boolean + + /** Whether Tab is lazily rendered */ + lazy: boolean +} diff --git a/types/table-column.d.ts b/types/table-column.d.ts new file mode 100644 index 0000000..34e1d30 --- /dev/null +++ b/types/table-column.d.ts @@ -0,0 +1,117 @@ +import { CreateElement, VNode } from 'vue' +import { ElementUIComponent, ElementUIHorizontalAlignment } from './component' +import { PopoverPlacement } from './popover' + +export type TableColumnType = 'default' | 'selection' | 'index' | 'expand' +export type TableColumnFixedType = 'left' | 'right' +export type SortOrders = 'ascending' | 'descending' | null + +export type TableColumn = { + /** Label of the column */ + label: string, + + /** Property name of the source data */ + property: string, + + /** Type of the column */ + type: string, + + /** Whether column is fixed at left/right */ + fixed: boolean | string +} + +/** Data used in renderHeader function */ +export interface RenderHeaderData { + /** The column that is current rendering */ + column: any, + + /** The index of the rendering column */ + $index: number +} + +/** Filter Object */ +export interface TableColumnFilter { + /** The text to show in the filter's panel */ + text: string, + + /** The value of the filter */ + value: any +} + +/** TableColumn Component */ +export declare class ElTableColumn extends ElementUIComponent { + /** Type of the column. If set to `selection`, the column will display checkbox. If set to `index`, the column will display index of the row (staring from 1). If set to `expand`, the column will display expand icon. */ + type: TableColumnType + + /** Column label */ + label: string + + /** Column's key. If you need to use the filter-change event, you need this attribute to identify which column is being filtered */ + columnKey: string + + /** Field name. You can also use its alias: property */ + prop: string + + /** Column width */ + width: string + + /** Column minimum width. Columns with `width` has a fixed width, while columns with `min-width` has a width that is distributed in proportion */ + minWidth: string + + /** Whether column is fixed at left/right. Will be fixed at left if `true` */ + fixed: boolean | TableColumnFixedType + + /** Render function for table header of this column */ + renderHeader: (h: CreateElement, data: RenderHeaderData) => VNode | string + + /** Whether column can be sorted */ + sortable: boolean | 'custom' + + /** Sorting method. Works when `sortable` is `true` */ + sortMethod: (a: any, b: any) => number + + /** The order of the sorting strategies used when sorting the data. Works when `sortable` is `true`. */ + sortOrders: SortOrders[] + + /** Whether column width can be resized. Works when border of `el-table` is `true` */ + resizable: boolean + + /** Function that formats content */ + formatter: (row: object, column: TableColumn) => any + + /** Whether to hide extra content and show them in a tooltip when hovering on the cell */ + showOverflowTooltip: boolean + + /** Alignment */ + align: ElementUIHorizontalAlignment + + /** Alignment of the table header. If omitted, the value of the `align` attribute will be applied */ + headerAlign: ElementUIHorizontalAlignment + + /** Class name of cells in the column */ + className: string + + /** Class name of the label of this column */ + labelClassName: string + + /** Function that determines if a certain row can be selected, works when `type` is `'selection'` */ + selectable: (row: object, index: number) => boolean + + /** Whether to reserve selection after data refreshing, works when `type` is `'selection'` */ + reserveSelection: boolean + + /** An array of data filtering options */ + filters: TableColumnFilter[] + + /** Placement for the filter dropdown */ + filterPlacement: PopoverPlacement + + /** Whether data filtering supports multiple options */ + filterMultiple: Boolean + + /** Data filtering method. If `filter-multiple` is on, this method will be called multiple times for each row, and a row will display if one of the calls returns `true` */ + filterMethod: (value: any, row: object) => boolean + + /** Filter value for selected data, might be useful when table header is rendered with `render-header` */ + filteredValue: TableColumnFilter[] +} diff --git a/types/table.d.ts b/types/table.d.ts new file mode 100644 index 0000000..da5bb38 --- /dev/null +++ b/types/table.d.ts @@ -0,0 +1,174 @@ +import { ElementUIComponent } from './component' +import { TooltipEffect } from './tooltip' + +export type SortOrder = 'ascending' | 'descending' + +/** Options to set the default sort column and order */ +export interface DefaultSortOptions { + /** Default sort column */ + prop: string, + + /** Default sort order */ + order: SortOrder +} + +export interface SummaryMethodParams { + columns: object[], + data: object +} + +export interface rowCallbackParams { + row: object, + rowIndex: number +} + +export interface cellCallbackParams { + row: object, + rowIndex: number, + column: object, + columnIndex: number +} + +export interface treeNode { + rowKey: string | number, + isLeaf: boolean, + level: number, + expanded: boolean, + loaded: boolean +} + +/** Table Component */ +export declare class ElTable extends ElementUIComponent { + /** Table data */ + data: object[] + + /** Table's height. By default it has an auto height. If its value is a number, the height is measured in pixels; if its value is a string, the height is affected by external styles */ + height: string | number + + /** Table's max-height. The height of the table starts from auto until it reaches the maxHeight limit. The maxHeight is measured in pixels, same as height */ + maxHeight: string | number + + /** Whether table is striped */ + stripe: boolean + + /** Whether table has vertical border */ + border: boolean + + /** Whether width of column automatically fits its container */ + fit: boolean + + /** Whether table header is visible */ + showHeader: boolean + + /** Whether current row is highlighted */ + highlightCurrentRow: boolean + + /** Key of current row, a set only prop */ + currentRowKey: string | number + + /** Whether to lazy load tree structure data, used with load attribute */ + lazy: boolean + + /** Horizontal indentation of nodes in adjacent levels in pixels */ + indent: number + + /** Function that returns custom class names for a row, or a string assigning class names for every row */ + rowClassName: string | ((param: rowCallbackParams) => string) + + /** Function that returns custom style for a row, or an object assigning custom style for every row */ + rowStyle: object | ((param: rowCallbackParams) => object) + + /** Function that returns custom class names for a cell, or a string assigning class names for every cell */ + cellClassName: string | ((param: cellCallbackParams) => string) + + /** Function that returns custom style for a cell, or an object assigning custom style for every cell */ + cellStyle: object | ((param: cellCallbackParams) => object) + + /** Function that returns custom class names for a row in table header, or a string assigning class names for every row in table header */ + headerRowClassName: string | ((param: rowCallbackParams) => string) + + /** Function that returns custom style for a row in table header, or an object assigning custom style for every row in table header */ + headerRowStyle: object | ((param: rowCallbackParams) => object) + + /** Function that returns custom class names for a cell in table header, or a string assigning class names for every cell in table header */ + headerCellClassName: string | ((param: cellCallbackParams) => string) + + /** Function that returns custom style for a cell in table header, or an object assigning custom style for every cell in table header */ + headerCellStyle: object | ((param: cellCallbackParams) => object) + + /** Key of row data, used for optimizing rendering. Required if reserve-selection is on */ + rowKey: (row: object) => any + + /** Displayed text when data is empty. You can customize this area with `slot="empty"` */ + emptyText: String + + /** Whether expand all rows by default. Only works when the table has a column `type="expand"` */ + defaultExpandAll: Boolean + + /** Set expanded rows by this prop. Prop's value is the keys of expand rows, you should set row-key before using this prop */ + expandRowKeys: any[] + + /** Set the default sort column and order */ + defaultSort: DefaultSortOptions + + /** Tooltip effect property */ + tooltipEffect: TooltipEffect + + /** Whether to display a summary row */ + showSummary: boolean + + /** Displayed text for the first column of summary row */ + sumText: string + + /** Custom summary method */ + summaryMethod: (param: SummaryMethodParams) => any[] + + /** Controls the behavior of master checkbox in multi-select tables when only some rows are selected */ + selectOnIndeterminate: boolean + + /** Clear selection. Might be useful when `reserve-selection` is on */ + clearSelection (): void + + /** + * Toggle or set if a certain row is selected + * + * @param row The row that is going to set its selected state + * @param selected Whether the row is selected. The selected state will be toggled if not set + */ + toggleRowSelection (row: object, selected?: boolean): void + + /** + * Toggle or set all rows + */ + toggleAllSelection (): void + + /** + * Set a certain row as selected + * + * @param row The row that is going to set as selected + */ + setCurrentRow (row?: object): void + + /** + * Toggle or set if a certain row is expanded + * + * @param row The row that is going to set its expanded state + * @param expanded Whether the row is expanded. The expanded state will be toggled if not set + */ + toggleRowExpansion (row: object, expanded?: boolean): void + + /** Clear sort status, reset the table to unsorted */ + clearSort (): void + + /** Clear filter, reset the table to unfiltered */ + clearFilter (): void + + /** Relayout the table, maybe needed when change the table or it's ancestors visibility */ + doLayout (): void + + /** Sort Table manually */ + sort (prop: string, order: string): void + + /** method for lazy load subtree data */ + load (row: object, treeNode: treeNode, resolve: Function): void +} diff --git a/types/tabs.d.ts b/types/tabs.d.ts new file mode 100644 index 0000000..fee7c1a --- /dev/null +++ b/types/tabs.d.ts @@ -0,0 +1,31 @@ +import { ElementUIComponent } from './component' + +export type TabType = 'card' | 'border-card' +export type TabPosition = 'top' | 'right' | 'bottom' | 'left' + +/** Divide data collections which are related yet belong to different types */ +export declare class ElTabs extends ElementUIComponent { + /** Type of Tab */ + type: TabType + + /** Whether Tab is closable */ + closable: boolean + + /** Whether Tab is addable */ + addable: boolean + + /** Whether Tab is addable and closable */ + editable: boolean + + /** Name of the selected tab */ + value: string + + /** Position of tabs */ + tabPosition: TabPosition + + /** Whether width of tab automatically fits its container */ + stretch: Boolean + + /** Hook function before switching tab. If false or a Promise is returned and then is rejected, switching will be prevented */ + beforeLeave: (activeName: string, oldActiveName: string) => boolean | Promise +} diff --git a/types/tag.d.ts b/types/tag.d.ts new file mode 100644 index 0000000..cc59f79 --- /dev/null +++ b/types/tag.d.ts @@ -0,0 +1,28 @@ +import { ElementUIComponent, ElementUIComponentSize } from './component' + +export type TagType = 'primary' | 'gray' | 'success' | 'warning' | 'danger' +export type TagTheme = 'dark' | 'light' | 'plain' + +/** Tag Component */ +export declare class ElTag extends ElementUIComponent { + /** Tag type */ + type: TagType + + /** Whether Tab can be removed */ + closable: boolean + + /** Whether the removal animation is disabled */ + disableTransitions: boolean + + /** Whether Tag has a highlighted border */ + hit: boolean + + /** Background color of the tag */ + color: string + + /** Tag size */ + size: ElementUIComponentSize + + /** Tag theme */ + effect: TagTheme +} diff --git a/types/time-picker.d.ts b/types/time-picker.d.ts new file mode 100644 index 0000000..40114f4 --- /dev/null +++ b/types/time-picker.d.ts @@ -0,0 +1,63 @@ +import { ElementUIComponent, ElementUIComponentSize, ElementUIHorizontalAlignment } from './component' + +export interface TimePickerOptions { + /** + * Available time range. + * e.g. `'18:30:00 - 20:30:00'` + * or `['09:30:00 - 12:00:00', '14:30:00 - 18:30:00']` + */ + selectableRange?: string | string[], + + /** Format of the picker */ + format?: string +} + +/** TimePicker Component */ +export declare class ElTimePicker extends ElementUIComponent { + /** Whether DatePicker is read only */ + readonly: boolean + + /** Whether DatePicker is disabled */ + disabled: boolean + + /** Whether the input is editable */ + editable: boolean + + /** Whether to show clear button */ + clearable: boolean + + /** Size of Input */ + size: ElementUIComponentSize + + /** Placeholder */ + placeholder: string + + /** Placeholder for the start time in range mode */ + startPlaceholder: string + + /** Placeholder for the end time in range mode */ + endPlaceholder: string + + /** Whether to pick a time range */ + isRange: boolean + + /** Value of the picker */ + value: string | Date + + /** Alignment */ + align: ElementUIHorizontalAlignment + + /** Custom class name for TimePicker's dropdown */ + popperClass: string + + /** Additional options, check the table below */ + pickerOptions: TimePickerOptions + + /** Range separator */ + rangeSeparator: string + + /** + * Focus the Input component + */ + focus (): void +} diff --git a/types/time-select.d.ts b/types/time-select.d.ts new file mode 100644 index 0000000..a784f8e --- /dev/null +++ b/types/time-select.d.ts @@ -0,0 +1,56 @@ +import { ElementUIComponent, ElementUIComponentSize, ElementUIHorizontalAlignment } from './component' + +export interface TimeSelectOptions { + /** Start time */ + start?: string, + + /** End time */ + end?: string, + + /** Time step */ + step?: string, + + /** Minimum time, any time before this time will be disabled */ + minTime?: string, + + /** Maximum time, any time after this time will be disabled */ + maxTime?: string +} + +/** TimeSelect Component */ +export declare class ElTimeSelect extends ElementUIComponent { + /** Whether DatePicker is read only */ + readonly: boolean + + /** Whether DatePicker is disabled */ + disabled: boolean + + /** Whether the input is editable */ + editable: boolean + + /** Whether to show clear button */ + clearable: boolean + + /** Size of Input */ + size: ElementUIComponentSize + + /** Placeholder */ + placeholder: string + + /** Value of the picker */ + value: string | Date + + /** Alignment */ + align: ElementUIHorizontalAlignment + + /** Custom class name for TimePicker's dropdown */ + popperClass: string + + /** Additional options, check the table below */ + pickerOptions: TimeSelectOptions + + /** + * Focus the Input component + */ + focus (): void +} diff --git a/types/timeline-item.d.ts b/types/timeline-item.d.ts new file mode 100644 index 0000000..647d555 --- /dev/null +++ b/types/timeline-item.d.ts @@ -0,0 +1,20 @@ +import { ElementUIComponent } from './component' + +export type TimelineItemPlacement = 'top' | 'bottom' +export type TimelineItemType = 'primary' | 'success' | 'warning' | 'danger' | 'info' +export type TimelineItemSize = 'normal' | 'large' + +/** TimelineItem Component */ +export declare class ElTimelineItem extends ElementUIComponent { + timestamp: string + + hideTimestamp: boolean + + placement: TimelineItemPlacement + + type: TimelineItemType + + size: TimelineItemSize + + icon: string +} diff --git a/types/timeline.d.ts b/types/timeline.d.ts new file mode 100644 index 0000000..20e033d --- /dev/null +++ b/types/timeline.d.ts @@ -0,0 +1,6 @@ +import { ElementUIComponent } from './component' + +/** Timeline Component */ +export declare class ElTimeline extends ElementUIComponent { + reverse: boolean +} diff --git a/types/tooltip.d.ts b/types/tooltip.d.ts new file mode 100644 index 0000000..b0fe4b6 --- /dev/null +++ b/types/tooltip.d.ts @@ -0,0 +1,52 @@ +import { ElementUIComponent } from './component' +import { PopoverPlacement } from './popover' + +export type TooltipEffect = 'dark' | 'light' + +/** Tooltip Component */ +export declare class ElTooltip extends ElementUIComponent { + /** Tooltip theme */ + effect: TooltipEffect + + /** Display content, can be overridden by slot#content */ + content: String + + /** Position of Tooltip */ + placement: PopoverPlacement + + /** Visibility of Tooltip */ + value: boolean + + /** Whether Tooltip is disabled */ + disabled: boolean + + /** Offset of the Tooltip */ + offset: number + + /** Animation name */ + transition: string + + /** Whether an arrow is displayed. For more information, check Vue-popper page */ + visibleArrow: boolean + + /** Popper.js parameters */ + popperOptions: object + + /** Delay of appearance, in millisecond */ + openDelay: number + + /** Whether to control Tooltip manually. mouseenter and mouseleave won't have effects if set to true */ + manual: boolean + + /** Custom class name for Tooltip's popper */ + popperClass: string + + /** Whether the mouse can enter the tooltip */ + enterable: string + + /** Timeout in milliseconds to hide tooltip */ + hideAfter: string + + /** Tooltip tabindex */ + tabindex: number +} diff --git a/types/transfer.d.ts b/types/transfer.d.ts new file mode 100644 index 0000000..9f35a7b --- /dev/null +++ b/types/transfer.d.ts @@ -0,0 +1,73 @@ +import { CreateElement, VNode } from 'vue' +import { ElementUIComponent } from './component' + +export type TransferPanelPosition = 'left' | 'right' + +export interface TransferData { + key: any, + label: string, + disabled: boolean +} + +export interface TransferFormat { + noChecked: string, + hasChecked: string, +} + +export interface TransferProps { + key: string, + label: string, + disabled: string +} + +export interface TransferRenderContent { + /** + * Render function for a specific option + * + * @param h The render function + * @param option The option data object + */ + (h: CreateElement, option: TransferData): VNode +} + +/** Transfer Component */ +export declare class ElTransfer extends ElementUIComponent { + /** Data source */ + data: TransferData[] + + /** Whether Transfer is filterable */ + filterable: boolean + + /** Placeholder for the filter input */ + filterPlaceholder: string + + /** Custom filter method */ + filterMethod: (query: string, item: TransferData) => boolean + + /** Order strategy for elements in the target list */ + targetOrder: string + + /** Custom list titles */ + titles: string[] + + /** Custom button texts */ + buttonTexts: string[] + + /** Custom render function for data items */ + renderContent: TransferRenderContent + + /** Texts for checking status in list header */ + format: TransferFormat + + /** Prop aliases for data source */ + props: TransferProps + + /** Key array of initially checked data items of the left list */ + leftDefaultChecked: any[] + + /** Key array of initially checked data items of the right list */ + rightDefaultChecked: any[] + + /** Clear the query text in specified panel */ + clearQuery (which: TransferPanelPosition): void +} diff --git a/types/tree.d.ts b/types/tree.d.ts new file mode 100644 index 0000000..64dd36a --- /dev/null +++ b/types/tree.d.ts @@ -0,0 +1,266 @@ +import { CreateElement, VNode } from 'vue'; +import { ElementUIComponent } from './component'; + +export interface TreeData { + id?: any; + label?: string; + disabled?: boolean; + isLeaf?: boolean; + children?: TreeData[]; +} + +export interface TreeProps { + label: string; + disabled: string; + isLeaf: string; + children: string; +} + +export interface TreeNode { + checked: boolean; + childNodes: TreeNode[]; + data: D; + expanded: boolean; + id: number; + indeterminate: boolean; + isLeaf: boolean; + level: number; + loaded: boolean; + loading: boolean; + parent: TreeNode | null; + store: any; + visible: boolean; + disabled: boolean; + icon: string; + key: K; + label: string; + nextSibling: TreeNode | null; + previousSibling: TreeNode | null; + isCurrent: boolean; +} + +/** incomplete, you can convert to any to use other properties */ +export interface TreeStore { + _getAllNodes: () => TreeNode[]; +} + +/** Tree Component */ +export declare class ElTree extends ElementUIComponent { + /** TreeStore */ + store: TreeStore; + + /** Tree data */ + data: D[]; + + /** Text displayed when data is void */ + emptyText: string; + + /** Unique identity key name for nodes, its value should be unique across the whole tree */ + nodeKey: string; + + /** Configuration options, see the following table */ + props: TreeProps; + + /** Method for loading subtree data */ + load: (data: D, resolve: Function) => void; + + /** + * Render function for a specific node + * + * @param h The render function + */ + renderContent: (h: CreateElement, context: { node: TreeNode; data: D; store: TreeStore }) => VNode; + + /** Whether current node is highlighted */ + highlightCurrent: boolean; + + /** Whether to expand all nodes by default */ + defaultExpandAll: boolean; + + /** Whether to expand or collapse node when clicking on the node. If false, then expand or collapse node only when clicking on the arrow icon. */ + expandOnClickNode: boolean; + + /** Whether to check or uncheck node when clicking on the node, if false, the node can only be checked or unchecked by clicking on the checkbox. */ + checkOnClickNode: boolean; + + /** Whether to expand father node when a child node is expanded */ + autoExpandParent: boolean; + + /** Array of keys of initially expanded nodes */ + defaultExpandedKeys: K[]; + + /** Whether node is selectable */ + showCheckbox: boolean; + + /** Whether checked state of a node not affects its father and child nodes when show-checkbox is true */ + checkStrictly: boolean; + + /** Array of keys of initially checked nodes */ + defaultCheckedKeys: K[]; + + /** + * This function will be executed on each node when use filter method. If return false, tree node will be hidden. + * + * @param value The query string + * @param data The original data object + * @param node Tree node + */ + filterNodeMethod: (value: string, data: D, node: TreeNode) => boolean; + + /** Whether only one node among the same level can be expanded at one time */ + accordion: boolean; + + /** Horizontal indentation of nodes in adjacent levels in pixels */ + indent: number; + + /** Whether enable tree nodes drag and drop */ + draggable: boolean; + + /** + * Function to be executed before dragging a node + * + * @param node The node to be dragged + */ + allowDrag: (node: TreeNode) => boolean; + + /** + * Function to be executed before the dragging node is dropped + * + * @param draggingNode The dragging node + * @param dropNode The target node + * @param type Drop type + */ + allowDrop: (draggingNode: TreeNode, dropNode: TreeNode, type: 'prev' | 'inner' | 'next') => boolean; + + /** + * Filter all tree nodes. Filtered nodes will be hidden + * + * @param value The value to be used as first parameter for `filter-node-method` + */ + filter(value: any): void; + + /** + * Update the children of the node which specified by the key + * + * @param key the key of the node which children will be updated + * @param data the children data + */ + updateKeyChildren(key: K, data: D[]): void; + + /** + * If the node can be selected (`show-checkbox` is `true`), it returns the currently selected array of nodes + * + * @param leafOnly If the `leafOnly` is `true`, it only returns the currently selected array of sub-nodes + * @param includeHalfChecked If the `includeHalfChecked` is `true`, the return value contains halfchecked nodes + */ + getCheckedNodes(leafOnly?: boolean, includeHalfChecked?: boolean): D[]; + + /** + * Set certain nodes to be checked. Only works when `node-key` is assigned + * + * @param nodes An array of nodes to be checked + * @param leafOnly If the parameter is true, it only returns the currently selected array of sub-nodes + */ + setCheckedNodes(data: D[], leafOnly?: boolean): void; + + /** + * If the node can be selected (`show-checkbox` is `true`), it returns the currently selected array of nodes' keys + * + * @param leafOnly If the `leafOnly` is `true`, it only returns the currently selected array of sub-nodes + */ + getCheckedKeys(leafOnly?: boolean): K[]; + + /** + * Set certain nodes to be checked. Only works when `node-key` is assigned + * + * @param keys An array of node's keys to be checked + * @param leafOnly If the parameter is true, it only returns the currently selected array of sub-nodes + */ + setCheckedKeys(keys: K[], leafOnly?: boolean): void; + + /** + * Set node to be checked or not. Only works when `node-key` is assigned + * + * @param data Node's key or data to be checked + * @param checked Indicating the node checked or not + * @param deep Indicating whether to checked state deeply or not + */ + setChecked(data: D | K, checked: boolean, deep: boolean): void; + + /** + * If the node can be selected (`show-checkbox` is `true`), it returns the currently half selected array of nodes + */ + getHalfCheckedNodes(): D[]; + + /** + * If the node can be selected (`show-checkbox` is `true`), it returns the currently half selected array of nodes' keys + */ + getHalfCheckedKeys(): K[]; + + /** + * Return the highlight node's key (null if no node is highlighted) + */ + getCurrentKey(): K; + + /** + * Set highlighted node by key, only works when node-key is assigned + * + * @param key The node's key to be highlighted + */ + setCurrentKey(key: K): void; + + /** + * Return the highlight node data (null if no node is highlighted) + * @todo the name of methods should be getCurrentNodeData + */ + getCurrentNode(): D; + + /** + * Set highlighted node, only works when node-key is assigned + * + * @param node The node to be highlighted + */ + setCurrentNode(data: D): void; + + /** + * Get node by node key or node data + * + * @param by node key or node data + */ + getNode(by: D | K): TreeNode; + + /** + * Remove node by key or node data or node instance + * + * @param by key or node data or node instance + */ + remove(by: D | K): void; + + /** + * Append a child node to specified node + * + * @param childData the data of appended node + * @param parent key or node data or node instance of the parent node + */ + append(childData: D, parent: D | K): void; + + /** + * insert a node before specified node + * + * @param data the data of inserted node + * @param ref key or node data or node instance of the reference node + */ + insertBefore(data: D, ref: D | K): void; + + /** + * insert a node after specified node + * + * @param data the data of inserted node + * @param ref key or node data or node instance of the reference node + */ + insertAfter(data: D, ref: D | K): void; + + /** Custom tree node icon */ + iconClass?: string; + +} diff --git a/types/upload.d.ts b/types/upload.d.ts new file mode 100644 index 0000000..525fc36 --- /dev/null +++ b/types/upload.d.ts @@ -0,0 +1,124 @@ +import { ElementUIComponent } from './component' + +export type ListType = 'text' | 'picture' | 'picture-card' +export type FileUploadStatus = 'ready' | 'uploading' | 'success' | 'fail' + +export interface FileListItem { + name: string, + url: string, + status?: FileUploadStatus +} + +export interface ElUploadInternalRawFile extends File { + uid: number +} + +export interface ElUploadInternalFileDetail { + status: FileUploadStatus, + name: string, + size: number, + percentage: number, + uid: number, + raw: ElUploadInternalRawFile, + url?: string +} + +export interface ElUploadProgressEvent extends ProgressEvent { + percent: number +} + +export interface HttpRequestOptions { + headers: object, + withCredentials: boolean, + file: File, + data: object, + filename: string, + action: string, + onProgress: (e: ElUploadProgressEvent) => void, + onSuccess: (response: any) => void, + onError: (err: ErrorEvent) => void +} + +/** Upload Component */ +export declare class ElUpload extends ElementUIComponent { + /** Request URL (required) */ + action: string + + /** Request headers */ + headers: object + + /** Whether uploading multiple files is permitted */ + multiple: boolean + + /** Additions options of request */ + data: object + + /** Key name for uploaded file */ + name: string + + /** Whether cookies are sent */ + withCredentials: boolean + + /** Whether to show the uploaded file list */ + showFileList: boolean + + /** Whether to activate drag and drop mode */ + drag: boolean + + /** Accepted file types, will not work when thumbnail-mode is true */ + accept: string + + /** Hook function when clicking the uploaded files */ + onPreview: (file: ElUploadInternalFileDetail) => void + + /** Hook function when files are removed */ + onRemove: (file: ElUploadInternalFileDetail, fileList: ElUploadInternalFileDetail[]) => void + + /** Hook function when uploaded successfully */ + onSuccess: (response: any, file: ElUploadInternalFileDetail, fileList: ElUploadInternalFileDetail[]) => void + + /** Hook function when some errors occurs */ + onError: (err: ErrorEvent, file: ElUploadInternalFileDetail, fileList: ElUploadInternalFileDetail[]) => void + + /** Hook function when some progress occurs */ + onProgress: (event: ElUploadProgressEvent, file: ElUploadInternalFileDetail, fileList: ElUploadInternalFileDetail[]) => void + + /** Hook function when file status change */ + onChange: (file: ElUploadInternalFileDetail, fileList: ElUploadInternalFileDetail[]) => void + + /** Hook function before uploading with the file to be uploaded as its parameter. If false or a Promise is returned, uploading will be aborted */ + beforeUpload: (file: ElUploadInternalRawFile) => boolean | Promise + + /** Whether thumbnail is displayed */ + thumbnailMode: boolean + + /** Default uploaded files */ + fileList: FileListItem[] + + /** Type of fileList */ + listType: ListType + + /** Whether to auto upload file */ + autoUpload: boolean + + /** Override default xhr behavior, allowing you to implement your own upload-file's request */ + httpRequest: (options: HttpRequestOptions) => void + + /** Whether to disable upload */ + disabled: boolean + + /** Maximum number of uploads allowed */ + limit: number + + /** Hook function when limit is exceeded */ + onExceed: (file: ElUploadInternalFileDetail, fileList: ElUploadInternalFileDetail[]) => void + + /** Clear the upload file list */ + clearFiles (): void; + + /** Abort specified file */ + abort (file: ElUploadInternalFileDetail): void + + /** Upload the file list manually */ + submit ():void; +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..e2ce871 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,10209 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@sinonjs/commons@^1", "@sinonjs/commons@^1.0.2", "@sinonjs/commons@^1.3.1": + version "1.4.0" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz#7b3ec2d96af481d7a0321252e7b1c94724ec5a78" + integrity sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw== + dependencies: + type-detect "4.0.8" + +"@sinonjs/formatio@^3.1.0", "@sinonjs/formatio@^3.2.1": + version "3.2.1" + resolved "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz#52310f2f9bcbc67bdac18c94ad4901b95fde267e" + integrity sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ== + dependencies: + "@sinonjs/commons" "^1" + "@sinonjs/samsam" "^3.1.0" + +"@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.2.0": + version "3.3.0" + resolved "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.0.tgz#9557ea89cd39dbc94ffbd093c8085281cac87416" + integrity sha512-beHeJM/RRAaLLsMJhsCvHK31rIqZuobfPLa/80yGH5hnD8PV1hyh9xJBJNFfNmO7yWqm+zomijHsXpI6iTQJfQ== + dependencies: + "@sinonjs/commons" "^1.0.2" + array-from "^2.1.1" + lodash "^4.17.11" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.1" + resolved "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" + integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== + +"@types/q@^1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18" + integrity sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA== + +"@vue/component-compiler-utils@^2.5.1", "@vue/component-compiler-utils@^2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.6.0.tgz#aa46d2a6f7647440b0b8932434d22f12371e543b" + integrity sha512-IHjxt7LsOFYc0DkTncB7OXJL7UzwOLPPQCfEUNyxL2qt+tF12THV+EO33O1G2Uk4feMSWua3iD39Itszx0f0bw== + dependencies: + consolidate "^0.15.1" + hash-sum "^1.0.2" + lru-cache "^4.1.2" + merge-source-map "^1.1.0" + postcss "^7.0.14" + postcss-selector-parser "^5.0.0" + prettier "1.16.3" + source-map "~0.6.1" + vue-template-es2015-compiler "^1.9.0" + +"@webassemblyjs/ast@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" + integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA== + dependencies: + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + +"@webassemblyjs/floating-point-hex-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313" + integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg== + +"@webassemblyjs/helper-api-error@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a" + integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg== + +"@webassemblyjs/helper-buffer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b" + integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w== + +"@webassemblyjs/helper-code-frame@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b" + integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw== + dependencies: + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/helper-fsm@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181" + integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A== + +"@webassemblyjs/helper-module-context@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209" + integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg== + +"@webassemblyjs/helper-wasm-bytecode@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06" + integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ== + +"@webassemblyjs/helper-wasm-section@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a" + integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + +"@webassemblyjs/ieee754@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b" + integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63" + integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw== + dependencies: + "@xtuc/long" "4.2.1" + +"@webassemblyjs/utf8@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82" + integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA== + +"@webassemblyjs/wasm-edit@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005" + integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/helper-wasm-section" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-opt" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/wasm-gen@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8" + integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wasm-opt@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7" + integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + +"@webassemblyjs/wasm-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a" + integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wast-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c" + integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/floating-point-hex-parser" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-code-frame" "1.7.11" + "@webassemblyjs/helper-fsm" "1.7.11" + "@xtuc/long" "4.2.1" + +"@webassemblyjs/wast-printer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813" + integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + "@xtuc/long" "4.2.1" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" + integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + +accepts@~1.3.4, accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +acorn-dynamic-import@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" + integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= + +acorn@^5.5.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +acorn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.5.tgz#81730c0815f3f3b34d8efa95cb7430965f4d887a" + integrity sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg== + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +agentkeepalive@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef" + integrity sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8= + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + integrity sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I= + +ajv-keywords@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= + +ajv@^5.2.3, ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ajv@^6.1.0, ajv@^6.5.5: + version "6.7.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.7.0.tgz#e3ce7bb372d6577bb1839f1dfdfcbf5ad2948d96" + integrity sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +algoliasearch@^3.24.5: + version "3.32.0" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.0.tgz#5818168c26ff921bd0346a919071bac928b747ce" + integrity sha512-C8oQnPTf0wPuyD2jSZwtBAPvz+lHOE7zRIPpgXGBuNt6ZNcC4omsbytG26318rT77a8h4759vmIp6n9p8iw4NA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.8" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + +alphanum-sort@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-colors@3.2.3, ansi-colors@^3.0.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== + +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^0.2.0, ansi-regex@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" + integrity sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" + integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== + +ansi-styles@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" + integrity sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +append-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" + integrity sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE= + dependencies: + buffer-equal "^1.0.0" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-filter@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" + integrity sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4= + dependencies: + make-iterator "^1.0.0" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-map@^2.0.0, arr-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" + integrity sha1-Onc0X/wc814qkYJWAfnljy4kysQ= + dependencies: + make-iterator "^1.0.0" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-each@^1.0.0, array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-from@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= + +array-initial@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" + integrity sha1-L6dLJnOTccOUe9enrcc74zSz15U= + dependencies: + array-slice "^1.0.0" + is-number "^4.0.0" + +array-last@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" + integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg== + dependencies: + is-number "^4.0.0" + +array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + +array-sort@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" + integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== + dependencies: + default-compare "^1.0.0" + get-value "^2.0.6" + kind-of "^5.0.2" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-done@^1.2.0, async-done@^1.2.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.1.tgz#14b7b73667b864c8f02b5b253fc9c6eddb777f3e" + integrity sha512-R1BaUeJ4PMoLNJuk+0tLJgjmEqVsdN118+Z8O+alhnQDQgy0kmD5Mqi0DNEmMx2LM0Ed5yekKu+ZXYvIHceicg== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.2" + process-nextick-args "^1.0.7" + stream-exhaust "^1.0.1" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + integrity sha1-GdOGodntxufByF04iu28xW0zYC0= + +async-each@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.2.tgz#8b8a7ca2a658f927e9f307d6d1a42f4199f0f735" + integrity sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg== + +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + +async-settle@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" + integrity sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs= + dependencies: + async-done "^1.2.2" + +async-validator@~1.8.1: + version "1.8.5" + resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-1.8.5.tgz#dc3e08ec1fd0dddb67e60842f02c0cd1cec6d7f0" + integrity sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA== + dependencies: + babel-runtime "6.x" + +async@1.x, async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@^2.0.0, async@^2.6.1: + version "2.6.2" + resolved "https://registry.npmjs.org/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" + integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== + dependencies: + lodash "^4.17.11" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@^9.1.3: + version "9.5.0" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.5.0.tgz#7e51d0355c11596e6cf9a0afc9a44e86d1596c70" + integrity sha512-hMKcyHsZn5+qL6AUeP3c8OyuteZ4VaUlg+fWbyl8z7PqsKHF/Bf8/px3K6AT8aMzDkBo8Bc11245MM+itDBOxQ== + dependencies: + browserslist "^4.4.2" + caniuse-lite "^1.0.30000947" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.14" + postcss-value-parser "^3.3.1" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + +babel-cli@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" + integrity sha1-UCq1SHTX24itALiHoGODzgPQAvE= + dependencies: + babel-core "^6.26.0" + babel-polyfill "^6.26.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + commander "^2.11.0" + convert-source-map "^1.5.0" + fs-readdir-recursive "^1.0.0" + glob "^7.1.2" + lodash "^4.17.4" + output-file-sync "^1.1.2" + path-is-absolute "^1.0.1" + slash "^1.0.0" + source-map "^0.5.6" + v8flags "^2.1.1" + optionalDependencies: + chokidar "^1.6.1" + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.26.0, babel-core@^6.26.3: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.18.0, babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-bindify-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" + integrity sha1-FMGeXxQte0fxmlJDHlKxzLxAozA= + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-explode-class@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + integrity sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes= + dependencies: + babel-helper-bindify-decorators "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-vue-jsx-merge-props@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6" + integrity sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg== + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-loader@^7.1.5: + version "7.1.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.5.tgz#e3ee0cd7394aa557e013b02d3e492bfd07aa6d68" + integrity sha512-iCHfbieL5d1LfOQeeVJEUyD9rTwBcP/fcEbRCfempxTDuqrKpu0AZjLAQHEQa3Yqyj9ORKe2iHfoj4rHLf7xpw== + dependencies: + find-cache-dir "^1.0.0" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-add-module-exports@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz#9ae9a1f4a8dc67f0cdec4f4aeda1e43a5ff65e25" + integrity sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU= + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-istanbul@^4.1.1: + version "4.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + integrity sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ== + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" + +babel-plugin-module-resolver@^2.2.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-2.7.1.tgz#18be3c42ddf59f7a456c9e0512cd91394f6e4be1" + integrity sha1-GL48Qt31n3pFbJ4FEs2ROU9uS+E= + dependencies: + find-babel-config "^1.0.1" + glob "^7.1.1" + resolve "^1.2.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= + +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + integrity sha1-a8lj67FuzLrmuStZbrfzXDQqi5o= + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= + +babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + integrity sha1-MSVjtNvePMgGzuPkFszurd0RrAs= + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= + +babel-plugin-syntax-jsx@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= + +babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= + +babel-plugin-transform-async-generator-functions@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + integrity sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds= + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-class-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= + dependencies: + babel-helper-function-name "^6.24.1" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" + integrity sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0= + dependencies: + babel-helper-explode-class "^6.24.1" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-vue-jsx@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-3.7.0.tgz#d40492e6692a36b594f7e9a1928f43e969740960" + integrity sha512-W39X07/n3oJMQd8tALBO+440NraGSF//Lo1ydd/9Nme3+QiRGFBb1Q39T9iixh0jZPPbfv3so18tNoIgLatymw== + dependencies: + esutils "^2.0.2" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-preset-stage-2@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" + integrity sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE= + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-transform-class-properties "^6.24.1" + babel-plugin-transform-decorators "^6.24.1" + babel-preset-stage-3 "^6.24.1" + +babel-preset-stage-3@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" + integrity sha1-g2raCp56f6N8sTj7kyb4eTSkg5U= + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-generator-functions "^6.24.1" + babel-plugin-transform-async-to-generator "^6.24.1" + babel-plugin-transform-exponentiation-operator "^6.24.1" + babel-plugin-transform-object-rest-spread "^6.22.0" + +babel-regenerator-runtime@^6.5.0: + version "6.5.0" + resolved "https://registry.npmjs.org/babel-regenerator-runtime/-/babel-regenerator-runtime-6.5.0.tgz#0e41cd1c9f80442466f015c749fff8ba98f8e110" + integrity sha1-DkHNHJ+ARCRm8BXHSf/4upj44RA= + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@6.x, babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +bach@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" + integrity sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA= + dependencies: + arr-filter "^1.1.1" + arr-flatten "^1.0.1" + arr-map "^2.0.0" + array-each "^1.0.0" + array-initial "^1.0.0" + array-last "^1.1.1" + async-done "^1.2.2" + async-settle "^1.0.0" + now-and-later "^2.0.0" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@^3.1.1, bluebird@^3.3.0, bluebird@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" + integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.18.3, body-parser@^1.16.1: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.0, braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +browserslist@^4.0.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.4.1.tgz#42e828954b6b29a7a53e352277be429478a69062" + integrity sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A== + dependencies: + caniuse-lite "^1.0.30000929" + electron-to-chromium "^1.3.103" + node-releases "^1.1.3" + +browserslist@^4.4.2: + version "4.5.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.5.1.tgz#2226cada1947b33f4cfcf7b608dcb519b6128106" + integrity sha512-/pPw5IAUyqaQXGuD5vS8tcbudyPZ241jk1W5pQBsGDfcjNQt7p8qxZhgMNuygDShte1PibLFexecWUPgmVLfrg== + dependencies: + caniuse-lite "^1.0.30000949" + electron-to-chromium "^1.3.116" + node-releases "^1.1.11" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +cacache@^11.0.2, cacache@^11.2.0, cacache@^11.3.1: + version "11.3.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" + integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== + dependencies: + bluebird "^3.5.3" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.3" + graceful-fs "^4.1.15" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= + dependencies: + callsites "^0.2.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000929: + version "1.0.30000938" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000938.tgz#b64bf1427438df40183fce910fe24e34feda7a3f" + integrity sha512-ekW8NQ3/FvokviDxhdKLZZAx7PptXNwxKgXtnR5y+PR3hckwuP3yJ1Ir+4/c97dsHNqtAyfKUGdw8P4EYzBNgw== + +caniuse-lite@^1.0.30000844: + version "1.0.30000929" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000929.tgz#7b391b781a9c3097ecc39ea053301aea8ea16317" + integrity sha512-n2w1gPQSsYyorSVYqPMqbSaz1w7o9ZC8VhOEGI9T5MfGDzp7sbopQxG6GaQmYsaq13Xfx/mkxJUWC1Dz3oZfzw== + +caniuse-lite@^1.0.30000947, caniuse-lite@^1.0.30000949: + version "1.0.30000950" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000950.tgz#8c559d66e332b34e919d1086cc6d29c1948856ae" + integrity sha512-Cs+4U9T0okW2ftBsCIHuEYXXkki7mjXmjCh4c6PzYShk04qDEr76/iC7KwhLoWoY65wcra1XOsRD+S7BptEb5A== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chai@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.0" + type-detect "^4.0.5" + +chalk@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" + integrity sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ= + dependencies: + ansi-styles "^1.1.0" + escape-string-regexp "^1.0.0" + has-ansi "^0.1.0" + strip-ansi "^0.3.0" + supports-color "^0.2.0" + +chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + +chokidar@^1.6.1, chokidar@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chokidar@^2.0.0, chokidar@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chokidar@^2.0.3: + version "2.1.2" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.1.2.tgz#9c23ea40b01638439e0513864d362aeacc5ad058" + integrity sha512-IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.0" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A== + dependencies: + tslib "^1.9.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-css@4.2.x: + version "4.2.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" + integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== + dependencies: + source-map "~0.6.0" + +clean-css@^3.1.9: + version "3.4.28" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" + integrity sha1-vxlF6C/ICPVWlebd6uwBQA79A/8= + dependencies: + commander "2.8.x" + source-map "0.4.x" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-deep@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-2.0.2.tgz#00db3a1e173656730d1188c3d6aced6d7ea97713" + integrity sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ== + dependencies: + for-own "^1.0.0" + is-plain-object "^2.0.4" + kind-of "^6.0.0" + shallow-clone "^1.0.0" + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone-stats@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65" + integrity sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +coa@~2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-map@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" + integrity sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw= + dependencies: + arr-map "^2.0.2" + for-own "^1.0.0" + make-iterator "^1.0.0" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +color@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.0.tgz#d8e9fb096732875774c84bf922815df0308d0ffc" + integrity sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colors@^1.1.0, colors@^1.1.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +colors@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + +commander@2.17.x, commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commander@2.8.x: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= + dependencies: + graceful-readlink ">= 1.0.0" + +commander@^2.11.0, commander@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commander@~2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1, component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +compressible@~2.0.14: + version "2.0.15" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.15.tgz#857a9ab0a7e5a07d8d837ed43fe2defff64fe212" + integrity sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw== + dependencies: + mime-db ">= 1.36.0 < 2" + +compression@^1.5.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db" + integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.14" + debug "2.6.9" + on-headers "~1.0.1" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0, concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect-history-api-fallback@^1.3.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +connect@^3.6.0: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ= + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +consolidate@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" + integrity sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw== + dependencies: + bluebird "^3.1.1" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.5.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +copy-props@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.4.tgz#93bb1cadfafd31da5bb8a9d4b41f471ec3a72dfe" + integrity sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A== + dependencies: + each-props "^1.3.0" + is-plain-object "^2.0.1" + +copy-webpack-plugin@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.0.0.tgz#db3269ab83e8a2c3316c1bc9cba54019bbcf5c17" + integrity sha512-iiDj+8nnZeW/i8vYJ3+ABSZkOefJnDYIGLojiZKKFDvf1wcEInABXH1+hN7axQMn04qvJxKjgVOee0e14XPtCg== + dependencies: + cacache "^11.3.1" + find-cache-dir "^2.0.0" + globby "^7.1.1" + is-glob "^4.0.0" + loader-utils "^1.1.0" + minimatch "^3.0.4" + normalize-path "^3.0.0" + p-limit "^2.1.0" + serialize-javascript "^1.4.0" + webpack-log "^2.0.0" + +core-js@^2.2.0, core-js@^2.4.0, core-js@^2.5.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944" + integrity sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.1.0.tgz#6c5c35e97f37f985061cdf653f114784231185cf" + integrity sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.9.0" + lodash.get "^4.4.2" + parse-json "^4.0.0" + +coveralls@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/coveralls/-/coveralls-3.0.3.tgz#83b1c64aea1c6afa69beaf50b55ac1bc4d13e2b8" + integrity sha512-viNfeGlda2zJr8Gj1zqXpDMRjw9uM54p7wzZdvLRyOgnAfCe974Dq4veZkjJdxQXbmdppu6flEajFYseHYaUhg== + dependencies: + growl "~> 1.10.0" + js-yaml "^3.11.0" + lcov-parse "^0.0.10" + log-driver "^1.2.7" + minimist "^1.2.0" + request "^2.86.0" + +cp-cli@^1.0.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cp-cli/-/cp-cli-1.1.2.tgz#b24e1fdb8b07a27ce3879995c8c0c6d67caa8b86" + integrity sha1-sk4f24sHonzjh5mVyMDG1nyqi4Y= + dependencies: + fs-extra "5.0.0" + yargs "11.0.0" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-env@^3.1.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-3.2.4.tgz#9e0585f277864ed421ce756f81a980ff0d698aba" + integrity sha1-ngWF8neGTtQhznVvgamA/w1piro= + dependencies: + cross-spawn "^5.1.0" + is-windows "^1.0.0" + +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1, cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-color-names@0.0.4, css-color-names@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + +css-declaration-sorter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== + dependencies: + postcss "^7.0.1" + timsort "^0.3.0" + +css-loader@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.0.tgz#42952ac22bca5d076978638e9813abce49b8f0cc" + integrity sha512-MoOu+CStsGrSt5K2OeZ89q3Snf+IkxRfAIt9aAKg4piioTrhtP1iEFPu+OVn3Ohz24FO6L+rw9UJxBILiSBw5Q== + dependencies: + icss-utils "^4.0.0" + loader-utils "^1.2.1" + lodash "^4.17.11" + postcss "^7.0.6" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^2.0.3" + postcss-modules-scope "^2.0.0" + postcss-modules-values "^2.0.0" + postcss-value-parser "^3.3.0" + schema-utils "^1.0.0" + +css-select-base-adapter@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-select@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.2.tgz#ab4386cec9e1f668855564b17c3733b43b2a5ede" + integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ== + dependencies: + boolbase "^1.0.0" + css-what "^2.1.2" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-selector-tokenizer@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz#a177271a8bca5019172f4f891fc6eed9cbf68d5d" + integrity sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA== + dependencies: + cssesc "^0.1.0" + fastparse "^1.1.1" + regexpu-core "^1.0.0" + +css-tree@1.0.0-alpha.28: + version "1.0.0-alpha.28" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.28.tgz#8e8968190d886c9477bc8d61e96f61af3f7ffa7f" + integrity sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w== + dependencies: + mdn-data "~1.1.0" + source-map "^0.5.3" + +css-tree@1.0.0-alpha.29: + version "1.0.0-alpha.29" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" + integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg== + dependencies: + mdn-data "~1.1.0" + source-map "^0.5.3" + +css-unit-converter@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" + integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY= + +css-url-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec" + integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= + +css-what@2.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" + integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ== + +css-what@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +cssesc@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" + integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q= + +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== + +cssnano-preset-default@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" + integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== + dependencies: + css-declaration-sorter "^4.0.1" + cssnano-util-raw-cache "^4.0.1" + postcss "^7.0.0" + postcss-calc "^7.0.1" + postcss-colormin "^4.0.3" + postcss-convert-values "^4.0.1" + postcss-discard-comments "^4.0.2" + postcss-discard-duplicates "^4.0.2" + postcss-discard-empty "^4.0.1" + postcss-discard-overridden "^4.0.1" + postcss-merge-longhand "^4.0.11" + postcss-merge-rules "^4.0.3" + postcss-minify-font-values "^4.0.2" + postcss-minify-gradients "^4.0.2" + postcss-minify-params "^4.0.2" + postcss-minify-selectors "^4.0.2" + postcss-normalize-charset "^4.0.1" + postcss-normalize-display-values "^4.0.2" + postcss-normalize-positions "^4.0.2" + postcss-normalize-repeat-style "^4.0.2" + postcss-normalize-string "^4.0.2" + postcss-normalize-timing-functions "^4.0.2" + postcss-normalize-unicode "^4.0.1" + postcss-normalize-url "^4.0.1" + postcss-normalize-whitespace "^4.0.2" + postcss-ordered-values "^4.1.2" + postcss-reduce-initial "^4.0.3" + postcss-reduce-transforms "^4.0.2" + postcss-svgo "^4.0.2" + postcss-unique-selectors "^4.0.1" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= + +cssnano-util-raw-cache@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== + dependencies: + postcss "^7.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== + +cssnano@^4.1.0: + version "4.1.10" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" + integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.7" + is-resolvable "^1.0.0" + postcss "^7.0.0" + +csso@^3.5.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/csso/-/csso-3.5.1.tgz#7b9eb8be61628973c1b261e169d2f024008e758b" + integrity sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg== + dependencies: + css-tree "1.0.0-alpha.29" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= + dependencies: + es5-ext "^0.10.9" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +date-format@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/date-format/-/date-format-2.0.0.tgz#7cf7b172f1ec564f0003b39ea302c5498fb98c8f" + integrity sha512-M6UqVvZVgFYqZL1SfHsRGIQSz3ZL+qgbsV5Lp1Vj61LZVYuEwcMXYay7DRDtYs2HQQBK5hQtQ0fD9aEJ89V0LA== + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +dateformat@^1.0.6, dateformat@^1.0.7-1.2.3: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk= + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + +de-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" + integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= + +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.2.6, debug@^3.1.0, debug@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@=3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decamelize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" + integrity sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg== + dependencies: + xregexp "4.0.0" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + +deep-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepmerge@^1.2.0, deepmerge@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" + integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== + +default-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" + integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== + dependencies: + kind-of "^5.0.2" + +default-gateway@^2.6.0: + version "2.7.2" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.7.2.tgz#b7ef339e5e024b045467af403d50348db4642d0f" + integrity sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ== + dependencies: + execa "^0.10.0" + ip-regex "^2.1.0" + +default-resolution@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" + integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ= + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= + dependencies: + globby "^6.1.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + p-map "^1.1.1" + pify "^3.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= + +diff@3.5.0, diff@^3.5.0: + version "3.5.0" + resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +dom-converter@~0.2: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serialize@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +dom-serializer@0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" + integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII= + dependencies: + domelementtype "~1.1.1" + entities "~1.1.1" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1, domelementtype@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@~1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs= + +domhandler@2.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.1.0.tgz#d2646f5e57f6c3bab11cf6cb05d3c0acf7412594" + integrity sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ= + dependencies: + domelementtype "1" + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485" + integrity sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU= + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1, domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-prop@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.1.tgz#b1a7a29c4abfd639585efaecce80d666b1e34125" + integrity sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +each-props@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333" + integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA== + dependencies: + is-plain-object "^2.0.1" + object.defaults "^1.1.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.3.103: + version "1.3.113" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz#b1ccf619df7295aea17bc6951dc689632629e4a9" + integrity sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g== + +electron-to-chromium@^1.3.116: + version "1.3.116" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.116.tgz#1dbfee6a592a0c14ade77dbdfe54fef86387d702" + integrity sha512-NKwKAXzur5vFCZYBHpdWjTMO8QptNLNP80nItkSIgUOapPAo9Uia+RvkCaZJtO7fhQaVElSvBPWEc2ku6cKsPA== + +electron-to-chromium@^1.3.47: + version "1.3.103" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.103.tgz#a695777efdbc419cad6cbb0e58458251302cd52f" + integrity sha512-tObPqGmY9X8MUM8i3MEimYmbnLLf05/QV5gPlkR8MQ3Uj8G8B2govE1U4cQcBYtv3ymck9Y8cIOu4waoiykMZQ== + +elliptic@^6.0.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +encodeurl@~1.0.1, encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +engine.io-client@~3.2.0: + version "3.2.1" + resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36" + integrity sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.1.1" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~3.3.1" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6" + integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.2.0: + version "3.2.1" + resolved "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz#b60281c35484a70ee0351ea0ebff83ec8c9522a2" + integrity sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w== + dependencies: + accepts "~1.3.4" + base64id "1.0.0" + cookie "0.3.1" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~3.3.1" + +enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= + +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +envify@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e" + integrity sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw== + dependencies: + esprima "^4.0.0" + through "~2.3.4" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.12.0, es-abstract@^1.5.1: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-keys "^1.0.12" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.14: + version "0.10.49" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.49.tgz#059a239de862c94494fec28f8150c977028c6c5e" + integrity sha512-3NMEhi57E31qdzmYp2jwRArIUsj1HI/RxbQ4bgnSB+AIKIxsAmTiK83bYMifIcpWvEc3P1X30DhUKOqEtF/kvg== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "^1.0.0" + +es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.47" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.47.tgz#d24232e1380daad5449a817be19bde9729024a11" + integrity sha512-/1TItLfj+TTfWoeRcDn/0FbGV6SNo4R+On2GGVucPU/j3BWnXE2Co8h8CTo4Tu34gFJtnmwS9xiScKs4EjZhdw== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "1" + +es6-iterator@^2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.0.5, es6-promise@^4.1.0: + version "4.2.5" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054" + integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg== + +es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + integrity sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8= + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +eslint-config-elemefe@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-config-elemefe/-/eslint-config-elemefe-0.1.1.tgz#5a1664ce3f7d91f68528b508d040044ae6c10aa3" + integrity sha1-WhZkzj99kfaFKLUI0EAESubBCqM= + +eslint-loader@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.1.1.tgz#2a9251523652430bfdd643efdb0afc1a2a89546a" + integrity sha512-1GrJFfSevQdYpoDzx8mEE2TDWsb/zmFuY09l6hURg1AeFIKQOvZ+vH0UPjzmd1CZIbfTV5HUkMeBmFiDBkgIsQ== + dependencies: + loader-fs-cache "^1.0.0" + loader-utils "^1.0.2" + object-assign "^4.0.1" + object-hash "^1.1.4" + rimraf "^2.6.1" + +eslint-plugin-html@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-4.0.6.tgz#724bb9272efb4df007dfee8dfb269ed83577e5b4" + integrity sha512-nj6A9oK+7BKnMm0E7dMRH3r75BfpkXtcVIb3pFC4AcDdBTNyg2NGxHXyFNT1emW4VsR7P2SZvRXXQtUR+kY08w== + dependencies: + htmlparser2 "^3.8.2" + +eslint-plugin-json@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-json/-/eslint-plugin-json-1.3.2.tgz#63fb1127b44864f2629b2571d7f10d52d81334ab" + integrity sha512-WPdA8ph8ptdlPPta7se9zhhVKd3qGmeiNJkCi6hQi5xPXPEXkXkoNGAUjVD6EXN2Df3ded1ww4jXSn6+JA65fQ== + dependencies: + vscode-json-languageservice "^3.2.1" + +eslint-scope@^3.7.1: + version "3.7.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" + integrity sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@4.18.2: + version "4.18.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.18.2.tgz#0f81267ad1012e7d2051e186a9004cc2267b8d45" + integrity sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw== + dependencies: + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.2" + esquery "^1.0.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "4.0.2" + text-table "~0.2.0" + +espree@^3.5.2: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== + +events@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== + +eventsource@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.16.2: + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.3" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.4" + qs "6.5.2" + range-parser "~1.2.0" + safe-buffer "5.1.2" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +external-editor@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fancy-log@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastparse@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" + integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg= + dependencies: + websocket-driver ">=0.5.1" + +figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +file-loader@^1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.11.tgz#6fe886449b0f2a936e43cabaac0cdbfb369506f8" + integrity sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg== + dependencies: + loader-utils "^1.0.2" + schema-utils "^0.4.5" + +file-save@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/file-save/-/file-save-0.2.0.tgz#39b20d0214e656b1417faa3c32d317b678545db7" + integrity sha1-ObINAhTmVrFBf6o8MtMXtnhUXbc= + dependencies: + mkdirp "~0.5.0" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +filesize@~2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-2.0.4.tgz#7805941c60fcdfe63f46d7ea358c59ade11c1325" + integrity sha1-eAWUHGD83+Y/RtfqNYxZreEcEyU= + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U= + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + +find-babel-config@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.1.0.tgz#acc01043a6749fec34429be6b64f542ebb5d6355" + integrity sha1-rMAQQ6Z0n+w0Qpvmtk9ULrtdY1U= + dependencies: + json5 "^0.5.1" + path-exists "^3.0.0" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + +find-cache-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" + integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA== + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +findup-sync@2.0.0, findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +fined@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.1.tgz#95d88ff329123dd1a6950fdfcd321f746271e01f" + integrity sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + +flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + +flat-cache@^1.2.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== + dependencies: + circular-json "^0.3.1" + graceful-fs "^4.1.2" + rimraf "~2.6.2" + write "^0.2.1" + +flat@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" + integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== + dependencies: + is-buffer "~2.0.3" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== + +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + integrity sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +flush-write-stream@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.6.1.tgz#514973c44b5757368bad8bddfe52f81f015c94cb" + integrity sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ== + dependencies: + debug "=3.1.0" + +for-in@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" + integrity sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE= + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-access@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" + integrity sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o= + dependencies: + null-check "^1.0.0" + +fs-extra@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.0: + version "7.0.1" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + +fs-mkdirp-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" + integrity sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes= + dependencies: + graceful-fs "^4.1.11" + through2 "^2.0.3" + +fs-readdir-recursive@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.0.0, fsevents@^1.2.2, fsevents@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" + integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +fstream@^1.0.0, fstream@^1.0.2: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gaze@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + integrity sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ= + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + +glob-watcher@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.3.tgz#88a8abf1c4d131eb93928994bc4a593c2e5dd626" + integrity sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg== + dependencies: + anymatch "^2.0.0" + async-done "^1.2.0" + chokidar "^2.0.0" + is-negated-glob "^1.0.0" + just-debounce "^1.0.0" + object.defaults "^1.1.0" + +glob@7.1.3, glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules-path@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.1.tgz#e541f4c800a1a8514a990477b267ac67525b9931" + integrity sha512-y+shkf4InI7mPRHSo2b/k6ix6+NLDtyccYv86whhxrSGX9wjPX1VMITmrDbE1eh7zkzhiWtW2sHklJYoQ62Cxg== + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +global@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^11.0.1: + version "11.10.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.10.0.tgz#1e09776dffda5e01816b3bb4077c8b59c24eaa50" + integrity sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ== + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globule@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" + integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== + dependencies: + glob "~7.1.1" + lodash "~4.17.10" + minimatch "~3.0.2" + +glogg@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" + integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== + dependencies: + sparkles "^1.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@~4.1.4: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +graceful-fs@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-2.0.3.tgz#7cd2cdb228a4a3f36e95efa6cc142de7d1a136d0" + integrity sha1-fNLNsiiko/Nule+mzBQt59GhNtA= + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +growl@1.10.5, "growl@~> 1.10.0": + version "1.10.5" + resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +gulp-autoprefixer@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gulp-autoprefixer/-/gulp-autoprefixer-6.0.0.tgz#7034ef12c24a92a5b20158d63623ebbd900faed8" + integrity sha512-MyLymXKVGTVBx/okQSBqmdhwhyqi3igBmZBwgpZp0GRbY1LY8VctOTLzwkQ18bZKJkSDnOKR5u32TMY9wSYdqQ== + dependencies: + autoprefixer "^9.1.3" + fancy-log "^1.3.2" + plugin-error "^1.0.1" + postcss "^7.0.2" + through2 "^2.0.0" + vinyl-sourcemaps-apply "^0.2.0" + +gulp-cli@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.0.1.tgz#7847e220cb3662f2be8a6d572bf14e17be5a994b" + integrity sha512-RxujJJdN8/O6IW2nPugl7YazhmrIEjmiVfPKrWt68r71UCaLKS71Hp0gpKT+F6qOUFtr7KqtifDKaAJPRVvMYQ== + dependencies: + ansi-colors "^1.0.1" + archy "^1.0.0" + array-sort "^1.0.0" + color-support "^1.1.3" + concat-stream "^1.6.0" + copy-props "^2.0.1" + fancy-log "^1.3.2" + gulplog "^1.0.0" + interpret "^1.1.0" + isobject "^3.0.1" + liftoff "^2.5.0" + matchdep "^2.0.0" + mute-stdout "^1.0.0" + pretty-hrtime "^1.0.0" + replace-homedir "^1.0.0" + semver-greatest-satisfied-range "^1.1.0" + v8flags "^3.0.1" + yargs "^7.1.0" + +gulp-cssmin@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/gulp-cssmin/-/gulp-cssmin-0.2.0.tgz#87ab3c69dd39b20d5d96355c6504ad6a447b1e72" + integrity sha1-h6s8ad05sg1dljVcZQStakR7HnI= + dependencies: + clean-css "^3.1.9" + filesize "~2.0.0" + graceful-fs "~4.1.4" + gulp-rename "~1.1.0" + gulp-util "~2.2.0" + map-stream "0.0.4" + temp-write "~0.1.0" + +gulp-rename@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-1.1.0.tgz#93090aaaf4d386c07f20538a6888f15efba727a1" + integrity sha1-kwkKqvTThsB/IFOKaIjxXvunJ6E= + dependencies: + map-stream ">=0.0.4" + +gulp-sass@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-4.0.2.tgz#cfb1e3eff2bd9852431c7ce87f43880807d8d505" + integrity sha512-q8psj4+aDrblJMMtRxihNBdovfzGrXJp1l4JU0Sz4b/Mhsi2DPrKFYCGDwjIWRENs04ELVHxdOJQ7Vs98OFohg== + dependencies: + chalk "^2.3.0" + lodash.clonedeep "^4.3.2" + node-sass "^4.8.3" + plugin-error "^1.0.1" + replace-ext "^1.0.0" + strip-ansi "^4.0.0" + through2 "^2.0.0" + vinyl-sourcemaps-apply "^0.2.0" + +gulp-util@~2.2.0: + version "2.2.20" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-2.2.20.tgz#d7146e5728910bd8f047a6b0b1e549bc22dbd64c" + integrity sha1-1xRuVyiRC9jwR6awseVJvCLb1kw= + dependencies: + chalk "^0.5.0" + dateformat "^1.0.7-1.2.3" + lodash._reinterpolate "^2.4.1" + lodash.template "^2.4.1" + minimist "^0.2.0" + multipipe "^0.1.0" + through2 "^0.5.0" + vinyl "^0.2.1" + +gulp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.0.tgz#95766c601dade4a77ed3e7b2b6dc03881b596366" + integrity sha1-lXZsYB2t5Kd+0+eyttwDiBtZY2Y= + dependencies: + glob-watcher "^5.0.0" + gulp-cli "^2.0.0" + undertaker "^1.0.0" + vinyl-fs "^3.0.0" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= + dependencies: + glogg "^1.0.0" + +handle-thing@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" + integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== + +handlebars@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" + integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e" + integrity sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4= + dependencies: + ansi-regex "^0.2.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.0, has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash-sum@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" + integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.0, he@1.2.x, he@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== + +highlight.js@^9.3.0: + version "9.13.1" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" + integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +homedir-polyfill@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" + integrity sha1-TCu8inWJmP7r9e1oWA921GdotLw= + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + +html-comment-regex@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +html-entities@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + +html-minifier@^3.2.3: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + +html-webpack-plugin@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" + integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= + dependencies: + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + tapable "^1.0.0" + toposort "^1.0.0" + util.promisify "1.0.0" + +htmlparser2@^3.8.2: + version "3.10.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" + integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ== + dependencies: + domelementtype "^1.3.0" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.0.6" + +htmlparser2@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.3.0.tgz#cc70d05a59f6542e43f0e685c982e14c924a9efe" + integrity sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4= + dependencies: + domelementtype "1" + domhandler "2.1" + domutils "1.1" + readable-stream "1.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.4.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8" + integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w== + +http-proxy-middleware@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz#0987e6bb5a5606e5a69168d8f967a87f15dd8aab" + integrity sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q== + dependencies: + http-proxy "^1.16.2" + is-glob "^4.0.0" + lodash "^4.17.5" + micromatch "^3.1.9" + +http-proxy@^1.13.0, http-proxy@^1.16.2: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== + dependencies: + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + +icss-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.0.0.tgz#d52cf4bcdcfa1c45c2dbefb4ffdf6b00ef608098" + integrity sha512-bA/xGiwWM17qjllIs9X/y0EjsB7e0AV08F3OL8UPsoNkNRibIuu8f1eKTnQ8QO1DteKKTxTUAn+IEWUToIwGOA== + dependencies: + postcss "^7.0.5" + +ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + +ignore@^3.3.3, ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +inquirer@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" + integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.11" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.0.0" + through "^2.3.6" + +internal-ip@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-3.0.1.tgz#df5c99876e1d2eb2ea2d74f520e3f669a00ece27" + integrity sha512-NXXgESC2nNVtU+pqmC9e6R8B1GpKxzsAQhffvh5AL79qKnodd+L7tnEQmTiUAVngqLalPbSqRA7XGIEL5nCd0Q== + dependencies: + default-gateway "^2.6.0" + ipaddr.js "^1.5.2" + +interpret@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= + +ipaddr.js@^1.5.2: + version "1.8.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.1.tgz#fa4b79fa47fd3def5e3b159825161c0a519c9427" + integrity sha1-+kt5+kf9Pe9eOxWYJRYcClGclCc= + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-buffer@~2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-color-stop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= + dependencies: + is-extglob "^2.1.1" + +is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-svg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" + integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== + dependencies: + html-comment-regex "^1.1.0" + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-valid-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" + integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao= + +is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isarray@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.4.tgz#38e7bcbb0f3ba1b7933c86ba1894ddfc3781bbb7" + integrity sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA== + +isbinaryfile@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" + integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== + dependencies: + buffer-alloc "^1.2.0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== + +istanbul-lib-instrument@^1.10.1: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" + integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.1" + semver "^5.3.0" + +istanbul@^0.4.0: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +javascript-stringify@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-1.6.0.tgz#142d111f3a6e3dae8f4a9afd77d45855b5a9cce3" + integrity sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM= + +js-base64@^2.1.8: + version "2.5.1" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" + integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@3.12.0: + version "3.12.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@3.x, js-yaml@^3.11.0, js-yaml@^3.12.0, js-yaml@^3.9.0, js-yaml@^3.9.1: + version "3.12.2" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz#ef1d067c5a9d9cb65bd72f285b5d8105c77f14fc" + integrity sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-loader@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" + integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w== + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json-templater@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/json-templater/-/json-templater-1.2.0.tgz#d12c96c7781d8451d623a8bee9b58f6901a8b15e" + integrity sha512-u2l5PGQuLs6eoeAW6z7LOgyk17d7v4LutnO630ZQt1Nw9XxzepU4vD1HDlYV45d0aR3tBek4AK6GYWbEI0nhOQ== + +json3@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +jsonc-parser@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.0.2.tgz#42fcf56d70852a043fadafde51ddb4a85649978d" + integrity sha512-TSU435K5tEKh3g7bam1AFf+uZrISheoDsLlpmAo6wWZYqjsnd09lHYK1Qo+moK4Ikifev1Gdpa69g4NELKnCrQ== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +just-debounce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.0.0.tgz#87fccfaeffc0b68cd19d55f6722943f929ea35ea" + integrity sha1-h/zPrv/AtozRnVX2cilD+SnqNeo= + +just-extend@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc" + integrity sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw== + +karma-chrome-launcher@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf" + integrity sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w== + dependencies: + fs-access "^1.0.0" + which "^1.2.1" + +karma-coverage@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.2.tgz#cc09dceb589a83101aca5fe70c287645ef387689" + integrity sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw== + dependencies: + dateformat "^1.0.6" + istanbul "^0.4.0" + lodash "^4.17.0" + minimatch "^3.0.0" + source-map "^0.5.1" + +karma-mocha@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz#eeaac7ffc0e201eb63c467440d2b69c7cf3778bf" + integrity sha1-7qrH/8DiAetjxGdEDStpx883eL8= + dependencies: + minimist "1.2.0" + +karma-sinon-chai@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/karma-sinon-chai/-/karma-sinon-chai-2.0.2.tgz#e28c109b989973abafc28a7c9f09ef24a05e07c2" + integrity sha512-SDgh6V0CUd+7ruL1d3yG6lFzmJNGRNQuEuCYXLaorruNP9nwQfA7hpsp4clx4CbOo5Gsajh3qUOT7CrVStUKMw== + +karma-sourcemap-loader@^0.3.7: + version "0.3.7" + resolved "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8" + integrity sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg= + dependencies: + graceful-fs "^4.1.2" + +karma-spec-reporter@^0.0.32: + version "0.0.32" + resolved "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.32.tgz#2e9c7207ea726771260259f82becb543209e440a" + integrity sha1-LpxyB+pyZ3EmAln4K+y1QyCeRAo= + dependencies: + colors "^1.1.2" + +karma-webpack@^3.0.5: + version "3.0.5" + resolved "https://registry.npmjs.org/karma-webpack/-/karma-webpack-3.0.5.tgz#1ff1e3a690fb73ae95ee95f9ab58f341cfc7b40f" + integrity sha512-nRudGJWstvVuA6Tbju9tyGUfXTtI1UXMXoRHVmM2/78D0q6s/Ye2IC157PKNDC15PWFGR0mVIRtWLAdcfsRJoA== + dependencies: + async "^2.0.0" + babel-runtime "^6.0.0" + loader-utils "^1.0.0" + lodash "^4.0.0" + source-map "^0.5.6" + webpack-dev-middleware "^2.0.6" + +karma@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/karma/-/karma-4.0.1.tgz#2581d6caa0d4cd28b65131561b47bad6d5478773" + integrity sha512-ind+4s03BqIXas7ZmraV3/kc5+mnqwCd+VDX1FndS6jxbt03kQKX2vXrWxNLuCjVYmhMwOZosAEKMM0a2q7w7A== + dependencies: + bluebird "^3.3.0" + body-parser "^1.16.1" + braces "^2.3.2" + chokidar "^2.0.3" + colors "^1.1.0" + connect "^3.6.0" + core-js "^2.2.0" + di "^0.0.1" + dom-serialize "^2.2.0" + flatted "^2.0.0" + glob "^7.1.1" + graceful-fs "^4.1.2" + http-proxy "^1.13.0" + isbinaryfile "^3.0.0" + lodash "^4.17.11" + log4js "^4.0.0" + mime "^2.3.1" + minimatch "^3.0.2" + optimist "^0.6.1" + qjobs "^1.1.4" + range-parser "^1.2.0" + rimraf "^2.6.0" + safe-buffer "^5.0.1" + socket.io "2.1.1" + source-map "^0.6.1" + tmp "0.0.33" + useragent "2.3.0" + +killable@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0, kind-of@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +last-call-webpack-plugin@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" + integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== + dependencies: + lodash "^4.17.5" + webpack-sources "^1.1.0" + +last-run@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" + integrity sha1-RblpQsF7HHnHchmCWbqUO+v4yls= + dependencies: + default-resolution "^2.0.0" + es6-weak-map "^2.0.1" + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +lcov-parse@^0.0.10: + version "0.0.10" + resolved "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" + integrity sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM= + +lead@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" + integrity sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI= + dependencies: + flush-write-stream "^1.0.2" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +liftoff@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" + integrity sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew= + dependencies: + extend "^3.0.0" + findup-sync "^2.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +lightercollective@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lightercollective/-/lightercollective-0.1.0.tgz#70df102c530dcb8d0ccabfe6175a8d00d5f61300" + integrity sha512-J9tg5uraYoQKaWbmrzDDexbG6hHnMcWS1qLYgJSWE+mpA3U5OCSeMUhb+K55otgZJ34oFdR0ECvdIb3xuO5JOQ== + +linkify-it@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.1.0.tgz#c4caf38a6cd7ac2212ef3c7d2bde30a91561f9db" + integrity sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg== + dependencies: + uc.micro "^1.0.1" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-script@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/load-script/-/load-script-1.0.0.tgz#0491939e0bee5643ee494a7e3da3d2bac70c6ca4" + integrity sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ= + +loader-fs-cache@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz#56e0bf08bd9708b26a765b68509840c8dec9fdbc" + integrity sha1-VuC/CL2XCLJqdltoUJhAyN7J/bw= + dependencies: + find-cache-dir "^0.1.1" + mkdirp "0.5.1" + +loader-runner@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^0.2.16: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.0, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash._escapehtmlchar@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz#df67c3bb6b7e8e1e831ab48bfa0795b92afe899d" + integrity sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0= + dependencies: + lodash._htmlescapes "~2.4.1" + +lodash._escapestringchar@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz#ecfe22618a2ade50bfeea43937e51df66f0edb72" + integrity sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I= + +lodash._htmlescapes@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz#32d14bf0844b6de6f8b62a051b4f67c228b624cb" + integrity sha1-MtFL8IRLbeb4tioFG09nwii2JMs= + +lodash._isnative@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._isnative/-/lodash._isnative-2.4.1.tgz#3ea6404b784a7be836c7b57580e1cdf79b14832c" + integrity sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw= + +lodash._objecttypes@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz#7c0b7f69d98a1f76529f890b0cdb1b4dfec11c11" + integrity sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE= + +lodash._reinterpolate@^2.4.1, lodash._reinterpolate@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz#4f1227aa5a8711fc632f5b07a1f4607aab8b3222" + integrity sha1-TxInqlqHEfxjL1sHofRgequLMiI= + +lodash._reunescapedhtml@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz#747c4fc40103eb3bb8a0976e571f7a2659e93ba7" + integrity sha1-dHxPxAED6zu4oJduVx96JlnpO6c= + dependencies: + lodash._htmlescapes "~2.4.1" + lodash.keys "~2.4.1" + +lodash._shimkeys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203" + integrity sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= + +lodash.clonedeep@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.defaults@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-2.4.1.tgz#a7e8885f05e68851144b6e12a8f3678026bc4c54" + integrity sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ= + dependencies: + lodash._objecttypes "~2.4.1" + lodash.keys "~2.4.1" + +lodash.escape@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-2.4.1.tgz#2ce12c5e084db0a57dda5e5d1eeeb9f5d175a3b4" + integrity sha1-LOEsXghNsKV92l5dHu659dF1o7Q= + dependencies: + lodash._escapehtmlchar "~2.4.1" + lodash._reunescapedhtml "~2.4.1" + lodash.keys "~2.4.1" + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.isobject@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" + integrity sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash.keys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-2.4.1.tgz#48dea46df8ff7632b10d706b8acb26591e2b3727" + integrity sha1-SN6kbfj/djKxDXBrissmWR4rNyc= + dependencies: + lodash._isnative "~2.4.1" + lodash._shimkeys "~2.4.1" + lodash.isobject "~2.4.1" + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.mergewith@^4.6.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + +lodash.tail@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664" + integrity sha1-0jM6NtnncXyK0vfKyv7HwytERmQ= + +lodash.template@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-2.4.1.tgz#9e611007edf629129a974ab3c48b817b3e1cf20d" + integrity sha1-nmEQB+32KRKal0qzxIuBez4c8g0= + dependencies: + lodash._escapestringchar "~2.4.1" + lodash._reinterpolate "~2.4.1" + lodash.defaults "~2.4.1" + lodash.escape "~2.4.1" + lodash.keys "~2.4.1" + lodash.templatesettings "~2.4.1" + lodash.values "~2.4.1" + +lodash.templatesettings@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz#ea76c75d11eb86d4dbe89a83893bb861929ac699" + integrity sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk= + dependencies: + lodash._reinterpolate "~2.4.1" + lodash.escape "~2.4.1" + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash.values@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-2.4.1.tgz#abf514436b3cb705001627978cbcf30b1280eea4" + integrity sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ= + dependencies: + lodash.keys "~2.4.1" + +lodash@^4.0.0, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10: + version "4.17.14" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" + integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== + +log-driver@^1.2.7: + version "1.2.7" + resolved "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" + integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== + +log-symbols@2.2.0, log-symbols@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +log4js@^4.0.0: + version "4.0.2" + resolved "https://registry.npmjs.org/log4js/-/log4js-4.0.2.tgz#0c73e623ca4448669653eb0e9f629beacc7fbbe3" + integrity sha512-KE7HjiieVDPPdveA3bJZSuu0n8chMkFl8mIoisBFxwEJ9FmXe4YzNuiqSwYUiR1K8q8/5/8Yd6AClENY1RA9ww== + dependencies: + date-format "^2.0.0" + debug "^3.1.0" + flatted "^2.0.0" + rfdc "^1.1.2" + streamroller "^1.0.1" + +loglevel@^1.4.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" + integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po= + +loglevelnext@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.5.tgz#36fc4f5996d6640f539ff203ba819641680d75a2" + integrity sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A== + dependencies: + es6-symbol "^3.1.1" + object.assign "^4.1.0" + +lolex@^2.3.2: + version "2.7.5" + resolved "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733" + integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q== + +lolex@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/lolex/-/lolex-3.1.0.tgz#1a7feb2fefd75b3e3a7f79f0e110d9476e294434" + integrity sha512-zFo5MgCJ0rZ7gQg69S4pqBsLURbFw11X68C18OcJjJQbqaXm2NoTrGl1IMM3TIz0/BnN1tIs2tzmmqvCsOMMjw== + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0, loud-rejection@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + +lru-cache@4.1.x, lru-cache@^4.0.1, lru-cache@^4.1.2: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-stream@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.4.tgz#5ec6de90213ef6c7b2eb9367e9ade8da4efdb68b" + integrity sha1-XsbekCE+9sey65Nn6a3o2k79tos= + +map-stream@>=0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" + integrity sha1-ih8HiW2CsQkmvTdEokIACfiJdKg= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-it-anchor@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-5.0.2.tgz#cdd917a05b7bf92fb736a6dae3385c6d0d0fa552" + integrity sha512-AFM/woBI8QDJMS/9+MmsBMT5/AR+ImfOsunQZTZhzcTmna3rIzAzbOh5E0l6mlFM/i9666BpUtkqQ9bS7WApCg== + +markdown-it-chain@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/markdown-it-chain/-/markdown-it-chain-1.3.0.tgz#ccf6fe86c10266bafb4e547380dfd7f277cc17bc" + integrity sha512-XClV8I1TKy8L2qsT9iX3qiV+50ZtcInGXI80CA+DP62sMs7hXlyV/RM3hfwy5O3Ad0sJm9xIwQELgANfESo8mQ== + dependencies: + webpack-chain "^4.9.0" + +markdown-it-container@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-container/-/markdown-it-container-2.0.0.tgz#0019b43fd02eefece2f1960a2895fba81a404695" + integrity sha1-ABm0P9Au7+zi8ZYKKJX7qBpARpU= + +markdown-it@^8.4.1: + version "8.4.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" + integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ== + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +matchdep@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" + integrity sha1-xvNINKDY28OzfCfui7yyfHd1WC4= + dependencies: + findup-sync "^2.0.0" + micromatch "^3.0.4" + resolve "^1.4.0" + stack-trace "0.0.10" + +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdn-data@~1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" + integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA== + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= + dependencies: + mimic-fn "^1.0.0" + +mem@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" + integrity sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^1.0.0" + p-is-promise "^1.1.0" + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.3.0, meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +"mime-db@>= 1.36.0 < 2", mime-db@~1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" + integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19: + version "2.1.21" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" + integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== + dependencies: + mime-db "~1.37.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mime@^2.0.3, mime@^2.1.0, mime@^2.3.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6" + integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +mini-css-extract-plugin@^0.4.1: + version "0.4.5" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.5.tgz#c99e9e78d54f3fa775633aee5933aeaa4e80719a" + integrity sha512-dqBanNfktnp2hwL2YguV9Jh91PFX7gu7nRLs4TGsbAfAG6WOtlynFRYzwDwmmeSb5uIwHo9nx1ta0f7vAZVp2w== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.0.tgz#4dffe525dae2b864c66c2e23c6271d7afdecefce" + integrity sha1-Tf/lJdriuGTGbC4jxicdev3s784= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mixin-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" + integrity sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4= + dependencies: + for-in "^0.1.3" + is-extendable "^0.1.1" + +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mocha@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/mocha/-/mocha-6.0.2.tgz#cdc1a6fdf66472c079b5605bac59d29807702d2c" + integrity sha512-RtTJsmmToGyeTznSOMoM6TPEk1A84FQaHIciKrRqARZx+B5ccJ5tXlmJzEKGBxZdqk9UjpRsesZTUkZmR5YnuQ== + dependencies: + ansi-colors "3.2.3" + browser-stdout "1.3.1" + debug "3.2.6" + diff "3.5.0" + escape-string-regexp "1.0.5" + findup-sync "2.0.0" + glob "7.1.3" + growl "1.10.5" + he "1.2.0" + js-yaml "3.12.0" + log-symbols "2.2.0" + minimatch "3.0.4" + mkdirp "0.5.1" + ms "2.1.1" + node-environment-flags "1.0.4" + object.assign "4.1.0" + strip-json-comments "2.0.1" + supports-color "6.0.0" + which "1.3.1" + wide-align "1.1.3" + yargs "12.0.5" + yargs-parser "11.1.1" + yargs-unparser "1.5.0" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1, ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +multipipe@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= + dependencies: + duplexer2 "0.0.2" + +mute-stdout@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" + integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nan@^2.10.0, nan@^2.9.2: + version "2.12.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" + integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= + +neo-async@^2.5.0, neo-async@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +next-tick@1, next-tick@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +nise@^1.4.10: + version "1.4.10" + resolved "https://registry.npmjs.org/nise/-/nise-1.4.10.tgz#ae46a09a26436fae91a38a60919356ae6db143b6" + integrity sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA== + dependencies: + "@sinonjs/formatio" "^3.1.0" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + lolex "^2.3.2" + path-to-regexp "^1.7.0" + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-environment-flags@1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.4.tgz#0b784a6551426bfc16d3b2208424dcbc2b2ff038" + integrity sha512-M9rwCnWVLW7PX+NUWe3ejEdiLYinRpsEre9hMkU/6NS4h+EEulYaDH1gCEZ2gyXsmw+RXYDaV2JkkTNcsPDJ0Q== + dependencies: + object.getownpropertydescriptors "^2.0.3" + +node-forge@0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" + integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ== + +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-libs-browser@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.0.tgz#c72f60d9d46de08a940dedbb25f3ffa2f9bbaa77" + integrity sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "0.0.4" + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-releases@^1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.11.tgz#9a0841a4b0d92b7d5141ed179e764f42ad22724a" + integrity sha512-8v1j5KfP+s5WOTa1spNUAOfreajQPN12JXbRR0oDE+YrJBQCXBnNqUDj27EKpPLOoSiU3tKi3xGPB+JaOdUEQQ== + dependencies: + semver "^5.3.0" + +node-releases@^1.1.3: + version "1.1.8" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.8.tgz#32a63fff63c5e51b7e0f540ac95947d220fc6862" + integrity sha512-gQm+K9mGCiT/NXHy+V/ZZS1N/LOaGGqRAAJJs3X9Ah1g+CIbRcBgNyoNYQ+SEtcyAtB9KqDruu+fF7nWjsqRaA== + dependencies: + semver "^5.3.0" + +node-sass@^4.11.0, node-sass@^4.8.3: + version "4.11.0" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.11.0.tgz#183faec398e9cbe93ba43362e2768ca988a6369a" + integrity sha512-bHUdHTphgQJZaF1LASx0kAviPH7sGlcyNhWade4eVIpFp6tsn7SV8xNMTbsQFpEV9VXpnwTTnNYlfsZXgGgmkA== + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash.assign "^4.2.0" + lodash.clonedeep "^4.3.2" + lodash.mergewith "^4.6.0" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.10.0" + node-gyp "^3.8.0" + npmlog "^4.0.0" + request "^2.88.0" + sass-graph "^2.2.4" + stdout-stream "^1.4.0" + "true-case-path" "^1.0.2" + +"nopt@2 || 3", nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +normalize-wheel@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45" + integrity sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU= + +now-and-later@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee" + integrity sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4= + dependencies: + once "^1.3.2" + +npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== + +npm-packlist@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.2.0.tgz#55a60e793e272f00862c7089274439a4cc31fc7f" + integrity sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@^1.0.2, nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +null-check@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" + integrity sha1-l33/1xdgErnsMNKjnbXPcqBDnt0= + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@^1.1.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@~1.0.0: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@4.1.0, object.assign@^4.0.1, object.assign@^4.0.4, object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.defaults@^1.0.0, object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8= + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc= + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.reduce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" + integrity sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60= + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.values@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" + integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.12.0" + function-bind "^1.1.1" + has "^1.0.3" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" + integrity sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c= + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +opn@^5.1.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" + integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== + dependencies: + is-wsl "^1.1.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optimize-css-assets-webpack-plugin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.1.tgz#9eb500711d35165b45e7fd60ba2df40cb3eb9159" + integrity sha512-Rqm6sSjWtx9FchdP0uzTQDc7GXDKnwVEGoSxjezPkzMewx7gEWE9IMUYKmigTRC4U3RaNSwYVnUDLuIdtTpm0A== + dependencies: + cssnano "^4.1.0" + last-call-webpack-plugin "^3.0.0" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + integrity sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4= + dependencies: + readable-stream "^2.0.1" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-locale@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0, osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +output-file-sync@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + integrity sha1-0KM+7+YaIF+suQCS6CZZjVJFznY= + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68" + integrity sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + +pako@~1.0.5: + version "1.0.8" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.8.tgz#6844890aab9c635af868ad5fecc62e8acbba3ea4" + integrity sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA== + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + dependencies: + no-case "^2.2.0" + +parse-asn1@^5.0.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.3.tgz#1600c6cc0727365d68b97f3aa78939e735a75204" + integrity sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-node-version@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.0.tgz#33d9aa8920dcc3c0d33658ec18ce237009a56d53" + integrity sha512-02GTVHD1u0nWc20n2G7WX/PgdhNFG04j5fi1OkaJzPWLTcf6vh6229Lta1wTmXG/7Dg42tCssgkccVt7qvd8Kg== + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= + dependencies: + path-root-regex "^0.1.0" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + dependencies: + isarray "0.0.1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pathval@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== + +portfinder@^1.0.9: + version "1.0.20" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a" + integrity sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw== + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-calc@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.1.tgz#36d77bab023b0ecbb9789d84dcb23c4941145436" + integrity sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ== + dependencies: + css-unit-converter "^1.1.1" + postcss "^7.0.5" + postcss-selector-parser "^5.0.0-rc.4" + postcss-value-parser "^3.3.1" + +postcss-colormin@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== + dependencies: + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-convert-values@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-discard-comments@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== + dependencies: + postcss "^7.0.0" + +postcss-discard-duplicates@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== + dependencies: + postcss "^7.0.0" + +postcss-discard-empty@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== + dependencies: + postcss "^7.0.0" + +postcss-discard-overridden@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== + dependencies: + postcss "^7.0.0" + +postcss-merge-longhand@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== + dependencies: + css-color-names "0.0.4" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" + +postcss-merge-rules@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + vendors "^1.0.0" + +postcss-minify-font-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-params@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== + dependencies: + alphanum-sort "^1.0.0" + browserslist "^4.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== + dependencies: + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.5.tgz#7f387f68f5555598068e4d6d1ea0b7d6fa984272" + integrity sha512-iFgxlCAVLno5wIJq+4hyuOmc4VjZEZxzpdeuZcBytLNWEK5Bx2oRF9PPcAz5TALbaFvrZm8sJYtJ3hV+tMSEIg== + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^7.0.6" + postcss-value-parser "^3.3.1" + +postcss-modules-scope@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.0.1.tgz#2c0f2394cde4cd09147db054c68917e38f6d43a4" + integrity sha512-7+6k9c3/AuZ5c596LJx9n923A/j3nF3ormewYBF1RrIQvjvjXe1xE8V8A1KFyFwXbvnshT6FBZFX0k/F1igneg== + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^7.0.6" + +postcss-modules-values@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz#479b46dc0c5ca3dc7fa5270851836b9ec7152f64" + integrity sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w== + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^7.0.6" + +postcss-normalize-charset@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== + dependencies: + postcss "^7.0.0" + +postcss-normalize-display-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-whitespace@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-ordered-values@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-reduce-initial@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + +postcss-reduce-transforms@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-selector-parser@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865" + integrity sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU= + dependencies: + dot-prop "^4.1.1" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^5.0.0, postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" + integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== + dependencies: + is-svg "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== + dependencies: + alphanum-sort "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.14" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.14.tgz#4527ed6b1ca0d82c53ce5ec1a2041c2346bbd6e5" + integrity sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +prettier@1.16.3: + version "1.16.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.3.tgz#8c62168453badef702f34b45b6ee899574a6a65d" + integrity sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw== + +pretty-error@^2.0.2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" + integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= + dependencies: + renderkid "^2.0.1" + utila "~0.4" + +pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + +progress-bar-webpack-plugin@^1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/progress-bar-webpack-plugin/-/progress-bar-webpack-plugin-1.11.0.tgz#4f801288443c55ec029b20cbfdcbf3e1dc17f852" + integrity sha512-XT6r8strD6toU0ZVip25baJINo7uE4BD4H8d4vhOV4GIK5PvNNky8GYJ2wMmVoYP8eo/sSmtNWn0Vw7zWDDE3A== + dependencies: + chalk "^1.1.1" + object.assign "^4.0.1" + progress "^1.1.8" + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +proxy-addr@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.8.0" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.24: + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3, pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qjobs@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.5.2, qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystring-es3@^0.2.0, querystring-es3@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef" + integrity sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg== + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.0.3, range-parser@^1.2.0, range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@1.0, readable-stream@~1.0.17: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^3.0.6: + version "3.1.1" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06" + integrity sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readdirp@^2.0.0, readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +reduce@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/reduce/-/reduce-1.0.1.tgz#14fa2e5ff1fc560703a020cbb5fbaab691565804" + integrity sha1-FPouX/H8VgcDoCDLtfuqtpFWWAQ= + dependencies: + object-keys "~1.0.0" + +regenerate@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpu-core@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" + integrity sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= + dependencies: + jsesc "~0.5.0" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remove-bom-buffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" + integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== + dependencies: + is-buffer "^1.1.5" + is-utf8 "^0.2.1" + +remove-bom-stream@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" + integrity sha1-BfGlk/FuQuH7kOv1nejlaVJflSM= + dependencies: + remove-bom-buffer "^3.0.0" + safe-buffer "^5.1.0" + through2 "^2.0.3" + +remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +renderkid@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.2.tgz#12d310f255360c07ad8fde253f6c9e9de372d2aa" + integrity sha512-FsygIxevi1jSiPY9h7vZmBFUbAOcbYm9UwyiLNdVsLRs/5We9Ob5NMPbGYUTWiLq5L+ezlVdE0A8bbME5CWTpg== + dependencies: + css-select "^1.1.0" + dom-converter "~0.2" + htmlparser2 "~3.3.0" + strip-ansi "^3.0.0" + utila "^0.4.0" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +replace-homedir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" + integrity sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw= + dependencies: + homedir-polyfill "^1.0.1" + is-absolute "^1.0.0" + remove-trailing-separator "^1.1.0" + +request@^2.86.0, request@^2.87.0, request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resize-observer-polyfill@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-options@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" + integrity sha1-MrueOcBtZzONyTeMDW1gdFZq0TE= + dependencies: + value-or-function "^3.0.0" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.2.0, resolve@^1.4.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" + integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rfdc@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.1.2.tgz#e6e72d74f5dc39de8f538f65e00c36c18018e349" + integrity sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA== + +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= + +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= + +rxjs@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" + integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-graph@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" + integrity sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k= + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^7.0.0" + +sass-loader@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-7.1.0.tgz#16fd5138cb8b424bf8a759528a1972d72aad069d" + integrity sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w== + dependencies: + clone-deep "^2.0.1" + loader-utils "^1.0.1" + lodash.tail "^4.1.1" + neo-async "^2.5.0" + pify "^3.0.0" + semver "^5.5.0" + +sax@^1.2.4, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^0.4.4, schema-utils@^0.4.5: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +select-version-cli@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/select-version-cli/-/select-version-cli-0.0.2.tgz#11f626f95cf7a4e2ddd59d66f51f6a5aedac87c0" + integrity sha512-1eKBU5kDoXmmkMAhZUa2L7fVb+lH4wfDKONSsfc9cQuVYmCzXtO14wijuHlFrx+2+/igmxlv5tt439726gfPaA== + dependencies: + commander "^2.19.0" + inquirer "^6.2.2" + semver "^5.6.0" + +selfsigned@^1.9.1: + version "1.10.4" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd" + integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw== + dependencies: + node-forge "0.7.5" + +semver-greatest-satisfied-range@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" + integrity sha1-E+jCZYq5aRywzXEJMkAoDTb3els= + dependencies: + sver-compat "^1.5.0" + +"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +serialize-javascript@^1.4.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.6.1.tgz#4d1f697ec49429a847ca6f442a2a755126c4d879" + integrity sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw== + +serve-index@^1.7.2: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallow-clone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-1.0.0.tgz#4480cd06e882ef68b2ad88a3ea54832e2c48b571" + integrity sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA== + dependencies: + is-extendable "^0.1.1" + kind-of "^5.0.0" + mixin-object "^2.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +sinon-chai@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.3.0.tgz#8084ff99451064910fbe2c2cb8ab540c00b740ea" + integrity sha512-r2JhDY7gbbmh5z3Q62pNbrjxZdOAjpsqW/8yxAZRSqLZqowmfGZPGUZPFf3UX36NLis0cv8VEM5IJh9HgkSOAA== + +sinon@^7.2.7: + version "7.2.7" + resolved "https://registry.npmjs.org/sinon/-/sinon-7.2.7.tgz#ee90f83ce87d9a6bac42cf32a3103d8c8b1bfb68" + integrity sha512-rlrre9F80pIQr3M36gOdoCEWzFAMDgHYD8+tocqOw+Zw9OZ8F84a80Ds69eZfcjnzDqqG88ulFld0oin/6rG/g== + dependencies: + "@sinonjs/commons" "^1.3.1" + "@sinonjs/formatio" "^3.2.1" + "@sinonjs/samsam" "^3.2.0" + diff "^3.5.0" + lolex "^3.1.0" + nise "^1.4.10" + supports-color "^5.5.0" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b" + integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs= + +socket.io-client@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f" + integrity sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~3.1.0" + engine.io-client "~3.2.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.2.0" + to-array "0.1.4" + +socket.io-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077" + integrity sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980" + integrity sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA== + dependencies: + debug "~3.1.0" + engine.io "~3.2.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.1.1" + socket.io-parser "~3.2.0" + +sockjs-client@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177" + integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg== + dependencies: + debug "^3.2.5" + eventsource "^1.0.7" + faye-websocket "~0.11.1" + inherits "^2.0.3" + json3 "^3.3.2" + url-parse "^1.4.3" + +sockjs@0.3.19: + version "0.3.19" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" + integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.0.1" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@~0.5.6: + version "0.5.10" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.10.tgz#2214080bc9d51832511ee2bab96e3c2f9353120c" + integrity sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@0.4.x, source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + +sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" + integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.0.tgz#81f222b5a743a329aa12cea6a390e60e9b613c52" + integrity sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de" + integrity sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stable@~0.1.6: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stack-trace@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +stdout-stream@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" + integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== + dependencies: + readable-stream "^2.0.1" + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds= + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-exhaust@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" + integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +streamroller@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/streamroller/-/streamroller-1.0.3.tgz#cb51e7e382f799a9381a5d7490ce3053b325fba3" + integrity sha512-P7z9NwP51EltdZ81otaGAN3ob+/F88USJE546joNq7bqRNTe6jc74fTBDyynxP4qpIfKlt/CesEYicuMzI0yJg== + dependencies: + async "^2.6.1" + date-format "^2.0.0" + debug "^3.1.0" + fs-extra "^7.0.0" + lodash "^4.17.10" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" + integrity sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA= + dependencies: + ansi-regex "^0.2.1" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" + integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== + dependencies: + ansi-regex "^4.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +style-loader@^0.23.1: + version "0.23.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" + integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + +stylehacks@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +supports-color@6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== + dependencies: + has-flag "^3.0.0" + +supports-color@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" + integrity sha1-2S3iaU6z9nMjlz1649i1W0wiGQo= + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +sver-compat@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" + integrity sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg= + dependencies: + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +svgo@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.1.1.tgz#12384b03335bcecd85cfa5f4e3375fed671cb985" + integrity sha512-GBkJbnTuFpM4jFbiERHDWhZc/S/kpHToqmZag3aEBjPYK44JAN2QBjvrGIxLOoCyMZjuFQIfTO2eJd8uwLY/9g== + dependencies: + coa "~2.0.1" + colors "~1.1.2" + css-select "^2.0.0" + css-select-base-adapter "~0.1.0" + css-tree "1.0.0-alpha.28" + css-url-regex "^1.1.0" + csso "^3.5.0" + js-yaml "^3.12.0" + mkdirp "~0.5.1" + object.values "^1.0.4" + sax "~1.2.4" + stable "~0.1.6" + unquote "~1.1.1" + util.promisify "~1.0.0" + +table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + integrity sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA== + dependencies: + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.1.tgz#4d297923c5a72a42360de2ab52dadfaaec00018e" + integrity sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA== + +tar@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tar@^4: + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +temp-write@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-0.1.1.tgz#0b6467838dd77fbf7f62a0c93da879732ffda932" + integrity sha1-C2Rng43Xf79/YqDJPah5cy/9qTI= + dependencies: + graceful-fs "~2.0.0" + tempfile "~0.1.2" + +tempfile@~0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-0.1.3.tgz#7d6b710047339d39f847327a056dadf183103010" + integrity sha1-fWtxAEcznTn4RzJ6BW2t8YMQMBA= + dependencies: + uuid "~1.4.0" + +terser-webpack-plugin@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.1.tgz#7545da9ae5f4f9ae6a0ac961eb46f5e7c845cc26" + integrity sha512-GGSt+gbT0oKcMDmPx4SRSfJPE1XaN3kQRWG4ghxKQw9cn5G9x6aCKSsgYdvyM0na9NJ4Drv0RG6jbBByZ5CMjw== + dependencies: + cacache "^11.0.2" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + terser "^3.8.1" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +terser@^3.8.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.14.1.tgz#cc4764014af570bc79c79742358bd46926018a32" + integrity sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + source-map-support "~0.5.6" + +test-exclude@^4.2.1: + version "4.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" + integrity sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA== + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +throttle-debounce@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-1.1.0.tgz#51853da37be68a155cb6e827b3514a3c422e89cd" + integrity sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg== + +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.5.1.tgz#dfdd012eb9c700e2323fd334f38ac622ab372da7" + integrity sha1-390BLrnHAOIyP9M084rGIqs3Lac= + dependencies: + readable-stream "~1.0.17" + xtend "~3.0.0" + +through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6, through@~2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunky@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826" + integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow== + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + dependencies: + setimmediate "^1.0.4" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + integrity sha1-GGX0PZ50sIItufFFt4z/fQ98hJs= + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +to-through@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" + integrity sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY= + dependencies: + through2 "^2.0.3" + +toposort@^1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" + integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +transliteration@^1.1.11: + version "1.6.6" + resolved "https://registry.yarnpkg.com/transliteration/-/transliteration-1.6.6.tgz#8a7e8ab3044ad19f233f50c15894cbf69e5d205e" + integrity sha1-in6KswRK0Z8jP1DBWJTL9p5dIF4= + dependencies: + yargs "^12.0.1" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +"true-case-path@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" + integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== + dependencies: + glob "^7.1.2" + +tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.5.tgz#0c65f15f815aa08b560a61ce8b4db7ffc3f45376" + integrity sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg== + +uglify-js@3.4.x, uglify-js@^3.0.0: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + +uglify-js@^3.1.4: + version "3.6.0" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5" + integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg== + dependencies: + commander "~2.20.0" + source-map "~0.6.1" + +uglifyjs-webpack-plugin@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-2.1.1.tgz#6937d7513a37280d4792f1fb536bef35e08e420a" + integrity sha512-TQEcyMNkObX/H+FfcKjiDgs5RcXX8vW2UUUrDTOfQgg3lrafztfeM5WAwXo+AzqozJK6NP9w98xNpG/dutzSsg== + dependencies: + cacache "^11.2.0" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-js "^3.0.0" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + +undertaker-registry@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" + integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA= + +undertaker@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.2.0.tgz#339da4646252d082dc378e708067299750e11b49" + integrity sha1-M52kZGJS0ILcN45wgGcpl1DhG0k= + dependencies: + arr-flatten "^1.0.1" + arr-map "^2.0.0" + bach "^1.0.0" + collection-map "^1.0.0" + es6-weak-map "^2.0.1" + last-run "^1.1.0" + object.defaults "^1.0.0" + object.reduce "^1.0.0" + undertaker-registry "^1.0.0" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6" + integrity sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg== + dependencies: + imurmurhash "^0.1.4" + +unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== + +upath@^1.1.0: + version "1.1.2" + resolved "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + +uppercamelcase@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/uppercamelcase/-/uppercamelcase-1.1.0.tgz#324d98a6b3afc7e8a8953e10641509b0e4e23f97" + integrity sha1-Mk2YprOvx+iolT4QZBUJsOTiP5c= + dependencies: + camelcase "^1.2.1" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-join@^2.0.2: + version "2.0.5" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728" + integrity sha1-WvIvGMBSoACkjXuCxenC4v7tpyg= + +url-loader@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8" + integrity sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg== + dependencies: + loader-utils "^1.1.0" + mime "^2.0.3" + schema-utils "^1.0.0" + +url-parse@^1.4.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8" + integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg== + dependencies: + querystringify "^2.0.0" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA= + +useragent@2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972" + integrity sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw== + dependencies: + lru-cache "4.1.x" + tmp "0.0.x" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@1.0.0, util.promisify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@^0.4.0, utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.0.1, uuid@^3.1.0, uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +uuid@~1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-1.4.2.tgz#453019f686966a6df83cdc5244e7c990ecc332fc" + integrity sha1-RTAZ9oaWam34PNxSROfJkOzDMvw= + +v8-compile-cache@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" + integrity sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw== + +v8flags@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + integrity sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ= + dependencies: + user-home "^1.1.1" + +v8flags@^3.0.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.2.tgz#fc5cd0c227428181e6c29b2992e4f8f1da5e0c9f" + integrity sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw== + dependencies: + homedir-polyfill "^1.0.1" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +value-or-function@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" + integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.2.tgz#7fcb5eef9f5623b156bcea89ec37d63676f21801" + integrity sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-fs@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" + integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== + dependencies: + fs-mkdirp-stream "^1.0.0" + glob-stream "^6.1.0" + graceful-fs "^4.0.0" + is-valid-glob "^1.0.0" + lazystream "^1.0.0" + lead "^1.0.0" + object.assign "^4.0.4" + pumpify "^1.3.5" + readable-stream "^2.3.3" + remove-bom-buffer "^3.0.0" + remove-bom-stream "^1.2.0" + resolve-options "^1.1.0" + through2 "^2.0.0" + to-through "^2.0.0" + value-or-function "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemap "^1.1.0" + +vinyl-sourcemap@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" + integrity sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY= + dependencies: + append-buffer "^1.0.2" + convert-source-map "^1.5.0" + graceful-fs "^4.1.6" + normalize-path "^2.1.1" + now-and-later "^2.0.0" + remove-bom-buffer "^3.0.0" + vinyl "^2.0.0" + +vinyl-sourcemaps-apply@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + integrity sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU= + dependencies: + source-map "^0.5.1" + +vinyl@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.2.3.tgz#bca938209582ec5a49ad538a00fa1f125e513252" + integrity sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI= + dependencies: + clone-stats "~0.0.1" + +vinyl@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= + dependencies: + indexof "0.0.1" + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + +vscode-json-languageservice@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.2.1.tgz#991d51128ebd81c5525d0578cabfa5b03e3cba2a" + integrity sha512-ee9MJ70/xR55ywvm0bZsDLhA800HCRE27AYgMNTU14RSg20Y+ngHdQnUt6OmiTXrQDI/7sne6QUOtHIN0hPQYA== + dependencies: + jsonc-parser "^2.0.2" + vscode-languageserver-types "^3.13.0" + vscode-nls "^4.0.0" + vscode-uri "^1.0.6" + +vscode-languageserver-types@^3.13.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" + integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== + +vscode-nls@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002" + integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw== + +vscode-uri@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.6.tgz#6b8f141b0bbc44ad7b07e94f82f168ac7608ad4d" + integrity sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww== + +vue-hot-reload-api@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz#b2d3d95402a811602380783ea4f566eb875569a2" + integrity sha512-AA86yKZ5uOKz87/q1UpngEXhbRkaYg1b7HMMVRobNV1IVKqZe8oLIzo6iMocVwZXnYitlGwf2k4ZRLOZlS8oPQ== + +vue-loader@^15.7.0: + version "15.7.0" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.7.0.tgz#27275aa5a3ef4958c5379c006dd1436ad04b25b3" + integrity sha512-x+NZ4RIthQOxcFclEcs8sXGEWqnZHodL2J9Vq+hUz+TDZzBaDIh1j3d9M2IUlTjtrHTZy4uMuRdTi8BGws7jLA== + dependencies: + "@vue/component-compiler-utils" "^2.5.1" + hash-sum "^1.0.2" + loader-utils "^1.1.0" + vue-hot-reload-api "^2.3.0" + vue-style-loader "^4.1.0" + +vue-router@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.2.tgz#dedc67afe6c4e2bc25682c8b1c2a8c0d7c7e56be" + integrity sha512-opKtsxjp9eOcFWdp6xLQPLmRGgfM932Tl56U9chYTnoWqKxQ8M20N7AkdEbM5beUh6wICoFGYugAX9vQjyJLFg== + +vue-style-loader@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8" + integrity sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ== + dependencies: + hash-sum "^1.0.2" + loader-utils "^1.0.2" + +vue-template-compiler@2.5.21: + version "2.5.21" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.21.tgz#a57ceb903177e8f643560a8d639a0f8db647054a" + integrity sha512-Vmk5Cv7UcmI99B9nXJEkaK262IQNnHp5rJYo+EwYpe2epTAXqcVyExhV6pk8jTkxQK2vRc8v8KmZBAwdmUZvvw== + dependencies: + de-indent "^1.0.2" + he "^1.1.0" + +vue-template-es2015-compiler@^1.6.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.8.1.tgz#e2ec4f42d16b6c712e61899c6b20bcdb1df128ca" + integrity sha512-mxBBMuSaPG9+NkVMbh28r8gvWQJ8UXxqDxVNeLy2KBUZiSNxZsagjYwLL8gjROb4oaaYtwRv3K8gAmw76I/U7Q== + +vue-template-es2015-compiler@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" + integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== + +vue@2.5.21: + version "2.5.21" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85" + integrity sha512-Aejvyyfhn0zjVeLvXd70h4hrE4zZDx1wfZqia6ekkobLmUZ+vNFQer53B4fu0EjWBSiqApxPejzkO1Znt3joxQ== + +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-chain@^4.9.0: + version "4.12.1" + resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-4.12.1.tgz#6c8439bbb2ab550952d60e1ea9319141906c02a6" + integrity sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ== + dependencies: + deepmerge "^1.5.2" + javascript-stringify "^1.6.0" + +webpack-cli@^3.0.8: + version "3.2.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.2.1.tgz#779c696c82482491f0803907508db2e276ed3b61" + integrity sha512-jeJveHwz/vwpJ3B8bxEL5a/rVKIpRNJDsKggfKnxuYeohNDW4Y/wB9N/XHJA093qZyS0r6mYL+/crLsIol4WKA== + dependencies: + chalk "^2.4.1" + cross-spawn "^6.0.5" + enhanced-resolve "^4.1.0" + findup-sync "^2.0.0" + global-modules "^1.0.0" + global-modules-path "^2.3.0" + import-local "^2.0.0" + interpret "^1.1.0" + lightercollective "^0.1.0" + loader-utils "^1.1.0" + supports-color "^5.5.0" + v8-compile-cache "^2.0.2" + yargs "^12.0.4" + +webpack-dev-middleware@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz#1132fecc9026fd90f0ecedac5cbff75d1fb45890" + integrity sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA== + dependencies: + memory-fs "~0.4.1" + mime "^2.3.1" + range-parser "^1.0.3" + webpack-log "^2.0.0" + +webpack-dev-middleware@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz#a51692801e8310844ef3e3790e1eacfe52326fd4" + integrity sha512-tj5LLD9r4tDuRIDa5Mu9lnY2qBBehAITv6A9irqXhw/HQquZgTx3BCd57zYbU2gMDnncA49ufK2qVQSbaKJwOw== + dependencies: + loud-rejection "^1.6.0" + memory-fs "~0.4.1" + mime "^2.1.0" + path-is-absolute "^1.0.0" + range-parser "^1.0.3" + url-join "^2.0.2" + webpack-log "^1.0.1" + +webpack-dev-server@^3.1.11: + version "3.1.14" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.14.tgz#60fb229b997fc5a0a1fc6237421030180959d469" + integrity sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.0.0" + compression "^1.5.2" + connect-history-api-fallback "^1.3.0" + debug "^3.1.0" + del "^3.0.0" + express "^4.16.2" + html-entities "^1.2.0" + http-proxy-middleware "~0.18.0" + import-local "^2.0.0" + internal-ip "^3.0.1" + ip "^1.1.5" + killable "^1.0.0" + loglevel "^1.4.1" + opn "^5.1.0" + portfinder "^1.0.9" + schema-utils "^1.0.0" + selfsigned "^1.9.1" + semver "^5.6.0" + serve-index "^1.7.2" + sockjs "0.3.19" + sockjs-client "1.3.0" + spdy "^4.0.0" + strip-ansi "^3.0.0" + supports-color "^5.1.0" + url "^0.11.0" + webpack-dev-middleware "3.4.0" + webpack-log "^2.0.0" + yargs "12.0.2" + +webpack-log@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-1.2.0.tgz#a4b34cda6b22b518dbb0ab32e567962d5c72a43d" + integrity sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA== + dependencies: + chalk "^2.1.0" + log-symbols "^2.1.0" + loglevelnext "^1.0.1" + uuid "^3.1.0" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-node-externals@^1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" + integrity sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg== + +webpack-sources@^1.1.0, webpack-sources@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.14.0: + version "4.29.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.29.0.tgz#f2cfef83f7ae404ba889ff5d43efd285ca26e750" + integrity sha512-pxdGG0keDBtamE1mNvT5zyBdx+7wkh6mh7uzMOo/uRQ/fhsdj5FXkh/j5mapzs060forql1oXqXN9HJGju+y7w== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/wasm-edit" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + acorn "^6.0.5" + acorn-dynamic-import "^4.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.4" + tapable "^1.1.0" + terser-webpack-plugin "^1.1.0" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + +websocket-driver@>=0.5.1: + version "0.7.0" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" + integrity sha1-DK+dLXVdk67gSdS90NP+LMoqJOs= + dependencies: + http-parser-js ">=0.4.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1, which@1.3.1, which@^1.1.1, which@^1.2.1, which@^1.2.14, which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@1.1.3, wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +wordwrap@^1.0.0, wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ== + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= + dependencies: + mkdirp "^0.5.1" + +ws@~3.3.1: + version "3.3.3" + resolved "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + +xregexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" + integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg== + +xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +xtend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" + integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo= + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yargs-parser@11.1.1, yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= + dependencies: + camelcase "^3.0.0" + +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= + dependencies: + camelcase "^4.1.0" + +yargs-unparser@1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d" + integrity sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw== + dependencies: + flat "^4.1.0" + lodash "^4.17.11" + yargs "^12.0.5" + +yargs@11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.0.0.tgz#c052931006c5eee74610e5fc0354bedfd08a201b" + integrity sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw== + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + +yargs@12.0.2: + version "12.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" + integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ== + dependencies: + cliui "^4.0.0" + decamelize "^2.0.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^10.1.0" + +yargs@12.0.5, yargs@^12.0.1, yargs@^12.0.4, yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + +yargs@^7.0.0, yargs@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=