Compare commits

..

4 Commits
v2.7.2 ... next

Author SHA1 Message Date
hetech
799c42d337 Select: not toggle dropdown when filtering (#12210) 2019-03-27 18:28:18 +08:00
Jikkai Xiao
ef33295a54 Timeline: add timeline component (#11736)
* Timeline: add timeline component

* Timeline: add timeline component

* Timeline: add test case

* Timeline: fix icon class

* Timeline: update docs

* Timeline: fix test case

* Timeline: remove pending attribute

* Timeline: fix docs

* Timeline: make reverse default to false

* Timline: fix test case

* Timeline: update element-ui.d.ts

* Timeline: optimize code
2018-08-28 17:18:21 +08:00
Jikkai Xiao
c71ad7f471 Table: fix params order of row events (#12086) 2018-08-28 17:18:21 +08:00
Jikkai Xiao
8cf15eda72 Chore: upgrade to webpack@4 (#11954)
* Chore: upgrade webpack@4

* Chore: upgrade to webpack@4

* Chore: add babel-preset-stage-2

* Chore: fix test case

* Chore: upgrade webpack@4

* Docs: update docs

* Docs: update docs

* Chore: fix coveralls

* Chore: update yarn.lock
2018-08-28 17:18:20 +08:00
505 changed files with 21254 additions and 34991 deletions

View File

@@ -15,18 +15,6 @@
"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"],

View File

@@ -1,6 +1,10 @@
{
"env": {
"mocha": true
},
"globals": {
"ga": true
"expect": true,
"sinon": true
},
"plugins": ["html", "json"],
"extends": "elemefe",

View File

@@ -43,8 +43,6 @@ 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, get result, more quickly and friendly.
To build:
```shell

View File

@@ -37,7 +37,7 @@ Estamos orgullosos de que usted esta interesado en contribuir al proyecto `Eleme
- 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
## 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
@@ -47,8 +47,6 @@ 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, get result, more quickly and friendly.
Para armar:
```

View File

@@ -1,60 +0,0 @@
# 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, regardez le résultat rapidement et facilement.
Pour le build:
```shell
npm run dist
```
## Concernant le développement de composants
- Exécutez `make new <nom-du-composant>` 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).

View File

@@ -41,8 +41,6 @@ npm run dev
# open http://localhost:8085
```
> **提示**:可以运行 `npm run dev:play`,修改 `examples/play/index.vue` 文件,调用你修改后的组件,仍然访问 http://localhost:8085查看修改效果更快更方便。
打包代码:
```shell

View File

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

17
.github/stale.yml vendored
View File

@@ -1,17 +0,0 @@
# 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

5
.gitignore vendored
View File

@@ -1,12 +1,8 @@
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
@@ -15,7 +11,6 @@ examples/element-ui
examples/pages/en-US
examples/pages/zh-CN
examples/pages/es
examples/pages/fr-FR
fe.element/element-ui
.npmrc
coverage

View File

@@ -1,9 +1,10 @@
sudo: false
language: node_js
node_js: 10
addons:
chrome: stable
node_js: lts/*
before_install:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- 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)"

View File

@@ -1,423 +1,5 @@
## Changelog
### 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)
### 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 fileadd 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*
@@ -444,7 +26,7 @@
- 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 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
@@ -521,7 +103,7 @@
- Added `precision` attribute, #11281
- Tabs
- Added `before-leave` attribute, #11259
- Added `lazy` attribute, #11167(by @Kingwl)
- Added `lazy` attribute, #11167by @Kingwl
- Table
- Added `sort` method to manually sort the table, #11311
@@ -570,7 +152,7 @@
- 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 'clearValidate` method for FormItem, #11076
- Added `checkOnClickNode` attribute for Tree, #11111
### 2.3.7
@@ -676,7 +258,7 @@
- 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)
- Now the date and time value in the dropdown panel are correctly formatted based on the `format` attribute, #10174by @remizovvv
- Upload
- Fixed `accept` attribute not working when `drag` is true, #10278
@@ -769,7 +351,7 @@
- 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 an error in calculating number of fixed columns after the column data changes, #9188by @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
@@ -1078,4 +660,4 @@
- The params of `row-class-name` and `row-style` method is now an object
##
<i><sup>*</sup> 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.</i>
<i><sup>*</sup> 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.</i>

View File

@@ -1,414 +1,5 @@
## Changelog
### 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
- Agregado soporte de datos con estructura tree (#14632 by @ziyoung)
#### Bug fixes
- 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)
#### Optimization
- Chore
- Añadido descripción de la página web (#14802 by @iamkun)
### 2.6.3
*2019-03-21*
#### Bug fixes
- 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*
#### New features
- 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)
#### Bug fixes
- 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)
#### Optimization
- 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*
#### Bug fixes
- **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*
#### New features
- 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)
#### Optimization
- 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)
#### Bug fixes
- 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)
### 2.5.4
*2019-02-01*
#### Bug fixes
- 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*
#### Optimization
- 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)
#### Bug fixes
- 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)
#### Bug fixes
### 2.5.2
*2019-01-27*
#### Optimization
- Docs:
- Actualizacion ChangeLog ES 2.5.1 (by @Gonzalo2310 in #14231)
#### Bug fixes
- 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*
#### Optimization
- DatePicker: resalta el mes y año actual (por @Debiancc en #14211)
- Actualizacion del changelog 2.5.0 (por @wacky6 en #14217)
#### Bug fixes
- 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*
#### Bug fixes
- 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*
@@ -435,7 +26,7 @@
- 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
- 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
@@ -698,7 +289,7 @@
- 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
- 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
@@ -725,15 +316,13 @@
- 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
@@ -1057,7 +646,7 @@
- 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.
- 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`
@@ -1076,4 +665,4 @@
# #
<i><sup>*</sup> 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.</i>``
<i><sup>*</sup> 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.</i>

File diff suppressed because it is too large Load Diff

View File

@@ -1,424 +1,5 @@
## 更新日志
### 2.7.2
*2019-04-03*
#### Bug fixes
- Form
- 修复 `label-width``auto` 的样式 (#14955 by @ziyoung)
#### Optimization
- 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)
#### 优化
- 文档
- 更新西班牙语文档 (#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)
### 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
- 调整 SelectProgressAutocompleteTooltipCollaspeTimePicker 的样式,#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 来自定义表头,#13012by @ivanseidel
- 修复 IE 下 Select 输入框不能输入的问题,#13034by @GaliMU
- Select 多选时,选项不换行,#12329 by @akki-jat
- Select 下拉列表展开后,箭头图标也可以正确显示,#12353by @firesh
- 修复 Select 的 size 属性不生效的问题,#13070
- 多选时可以清除 Select 已选中的值,#13049by @ZSkycat
- 修复最后一个 TabNav 不能删除的问题,#13039
- 修复 TabNav 中 label 显示不正确的问题,#13178
- Alert 新增 title slot#13082by @Kingwl
- 修复 Table 中的 tooltip 内容不正确的问题,#13159by @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*
@@ -1079,4 +660,4 @@
- `row-class-name``row-style` 的函数参数改为对象,以保证 API 的一致性
##
<i><sup>*</sup> 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 [XSS 攻击](https://en.wikipedia.org/wiki/Cross-site_scripting)。因此请在 `dangerouslyUseHTMLString` 打开的情况下,确保 `message` 的内容是可信的,**永远不要**将用户提交的内容赋值给 `message` 属性。</i>
<i><sup>*</sup> 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 [XSS 攻击](https://en.wikipedia.org/wiki/Cross-site_scripting)。因此请在 `dangerouslyUseHTMLString` 打开的情况下,确保 `message` 的内容是可信的,**永远不要**将用户提交的内容赋值给 `message` 属性。</i>

View File

@@ -47,6 +47,11 @@
<img width="150px" src="https://user-images.githubusercontent.com/1016365/34124854-48fafa06-e3e9-11e7-8c04-251055feebee.png">
</a>
</td>
<td align="center" valign="middle">
<a href="https://www.duotai.cn/?utm_source=element" target="_blank">
<img width="140px" src="https://user-images.githubusercontent.com/10095631/39403151-c42dbcee-4ba5-11e8-9c09-8e5283da4144.png">
</a>
</td>
<td align="center" valign="middle">
<a href="https://www.duohui.cn/?utm_source=element&utm_medium=web&utm_campaign=element-index" target="_blank">
<img width="150px" src="https://user-images.githubusercontent.com/10095631/35603534-bb24470c-0678-11e8-8bcc-17ceaef8cbef.png">
@@ -68,7 +73,6 @@
- [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)
- [Customize theme](http://element.eleme.io/#/en-US/component/custom-theme)
@@ -115,7 +119,7 @@ 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.
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)) 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).
@@ -124,9 +128,7 @@ Detailed changes for each release are documented in the [release notes](https://
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.
[![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/67274736)
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)) before making a pull request.
## Special Thanks
English documentation is brought to you by SwiftGG Translation Team:
@@ -156,7 +158,7 @@ Spanish documentation is made possible by these community developers:
## Donation
If you find Element useful, you can buy us a cup of coffee
<img width="650" src="https://user-images.githubusercontent.com/14025786/44833997-5d7c4d80-ac62-11e8-8445-1dffec0eb13c.png" alt="donation">
<img width="650" src="https://user-images.githubusercontent.com/10095631/42198577-587063dc-7ebb-11e8-892b-91e08f99ce1e.jpg" alt="donation">
## Backers
@@ -229,11 +231,6 @@ Become a sponsor and get your logo on our README on Github with a link to your s
<a href="https://opencollective.com/element/sponsor/28/website" target="_blank"><img src="https://opencollective.com/element/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/29/website" target="_blank"><img src="https://opencollective.com/element/sponsor/29/avatar.svg"></a>
## Join Discusion Group
Scan the QR code using [Dingtalk App](https://www.dingtalk.com/) to join in discusion group :
<img alt="Join Discusion Group" src="https://user-images.githubusercontent.com/17680888/54505885-e3e54c00-4974-11e9-94b9-4c13644fcd98.png" width="300">
## LICENSE

View File

@@ -10,11 +10,10 @@ const client = algoliasearch('4C63BTGP6S', key);
const langs = {
'zh-CN': 'element-zh',
'en-US': 'element-en',
'es': 'element-es',
'fr-FR': 'element-fr'
'es': 'element-es'
};
['zh-CN', 'en-US', 'es', 'fr-FR'].forEach(lang => {
['zh-CN', 'en-US', 'es'].forEach(lang => {
const indexName = langs[lang];
const index = client.initIndex(indexName);
index.clearIndex(err => {

View File

@@ -53,10 +53,6 @@ export default {
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';

View File

@@ -1,6 +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' };
if (!content[version]) content[version] = '2.7';
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' };
if (!content[version]) content[version] = '2.4';
fs.writeFileSync(path.resolve(__dirname, '../../examples/versions.json'), JSON.stringify(content));

View File

@@ -2,6 +2,7 @@ var path = require('path');
var fs = require('fs');
var nodeExternals = require('webpack-node-externals');
var Components = require('../components.json');
var saladConfig = require('./salad.config.json');
var utilsList = fs.readdirSync(path.resolve(__dirname, '../src/utils'));
var mixinsList = fs.readdirSync(path.resolve(__dirname, '../src/mixins'));
@@ -47,3 +48,12 @@ exports.vue = {
};
exports.jsexclude = /node_modules|utils\/popper\.js|utils\/date.\js/;
exports.postcss = function(webapck) {
saladConfig.features.partialImport = {
addDependencyTo: webapck
};
return [
require('postcss-salad')(saladConfig)
];
};

View File

@@ -40,7 +40,7 @@ if [ "$TRAVIS_TAG" ]; then
# build sub folder
echo $TRAVIS_TAG
SUB_FOLDER='2.7'
SUB_FOLDER='2.4'
mkdir $SUB_FOLDER
rm -rf *.js *.css *.map static
rm -rf $SUB_FOLDER/**

View File

@@ -1,13 +1,12 @@
#! /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.7'
mkdir -p $SUB_FOLDER
SUB_FOLDER='2.4'
mkdir $SUB_FOLDER
rm -rf *.js *.css *.map static
rm -rf $SUB_FOLDER/**
cp -rf ../../examples/element-ui/** .
@@ -15,5 +14,5 @@ cp -rf ../../examples/element-ui/** $SUB_FOLDER/
cd ../..
# deploy domestic site
faas deploy alpha -P element
faas deploy alpha
rm -rf temp_web

View File

@@ -1,26 +0,0 @@
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;

View File

@@ -1,24 +0,0 @@
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 `<demo-block>
<div>${md.render(description)}</div>
<!--element-demo: ${content}:element-demo-->
`;
}
return '</demo-block>';
}
});
md.use(mdContainer, 'tip');
md.use(mdContainer, 'warning');
};

View File

@@ -1,14 +0,0 @@
// 覆盖默认的 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 `<template slot="highlight"><pre v-pre><code class="html">${md.utils.escapeHtml(token.content)}</code></pre></template>`;
}
return defaultRender(tokens, idx, options, env, self);
};
};

View File

@@ -1,67 +0,0 @@
const {
stripScript,
stripTemplate,
genInlineComponentText
} = require('./util');
const md = require('./config');
module.exports = function(source) {
const content = md.render(source);
const startTag = '<!--element-demo:';
const startTagLen = startTag.length;
const endTag = ':element-demo-->';
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(`<${demoComponentName} slot="source" />`);
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 = `<script>
export default {
name: 'component-doc',
components: {
${componenetsString}
}
}
</script>`;
} else if (content.indexOf('<script>') === 0) { // 硬编码,有待改善
start = content.indexOf('</script>') + '</script>'.length;
pageScript = content.slice(0, start);
}
output.push(content.slice(start));
return `
<template>
<section class="content element-doc">
${output.join('')}
</section>
</template>
${pageScript}
`;
};

View File

@@ -1,79 +0,0 @@
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/master/lib/loaders/templateLoader.js#L29
const finalOptions = {
source: `<div>${template}</div>`,
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 demo() {
${demoComponentContent}
${script}
return {
...democomponentExport,
render,
staticRenderFns
}
})()`;
return demoComponentContent;
}
module.exports = {
stripScript,
stripStyle,
stripTemplate,
genInlineComponentText
};

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env sh
set -e
git checkout master
git merge dev
VERSION=`npx select-version-cli`
#!/usr/bin/env sh
set -e
echo "Enter release version: "
read VERSION
read -p "Releasing $VERSION - are you sure? (y/n)" -n 1 -r
echo # (optional) move to a new line

16
build/salad.config.json Normal file
View File

@@ -0,0 +1,16 @@
{
"browsers": ["ie > 8", "last 2 versions"],
"features": {
"bem": {
"shortcuts": {
"component": "b",
"modifier": "m",
"descendent": "e"
},
"separators": {
"descendent": "__",
"modifier": "--"
}
}
}
}

34
build/strip-tags.js Normal file
View File

@@ -0,0 +1,34 @@
/*!
* strip-tags <https://github.com/jonschlinkert/strip-tags>
*
* Copyright (c) 2015 Jon Schlinkert, contributors.
* Licensed under the MIT license.
*/
'use strict';
var cheerio = require('cheerio');
exports.strip = function(str, tags) {
var $ = cheerio.load(str, {decodeEntities: false});
if (!tags || tags.length === 0) {
return str;
}
tags = !Array.isArray(tags) ? [tags] : tags;
var len = tags.length;
while (len--) {
$(tags[len]).remove();
}
return $.html();
};
exports.fetch = function(str, tag) {
var $ = cheerio.load(str, {decodeEntities: false});
if (!tag) return str;
return $(tag).html();
};

View File

@@ -14,8 +14,6 @@ module.exports = {
publicPath: '/dist/',
filename: 'element-ui.common.js',
chunkFilename: '[id].js',
libraryExport: 'default',
library: 'ELEMENT',
libraryTarget: 'commonjs2'
},
resolve: {
@@ -52,7 +50,11 @@ module.exports = {
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader']
loaders: ['style-loader', 'css-loader', 'postcss-loader']
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,

View File

@@ -47,7 +47,11 @@ const webpackConfig = {
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader']
loaders: ['style-loader', 'css-loader', 'postcss-loader']
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,

View File

@@ -1,7 +1,6 @@
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');
@@ -16,10 +15,8 @@ module.exports = {
filename: 'index.js',
chunkFilename: '[id].js',
libraryTarget: 'umd',
libraryExport: 'default',
library: 'ELEMENT',
umdNamedDefine: true,
globalObject: 'typeof self !== \'undefined\' ? self : this'
umdNamedDefine: true
},
resolve: {
extensions: ['.js', '.vue', '.json'],
@@ -28,17 +25,6 @@ module.exports = {
externals: {
vue: config.vue
},
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
output: {
comments: false
}
}
})
]
},
performance: {
hints: false
},
@@ -64,7 +50,11 @@ module.exports = {
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader']
loaders: ['style-loader', 'css-loader', 'postcss-loader']
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,

View File

@@ -5,14 +5,30 @@ 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 md = require('markdown-it')();
const slugify = require('transliteration').slugify;
const striptags = require('./strip-tags');
const config = require('./config');
const isProd = process.env.NODE_ENV === 'production';
const isPlay = !!process.env.PLAY_ENV;
function convert(str) {
str = str.replace(/(&#x)(\w{4});/gi, function($0) {
return String.fromCharCode(parseInt(encodeURIComponent($0).replace(/(%26%23x)(\w{4})(%3B)/g, '$2'), 16));
});
return str;
}
function wrap(render) {
return function() {
return render.apply(this, arguments)
.replace('<code v-pre class="', '<code class="hljs ')
.replace('<code>', '<code class="hljs">');
};
}
const webpackConfig = {
mode: process.env.NODE_ENV,
entry: isProd ? {
@@ -66,8 +82,16 @@ const webpackConfig = {
}
},
{
test: /\.(scss|css)$/,
use: [
test: /\.css$/,
loaders: [
isProd ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
'postcss-loader'
]
},
{
test: /\.scss$/,
loaders: [
isProd ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
'sass-loader'
@@ -75,24 +99,67 @@ const webpackConfig = {
},
{
test: /\.md$/,
use: [
loaders: [
{
loader: 'vue-loader',
options: {
compilerOptions: {
preserveWhitespace: false
}
}
loader: 'vue-loader'
},
{
loader: path.resolve(__dirname, './md-loader/index.js')
loader: 'vue-markdown-loader/lib/markdown-compiler',
options: {
preventExtract: true,
raw: true,
preprocess: function(MarkdownIt, source) {
MarkdownIt.renderer.rules.table_open = function() {
return '<table class="table">';
};
MarkdownIt.renderer.rules.fence = wrap(MarkdownIt.renderer.rules.fence);
return source;
},
use: [
[require('markdown-it-anchor'), {
level: 2,
slugify: slugify,
permalink: true,
permalinkBefore: true
}],
[require('markdown-it-container'), 'demo', {
validate: function(params) {
return params.trim().match(/^demo\s*(.*)$/);
},
render: function(tokens, idx) {
var m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
if (tokens[idx].nesting === 1) {
var description = (m && m.length > 1) ? m[1] : '';
var content = tokens[idx + 1].content;
var html = convert(striptags.strip(content, ['script', 'style'])).replace(/(<[^>]*)=""(?=.*>)/g, '$1');
var script = striptags.fetch(content, 'script');
var style = striptags.fetch(content, 'style');
var jsfiddle = { html: html, script: script, style: style };
var descriptionHTML = description
? md.render(description)
: '';
jsfiddle = md.utils.escapeHtml(JSON.stringify(jsfiddle));
return `<demo-block class="demo-box" :jsfiddle="${jsfiddle}">
<div class="source" slot="source">${html}</div>
${descriptionHTML}
<div class="highlight" slot="highlight">`;
}
return '</div></demo-block>\n';
}
}],
[require('markdown-it-container'), 'tip'],
[require('markdown-it-container'), 'warning']
]
}
}
]
},
{
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]')
@@ -111,9 +178,6 @@ const webpackConfig = {
]),
new ProgressBarPlugin(),
new VueLoaderPlugin(),
new webpack.DefinePlugin({
'process.env.FAAS_ENV': JSON.stringify(process.env.FAAS_ENV)
}),
new webpack.LoaderOptionsPlugin({
vue: {
compilerOptions: {
@@ -121,31 +185,15 @@ const webpackConfig = {
}
}
})
],
optimization: {
minimizer: []
}
]
};
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({})
);
}
module.exports = webpackConfig;

View File

@@ -22,6 +22,7 @@ const webpackConfig = {
}),
modules: ['node_modules']
},
devtool: '#inline-source-map',
module: {
rules: [
{
@@ -41,7 +42,7 @@ const webpackConfig = {
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader']
loaders: ['style-loader', 'css-loader', 'postcss-loader']
},
{
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,

View File

@@ -13,7 +13,6 @@
import zhLocale from 'main/locale/lang/zh-CN';
import enLocale from 'main/locale/lang/en';
import esLocale from 'main/locale/lang/es';
import frLocale from 'main/locale/lang/fr';
const lang = location.hash.replace('#', '').split('/')[1] || 'zh-CN';
const localize = lang => {
@@ -24,9 +23,6 @@
case 'es':
use(esLocale);
break;
case 'fr-FR':
use(frLocale);
break;
default:
use(enLocale);
}
@@ -84,3 +80,9 @@
}
};
</script>
<style>
@import 'highlight.js/styles/color-brewer.css';
@import 'assets/styles/common.css';
@import 'assets/styles/fonts/style.css';
</style>

View File

@@ -0,0 +1,16 @@
<svg width="63" height="59" viewBox="0 0 63 59" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Canvas" fill="none">
<g id="duotai-icon">
<g id="Rectangle">
<rect width="41.1402" height="42.1429" transform="translate(21.5987 16.8571)" fill="#FF7262"/>
</g>
<g id="Vector 2">
<path d="M 0 25.2857L 21.5986 0L 43.1972 25.2857L 0 25.2857Z" transform="translate(0 33.7142)" fill="#0ACF83"/>
</g>
<g id="Ellipse">
<ellipse cx="16.4561" cy="16.8572" rx="16.4561" ry="16.8572" transform="translate(5.14249 0)" fill="#1ABCFE"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,6 @@ html, body {
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;
@@ -15,7 +14,7 @@ html, body {
#app {
height: 100%;
&.is-component {
@when component {
overflow-y: hidden;
.main-cnt {

View File

@@ -1,18 +0,0 @@
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 }`;
}
};

View File

@@ -4,16 +4,12 @@
:class="[blockClass, { 'hover': hovering }]"
@mouseenter="hovering = true"
@mouseleave="hovering = false">
<div class="source">
<slot name="source"></slot>
</div>
<slot name="source"></slot>
<div class="meta" ref="meta">
<div class="description" v-if="$slots.default">
<slot></slot>
</div>
<div class="highlight">
<slot name="highlight"></slot>
</div>
<slot name="highlight"></slot>
</div>
<div
class="demo-block-control"
@@ -33,7 +29,7 @@
size="small"
type="text"
class="control-button"
@click.stop="goCodepen">
@click.stop="goJsfiddle">
{{ langConfig['button-text'] }}
</el-button>
</transition>
@@ -42,7 +38,7 @@
</div>
</template>
<style lang="scss">
<style>
.demo-block {
border: solid 1px #ebebeb;
border-radius: 3px;
@@ -183,17 +179,11 @@
<script type="text/babel">
import compoLang from '../i18n/component.json';
import Element from 'main/index.js';
import { stripScript, stripStyle, stripTemplate } from '../util';
const { version } = Element;
export default {
data() {
return {
codepen: {
script: '',
html: '',
style: ''
},
hovering: false,
isExpanded: false,
fixedControl: false,
@@ -201,10 +191,16 @@
};
},
props: {
jsfiddle: Object,
default() {
return {};
}
},
methods: {
goCodepen() {
// since 2.6.2 use code rather than jsfiddle https://blog.codepen.io/documentation/api/prefill/
const { script, html, style } = this.codepen;
goJsfiddle() {
const { script, html, style } = this.jsfiddle;
const resourcesTpl = '<scr' + 'ipt src="//unpkg.com/vue/dist/vue.js"></scr' + 'ipt>' +
'\n<scr' + `ipt src="//unpkg.com/element-ui@${ version }/lib/index.js"></scr` + 'ipt>';
let jsTpl = (script || '').replace(/export default/, 'var Main =').trim();
@@ -216,23 +212,25 @@
const data = {
js: jsTpl,
css: cssTpl,
html: htmlTpl
html: htmlTpl,
panel_js: 3,
panel_css: 1
};
const form = document.getElementById('fiddle-form') || document.createElement('form');
while (form.firstChild) {
form.removeChild(form.firstChild);
}
form.method = 'POST';
form.action = 'https://codepen.io/pen/define/';
form.innerHTML = '';
const node = document.createElement('textarea');
form.method = 'post';
form.action = 'https://jsfiddle.net/api/post/library/pure/';
form.target = '_blank';
for (let name in data) {
node.name = name;
node.value = data[name].toString();
form.appendChild(node.cloneNode());
}
form.setAttribute('id', 'fiddle-form');
form.style.display = 'none';
const input = document.createElement('input');
input.setAttribute('name', 'data');
input.setAttribute('type', 'hidden');
input.setAttribute('value', JSON.stringify(data));
form.appendChild(input);
document.body.appendChild(form);
form.submit();
@@ -301,25 +299,6 @@
}
},
created() {
const highlight = this.$slots.highlight;
if (highlight && highlight[0]) {
let code = '';
let cur = highlight[0];
if (cur.tag === 'pre' && (cur.children && cur.children[0])) {
cur = cur.children[0];
if (cur.tag === 'code') {
code = cur.children[0].text;
}
}
if (code) {
this.codepen.html = stripTemplate(code);
this.codepen.script = stripScript(code);
this.codepen.style = stripStyle(code);
}
}
},
mounted() {
this.$nextTick(() => {
let highlight = this.$el.getElementsByClassName('highlight')[0];

View File

@@ -17,7 +17,7 @@
</div>
</template>
<style lang="scss">
<style>
.footer-nav {
padding: 40px 0;
color: #333;

View File

@@ -43,7 +43,7 @@
</footer>
</template>
<style lang="scss">
<style>
.footer {
background-color: #F7FBFD;
width: 100%;

View File

@@ -1,4 +1,4 @@
<style lang="scss" scoped>
<style scoped>
.headerWrapper {
height: 80px;
}
@@ -10,14 +10,13 @@
top: 0;
left: 0;
width: 100%;
line-height: 80px;
line-height: @height;
z-index: 100;
position: relative;
.container {
height: 100%;
box-sizing: border-box;
border-bottom: 1px solid #DCDFE6;
}
.nav-lang-spe {
@@ -55,15 +54,9 @@
height: 100%;
line-height: 80px;
background: transparent;
@utils-clearfix;
padding: 0;
margin: 0;
&::before, &::after {
display: table;
content: "";
}
&::after {
clear: both;
}
}
.nav-gap {
@@ -129,24 +122,23 @@
a {
text-decoration: none;
color: #1989FA;
opacity: 0.5;
color: #888;
display: block;
padding: 0 22px;
&.active,
&:hover {
opacity: 1;
color: #333;
}
&.active::after {
content: '';
display: inline-block;
position: absolute;
bottom: 0;
left: calc(50% - 15px);
width: 30px;
height: 2px;
bottom: 15px;
left: calc(50% - 7px);
width: 14px;
height: 4px;
background: #409EFF;
}
}
@@ -180,7 +172,7 @@
transform: translateY(-2px);
}
.is-active {
@when active {
span, i {
color: #409EFF;
}
@@ -364,8 +356,7 @@
<!--theme picker-->
<li class="nav-item nav-theme-switch" v-show="isComponentPage">
<theme-configurator :key="lang" v-if="showThemeConfigurator"></theme-configurator>
<theme-picker v-else></theme-picker>
<theme-picker></theme-picker>
</li>
</ul>
</div>
@@ -374,13 +365,9 @@
</template>
<script>
import ThemePicker from './theme-picker.vue';
import ThemeConfigurator from './theme-configurator';
import AlgoliaSearch from './search.vue';
import compoLang from '../i18n/component.json';
import Element from 'main/index.js';
import { getVars } from './theme-configurator/utils/api.js';
import bus from '../bus';
const { version } = Element;
export default {
@@ -394,16 +381,13 @@
langs: {
'zh-CN': '中文',
'en-US': 'English',
'es': 'Español',
'fr-FR': 'Français'
},
showThemeConfigurator: false
'es': 'Español'
}
};
},
components: {
ThemePicker,
ThemeConfigurator,
AlgoliaSearch
},
@@ -421,20 +405,7 @@
return /^component/.test(this.$route.name);
}
},
mounted() {
const host = location.hostname;
this.showThemeConfigurator = host.match('localhost') || host.match('elenet');
if (!this.showThemeConfigurator) {
getVars()
.then(() => {
this.showThemeConfigurator = true;
ga('send', 'event', 'DocView', 'Inner');
})
.catch((err) => {
console.error(err);
});
}
},
methods: {
switchVersion(version) {
if (version === this.version) return;
@@ -469,17 +440,6 @@
};
xhr.open('GET', '/versions.json');
xhr.send();
let primaryLast = '#409EFF';
bus.$on('user-theme-config-update', (val) => {
let primaryColor = val.global['$--color-primary'];
if (!primaryColor) primaryColor = '#409EFF';
const base64svg = 'data:image/svg+xml;base64,';
const imgSet = document.querySelectorAll('h1 img');
imgSet.forEach((img) => {
img.src = `${base64svg}${window.btoa(window.atob(img.src.replace(base64svg, '')).replace(primaryLast, primaryColor))}`;
});
primaryLast = primaryColor;
});
}
};
</script>

View File

@@ -6,8 +6,7 @@
:fetch-suggestions="querySearch"
:placeholder="placeholder"
:trigger-on-focus="false"
@select="handleSelect"
highlight-first-item>
@select="handleSelect">
<template slot-scope="props">
<p class="algolia-search-title" v-if="props.item.title">
<span v-html="props.item.highlightedCompo"></span>
@@ -35,10 +34,10 @@
</el-autocomplete>
</template>
<style lang="scss">
<style>
.algolia-search {
width: 450px !important;
&.is-empty {
.el-autocomplete-suggestion__list {
padding-bottom: 0;
@@ -52,27 +51,27 @@
li {
border-bottom: solid 1px #ebebeb;
&:last-child {
border-bottom: none;
}
}
.algolia-highlight {
color: #409EFF;
font-weight: bold;
}
.algolia-search-title {
font-size: 14px;
margin: 6px 0;
line-height: 1.8;
}
.algolia-search-separator {
padding: 0 6px;
}
.algolia-search-content {
font-size: 12px;
margin: 6px 0;
@@ -81,7 +80,7 @@
text-overflow: ellipsis;
white-space: nowrap;
}
.algolia-search-link {
position: absolute;
bottom: 0;
@@ -97,14 +96,14 @@
&:hover {
background-color: #e4e7ed;
}
img {
display: inline-block;
height: 17px;
margin-top: 10px;
}
}
.algolia-search-empty {
margin: 5px 0;
text-align: center;
@@ -137,11 +136,6 @@
search: 'Buscar',
empty: 'No hay datos que coincidan',
index: 'es'
},
'fr-FR': {
search: 'Rechercher',
empty: 'Aucun résultat',
index: 'fr'
}
}
};
@@ -219,4 +213,4 @@
this.initIndex();
}
};
</script>
</script>

View File

@@ -1,4 +1,4 @@
<style lang="scss">
<style>
.side-nav {
width: 100%;
box-sizing: border-box;
@@ -130,6 +130,11 @@
<img src="~examples/assets/images/tipe.svg" alt="tipe.io">
</a>
</li>
<li class="nav-item">
<a class="sponsor" href="https://www.duotai.net/?utm_source=element" target="_blank">
<img src="~examples/assets/images/duotai.svg" alt="duotai">
</a>
</li>
<li class="nav-item">
<a class="sponsor" href="https://www.duohui.cn/?utm_source=element&utm_medium=web&utm_campaign=element-index" target="_blank">
<img src="~examples/assets/images/duohui.svg" alt="duohui">
@@ -175,7 +180,7 @@
<li
class="nav-item"
v-for="(navItem, key) in group.list"
v-show="!navItem.disabled"
v-if="!navItem.disabled"
:key="key">
<router-link
active-class="active"

View File

@@ -1,61 +0,0 @@
<script>
const ORIGINAL_THEME = '#409EFF';
import { get as ajaxGet } from './utils/ajax';
import { updateDomHeadStyle } from './utils/utils.js';
export default {
data() {
return {
docs: '', // content of docs css
theme: ORIGINAL_THEME,
asyncCb: true
};
},
methods: {
updateDocStyle(e, cb) {
const val = e.global['$--color-primary'] || ORIGINAL_THEME;
const oldVal = this.theme;
const getHandler = (variable, id) => {
return () => {
let newStyle = this.updateStyle(this[variable], ORIGINAL_THEME, val);
updateDomHeadStyle(id, newStyle);
this.asyncCb && cb();
};
};
const docsHandler = getHandler('docs', 'docs-style');
if (!this.docs) {
const links = [].filter.call(document.querySelectorAll('link'), link => {
return /docs\..+\.css/.test(link.href || '');
});
if (links[0]) {
this.getCSSString(links[0].href, docsHandler, 'docs');
} else {
this.asyncCb = false;
}
} else {
docsHandler();
}
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText;
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text);
});
styles.forEach(style => {
const { innerText } = style;
if (typeof innerText !== 'string') return;
style.innerText = this.updateStyle(innerText, oldVal, val);
});
this.theme = val;
!this.asyncCb && cb();
},
updateStyle(style, oldColor, newColor) {
return style.replace(new RegExp(oldColor, 'ig'), newColor);
},
getCSSString(url, callback, variable) {
ajaxGet(url).then((res) => {
this[variable] = res;
callback();
});
}
}
};
</script>

View File

@@ -1,78 +0,0 @@
<template>
<div class="action-area">
<div class="action-area-main">
<div class="action-button">
<el-button type="warning" @click.stop="onReset">{{getActionDisplayName("reset-theme")}}</el-button>
</div>
<div class="action-button">
<el-button
type="primary"
:loading=downloading
style="background: #66b1ff;border-color: #66b1ff"
@click.stop="onDownload">
{{getActionDisplayName("download-theme")}}
</el-button>
</div>
</div>
</div>
</template>
<style>
.action-area {
width: 24%;
max-width: 400px;
position: fixed;
right: 0;
bottom: 0;
padding-right: 1%;
}
@media (min-width: 1600px) {
.action-area {
padding-right: calc((100% - 1600px) / 2);
}
}
.action-area-main {
opacity: .95;
background: #F5F7FA;
height: 70px;
bottom: 0;
width: 97%;
box-sizing: border-box;
margin: 0 .5% 0 5%;
}
.action-button {
width: 50%;
text-align: center;
display: inline-block;
padding-top: 15px;
}
</style>
<script>
import { getActionDisplayName } from './utils/utils.js';
export default {
data() {
return {
downloading: false
};
},
methods: {
onReset() {
this.$parent.onReset();
},
getActionDisplayName(key) {
return getActionDisplayName(key);
},
onDownload() {
this.downloading = true;
this.$parent.onDownload()
.then()
.catch((err) => {
this.$parent.onError(err);
})
.then(() => {
this.downloading = false;
});
ga('send', 'event', 'ThemeConfigurator', 'Download');
}
}
};
</script>

View File

@@ -1,86 +0,0 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<theme-input
v-if="isGlobal"
:val="value"
@change="onChange"
></theme-input>
<el-select
v-if="!isGlobal"
v-model="value"
class="select"
@change="onSelectChange"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</section>
</template>
<style>
.select {
width: 100%;
}
</style>
<script>
import Mixin from './mixin';
import Input from './input';
import { getStyleDisplayName } from '../utils/utils.js';
export default {
data() {
return {
options: [],
value: ''
};
},
components: {
themeInput: Input
},
mixins: [Mixin],
computed: {
isGlobalInputValue() {
return this.config.value.startsWith('$');
}
},
methods: {
onSelectChange(e) {
this.onChange(e);
},
initSelectOption() {
this.options = [];
const golbalV = this.golbalValue.border;
if (golbalV) {
Object.keys(golbalV).forEach((font) => {
if (font.includes('border-radius')) {
const size = golbalV[font];
this.options.push({
value: size.key,
label: getStyleDisplayName(size)
});
}
});
}
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.initSelectOption();
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@@ -1,156 +0,0 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
<el-button
class="plus-button"
size="mini"
round
icon="el-icon-plus"
@click.stop="onAddShadow"
>
</el-button>
</div>
<div class="config-content" v-for="(each, key) in valueArr" :key="key">
<div class="content-10">
<color-picker
size="mini"
class="colorPicker"
v-model="each.color"
@change="val => onInputChange(val, key, 'color')"
show-alpha
></color-picker>
<span class="content-tip">Color</span>
</div>
<div class="content-20">
<theme-input
size="mini"
:val="each.offsetX"
@change="val => onInputChange(Number(val), key, 'offsetX')"
>
</theme-input>
<span class="content-tip">X-px</span>
</div>
<div class="content-20">
<theme-input
size="mini"
:val="each.offsetY"
@change="val => onInputChange(Number(val), key, 'offsetY')"
>
</theme-input>
<span class="content-tip">Y-px</span>
</div>
<div class="content-20">
<theme-input
size="mini"
:val="each.spreadRadius"
@change="val => onInputChange(Number(val), key, 'spreadRadius')"
>
</theme-input>
<span class="content-tip">Spread</span>
</div>
<div class="content-20">
<theme-input
size="mini"
:val="each.blurRadius"
@change="val => onInputChange(Number(val), key, 'blurRadius')"
>
</theme-input>
<span class="content-tip">Blur</span>
</div>
<div class="content-10">
<el-button
size="mini"
round
icon="el-icon-minus"
@click.stop="val => onMinusShadow(key)"
></el-button>
</div>
</div>
</section>
</template>
<style scoped>
.plus-button {
position: absolute;
left: 90%;
margin-top: 4px;
}
.colorPicker {
margin-left: 0;
}
.content-20 .el-input__suffix-inner span{
line-height: 28px;
}
.content-20 {
padding: 0 3px;
}
.content-10 {
vertical-align: top;
}
.content-tip {
color: #909399;
font-size: 12px;
}
.config-content {
padding: 5px 0;
}
/* Element buton style override */
.el-button--mini.is-round {
padding: 3px 3px;
}
</style>
<script>
import Mixin from './mixin';
import Input from './input';
import { parse as parseShaodw, stringify as stringifyShaodw } from '../utils/boxShadow.js';
import ColorPicker from './color-picker';
export default {
components: {
ColorPicker,
themeInput: Input
},
data() {
return {
valueArr: []
};
},
mixins: [Mixin],
methods: {
onAddShadow() {
this.valueArr.push({
offsetX: 0,
offsetY: 0,
spreadRadius: 0,
blurRadius: 0,
color: 'rgba(0,0,0,0)',
inset: false
});
},
onMinusShadow(index) {
this.valueArr.splice(index, 1);
this.onShadowChange();
},
onInputChange(e, index, key) {
const arr = this.valueArr[index];
arr[key] = e;
this.valueArr.splice(index, 1, arr);
this.onShadowChange();
},
onShadowChange() {
this.onChange(
stringifyShaodw(this.valueArr)
);
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.valueArr = parseShaodw(value);
}
}
}
};
</script>

View File

@@ -1,8 +0,0 @@
import ColorPicker from './src/main';
/* istanbul ignore next */
ColorPicker.install = function(Vue) {
Vue.component(ColorPicker.name, ColorPicker);
};
export default ColorPicker;

View File

@@ -1,316 +0,0 @@
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
// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
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));
}
}
}
};

View File

@@ -1,132 +0,0 @@
<template>
<div class="el-color-alpha-slider" :class="{ 'is-vertical': vertical }">
<div class="el-color-alpha-slider__bar"
@click="handleClick"
ref="bar"
:style="{
background: background
}">
</div>
<div class="el-color-alpha-slider__thumb"
ref="thumb"
:style="{
left: thumbLeft + 'px',
top: thumbTop + 'px'
}">
</div>
</div>
</template>
<script>
import draggable from '../draggable';
export default {
name: 'el-color-alpha-slider',
props: {
color: {
required: true
},
vertical: Boolean
},
watch: {
'color._alpha'() {
this.update();
},
'color.value'() {
this.update();
}
},
methods: {
handleClick(event) {
const thumb = this.$refs.thumb;
const target = event.target;
if (target !== thumb) {
this.handleDrag(event);
}
},
handleDrag(event) {
const rect = this.$el.getBoundingClientRect();
const { thumb } = this.$refs;
if (!this.vertical) {
let left = event.clientX - rect.left;
left = Math.max(thumb.offsetWidth / 2, left);
left = Math.min(left, rect.width - thumb.offsetWidth / 2);
this.color.set('alpha', Math.round((left - thumb.offsetWidth / 2) / (rect.width - thumb.offsetWidth) * 100));
} else {
let top = event.clientY - rect.top;
top = Math.max(thumb.offsetHeight / 2, top);
top = Math.min(top, rect.height - thumb.offsetHeight / 2);
this.color.set('alpha', Math.round((top - thumb.offsetHeight / 2) / (rect.height - thumb.offsetHeight) * 100));
}
},
getThumbLeft() {
if (this.vertical) return 0;
const el = this.$el;
const alpha = this.color._alpha;
if (!el) return 0;
const thumb = this.$refs.thumb;
return Math.round(alpha * (el.offsetWidth - thumb.offsetWidth / 2) / 100);
},
getThumbTop() {
if (!this.vertical) return 0;
const el = this.$el;
const alpha = this.color._alpha;
if (!el) return 0;
const thumb = this.$refs.thumb;
return Math.round(alpha * (el.offsetHeight - thumb.offsetHeight / 2) / 100);
},
getBackground() {
if (this.color && this.color.value) {
const { r, g, b } = this.color.toRgb();
return `linear-gradient(to right, rgba(${r}, ${g}, ${b}, 0) 0%, rgba(${r}, ${g}, ${b}, 1) 100%)`;
}
return null;
},
update() {
this.thumbLeft = this.getThumbLeft();
this.thumbTop = this.getThumbTop();
this.background = this.getBackground();
}
},
data() {
return {
thumbLeft: 0,
thumbTop: 0,
background: null
};
},
mounted() {
const { bar, thumb } = this.$refs;
const dragConfig = {
drag: (event) => {
this.handleDrag(event);
},
end: (event) => {
this.handleDrag(event);
}
};
draggable(bar, dragConfig);
draggable(thumb, dragConfig);
this.update();
}
};
</script>

View File

@@ -1,111 +0,0 @@
<template>
<div class="el-color-predefine color-list-container">
<div class="el-color-predefine__colors color-list">
<div class="color-list-item"
:class="{selected: item.selected, 'is-alpha': item._alpha < 100}"
v-for="(item, index) in rgbaColors"
:key="colors[index].variable"
@click="handleSelect(index)">
<span class="color-list-item-ball" :style="{'background-color': item.value}">
</span>
<div class="color-list-item-label">
{{item.info.label}}
<div class="color-list-item-value">
{{item.info.value}}
</div>
</div>
</div>
</div>
</div>
</template>
<style>
.color-list-container {
border-top: 1px solid #EBEEF5;
margin-top: 15px;
padding-top: 10px;
width: 100%;
}
.color-list {
max-height: 138px;
overflow: auto;
}
.color-list-item {
height: 24px;
width: 100%;
cursor: pointer;
margin: 2px 0;
position: relative;
}
.color-list-item:hover {
background: #efefef;
}
.color-list-item-ball {
height: 20px;
width: 20px;
margin-top: 2px;
margin-left: 5px;
border-radius: 100%;
display: block;
position: absolute;
}
.color-list-item-label {
margin-left: 35px;
font-size: 13px;
line-height: 24px;
display: inline-block;
width: 85%;
overflow: hidden;
}
.color-list-item-value {
float: right;
}
</style>
<script>
import Color from '../color';
export default {
props: {
colors: { type: Array, required: true },
color: { required: true }
},
data() {
return {
rgbaColors: this.parseColors(this.colors, this.color)
};
},
methods: {
handleSelect(index) {
this.color.fromString(this.colors[index].value);
this.$emit('select', this.colors[index]);
},
parseColors(colors, color) {
return colors.map(value => {
const c = new Color();
c.enableAlpha = true;
c.format = 'rgba';
c.fromString(value.value);
c.info = value;
c.selected = c.value === color.value;
return c;
});
}
},
watch: {
'$parent.currentColor'(val) {
const color = new Color();
color.fromString(val);
this.rgbaColors.forEach(item => {
item.selected = color.compare(item);
});
},
colors(newVal) {
this.rgbaColors = this.parseColors(newVal, this.color);
},
color(newVal) {
this.rgbaColors = this.parseColors(this.colors, newVal);
}
}
};
</script>

View File

@@ -1,123 +0,0 @@
<template>
<div class="el-color-hue-slider" :class="{ 'is-vertical': vertical }">
<div class="el-color-hue-slider__bar" @click="handleClick" ref="bar"></div>
<div class="el-color-hue-slider__thumb"
:style="{
left: thumbLeft + 'px',
top: thumbTop + 'px'
}"
ref="thumb">
</div>
</div>
</template>
<script>
import draggable from '../draggable';
export default {
name: 'el-color-hue-slider',
props: {
color: {
required: true
},
vertical: Boolean
},
data() {
return {
thumbLeft: 0,
thumbTop: 0
};
},
computed: {
hueValue() {
const hue = this.color.get('hue');
return hue;
}
},
watch: {
hueValue() {
this.update();
}
},
methods: {
handleClick(event) {
const thumb = this.$refs.thumb;
const target = event.target;
if (target !== thumb) {
this.handleDrag(event);
}
},
handleDrag(event) {
const rect = this.$el.getBoundingClientRect();
const { thumb } = this.$refs;
let hue;
if (!this.vertical) {
let left = event.clientX - rect.left;
left = Math.min(left, rect.width - thumb.offsetWidth / 2);
left = Math.max(thumb.offsetWidth / 2, left);
hue = Math.round((left - thumb.offsetWidth / 2) / (rect.width - thumb.offsetWidth) * 360);
} else {
let top = event.clientY - rect.top;
top = Math.min(top, rect.height - thumb.offsetHeight / 2);
top = Math.max(thumb.offsetHeight / 2, top);
hue = Math.round((top - thumb.offsetHeight / 2) / (rect.height - thumb.offsetHeight) * 360);
}
this.color.set('hue', hue);
},
getThumbLeft() {
if (this.vertical) return 0;
const el = this.$el;
const hue = this.color.get('hue');
if (!el) return 0;
const thumb = this.$refs.thumb;
return Math.round(hue * (el.offsetWidth - thumb.offsetWidth / 2) / 360);
},
getThumbTop() {
if (!this.vertical) return 0;
const el = this.$el;
const hue = this.color.get('hue');
if (!el) return 0;
const thumb = this.$refs.thumb;
return Math.round(hue * (el.offsetHeight - thumb.offsetHeight / 2) / 360);
},
update() {
this.thumbLeft = this.getThumbLeft();
this.thumbTop = this.getThumbTop();
}
},
mounted() {
const { bar, thumb } = this.$refs;
const dragConfig = {
drag: (event) => {
this.handleDrag(event);
},
end: (event) => {
this.handleDrag(event);
}
};
draggable(bar, dragConfig);
draggable(thumb, dragConfig);
this.update();
}
};
</script>

View File

@@ -1,134 +0,0 @@
<template>
<transition name="el-zoom-in-top" @after-leave="doDestroy">
<div
class="el-color-dropdown"
v-show="showPopper">
<div class="el-color-dropdown__main-wrapper">
<hue-slider ref="hue" :color="color" vertical style="float: right;"></hue-slider>
<sv-panel ref="sl" :color="color"></sv-panel>
</div>
<alpha-slider v-if="showAlpha" ref="alpha" :color="color"></alpha-slider>
<predefine v-if="predefine" :color="color" :colors="predefine"></predefine>
<div class="el-color-dropdown__btns">
<span class="el-color-dropdown__value">
<el-input
v-model="customInput"
@keyup.native.enter="handleConfirm"
@blur="handleConfirm"
:validate-event="false"
size="mini">
</el-input>
</span>
<!-- <el-button
size="mini"
type="text"
class="el-color-dropdown__link-btn"
@click="$emit('clear')">
{{ t('el.colorpicker.clear') }}
</el-button> -->
<el-button
plain
size="mini"
class="el-color-dropdown__btn"
@click="confirmValue">
{{ t('el.colorpicker.confirm') }}
</el-button>
</div>
<color-list
v-if="colorList && colorList.length > 0"
:color="color"
:colors="colorList"
@select=onColorListSelect
></color-list>
</div>
</transition>
</template>
<script>
import SvPanel from './sv-panel';
import HueSlider from './hue-slider';
import AlphaSlider from './alpha-slider';
import Predefine from './predefine';
import ColorList from './color-list';
import Popper from 'element-ui/src/utils/vue-popper';
import Locale from 'element-ui/src/mixins/locale';
import ElInput from 'element-ui/packages/input';
import ElButton from 'element-ui/packages/button';
export default {
name: 'el-color-picker-dropdown',
mixins: [Popper, Locale],
components: {
SvPanel,
HueSlider,
AlphaSlider,
ElInput,
ElButton,
Predefine,
ColorList
},
props: {
color: {
required: true
},
showAlpha: Boolean,
predefine: Array,
colorList: Array
},
data() {
return {
customInput: ''
};
},
computed: {
currentColor() {
const parent = this.$parent;
return !parent.value && !parent.showPanelColor ? '' : parent.color.value;
}
},
methods: {
confirmValue() {
this.$emit('pick');
},
onColorListSelect(e) {
this.$emit('pick', e);
},
handleConfirm() {
this.color.fromString(this.customInput);
}
},
mounted() {
this.$parent.popperElm = this.popperElm = this.$el;
this.referenceElm = this.$parent.$el;
},
watch: {
showPopper(val) {
if (val === true) {
this.$nextTick(() => {
const { sl, hue, alpha } = this.$refs;
sl && sl.update();
hue && hue.update();
alpha && alpha.update();
});
}
},
currentColor: {
immediate: true,
handler(val) {
this.customInput = val;
}
}
}
};
</script>

View File

@@ -1,61 +0,0 @@
<template>
<div class="el-color-predefine">
<div class="el-color-predefine__colors">
<div class="el-color-predefine__color-selector"
:class="{selected: item.selected, 'is-alpha': item._alpha < 100}"
v-for="(item, index) in rgbaColors"
:key="colors[index]"
@click="handleSelect(index)">
<div :style="{'background-color': item.value}">
</div>
</div>
</div>
</div>
</template>
<script>
import Color from '../color';
export default {
props: {
colors: { type: Array, required: true },
color: { required: true }
},
data() {
return {
rgbaColors: this.parseColors(this.colors, this.color)
};
},
methods: {
handleSelect(index) {
this.color.fromString(this.colors[index]);
},
parseColors(colors, color) {
return colors.map(value => {
const c = new Color();
c.enableAlpha = true;
c.format = 'rgba';
c.fromString(value);
c.selected = c.value === color.value;
return c;
});
}
},
watch: {
'$parent.currentColor'(val) {
const color = new Color();
color.fromString(val);
this.rgbaColors.forEach(item => {
item.selected = color.compare(item);
});
},
colors(newVal) {
this.rgbaColors = this.parseColors(newVal, this.color);
},
color(newVal) {
this.rgbaColors = this.parseColors(this.colors, newVal);
}
}
};
</script>

View File

@@ -1,100 +0,0 @@
<template>
<div class="el-color-svpanel"
:style="{
backgroundColor: background
}">
<div class="el-color-svpanel__white"></div>
<div class="el-color-svpanel__black"></div>
<div class="el-color-svpanel__cursor"
:style="{
top: cursorTop + 'px',
left: cursorLeft + 'px'
}">
<div></div>
</div>
</div>
</template>
<script>
import draggable from '../draggable';
export default {
name: 'el-sl-panel',
props: {
color: {
required: true
}
},
computed: {
colorValue() {
const hue = this.color.get('hue');
const value = this.color.get('value');
return { hue, value };
}
},
watch: {
colorValue() {
this.update();
}
},
methods: {
update() {
const saturation = this.color.get('saturation');
const value = this.color.get('value');
const el = this.$el;
let { clientWidth: width, clientHeight: height } = el;
this.cursorLeft = saturation * width / 100;
this.cursorTop = (100 - value) * height / 100;
this.background = 'hsl(' + this.color.get('hue') + ', 100%, 50%)';
},
handleDrag(event) {
const el = this.$el;
const rect = el.getBoundingClientRect();
let left = event.clientX - rect.left;
let top = event.clientY - rect.top;
left = Math.max(0, left);
left = Math.min(left, rect.width);
top = Math.max(0, top);
top = Math.min(top, rect.height);
this.cursorLeft = left;
this.cursorTop = top;
this.color.set({
saturation: left / rect.width * 100,
value: 100 - top / rect.height * 100
});
}
},
mounted() {
draggable(this.$el, {
drag: (event) => {
this.handleDrag(event);
},
end: (event) => {
this.handleDrag(event);
}
});
this.update();
},
data() {
return {
cursorTop: 0,
cursorLeft: 0,
background: 'hsl(0, 100%, 50%)'
};
}
};
</script>

View File

@@ -1,36 +0,0 @@
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);
}
});
}

View File

@@ -1,190 +0,0 @@
<template>
<div
:class="[
'el-color-picker',
colorDisabled ? 'is-disabled' : '',
colorSize ? `el-color-picker--${ colorSize }` : ''
]"
v-clickoutside="hide">
<div class="el-color-picker__mask" v-if="colorDisabled"></div>
<div class="el-color-picker__trigger" @click="handleTrigger">
<span class="el-color-picker__color" :class="{ 'is-alpha': showAlpha }">
<span class="el-color-picker__color-inner"
:style="{
backgroundColor: displayedColor
}"></span>
<span class="el-color-picker__empty el-icon-close" v-if="!value && !showPanelColor"></span>
</span>
<span class="el-color-picker__icon el-icon-arrow-down" v-show="value || showPanelColor"></span>
</div>
<picker-dropdown
ref="dropdown"
:class="['el-color-picker__panel', popperClass || '']"
v-model="showPicker"
@pick="confirmValue"
@clear="clearValue"
:color="color"
:show-alpha="showAlpha"
:predefine="predefine"
:colorList="colorList">
</picker-dropdown>
</div>
</template>
<script>
import Color from './color';
import PickerDropdown from './components/picker-dropdown.vue';
import Clickoutside from 'element-ui/src/utils/clickoutside';
import Emitter from 'element-ui/src/mixins/emitter';
export default {
name: 'ElColorPicker',
mixins: [Emitter],
props: {
value: String,
showAlpha: Boolean,
colorFormat: String,
disabled: Boolean,
size: String,
popperClass: String,
predefine: Array,
colorList: Array
},
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
directives: { Clickoutside },
computed: {
displayedColor() {
if (!this.value && !this.showPanelColor) {
return 'transparent';
}
return this.displayedRgb(this.color, this.showAlpha);
},
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
colorSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
colorDisabled() {
return this.disabled || (this.elForm || {}).disabled;
}
},
watch: {
value(val) {
if (!val) {
this.showPanelColor = false;
} else if (val && val !== this.color.value) {
this.color.fromString(val);
}
},
color: {
deep: true,
handler() {
this.showPanelColor = true;
}
},
displayedColor(val) {
if (!this.showPicker) return;
const currentValueColor = new Color({
enableAlpha: this.showAlpha,
format: this.colorFormat
});
currentValueColor.fromString(this.value);
const currentValueColorRgb = this.displayedRgb(currentValueColor, this.showAlpha);
if (val !== currentValueColorRgb) {
this.$emit('active-change', val);
}
}
},
methods: {
handleTrigger() {
if (this.colorDisabled) return;
this.showPicker = !this.showPicker;
},
confirmValue(selection) {
const value = selection || this.color.value;
this.$emit('input', value);
this.$emit('change', value);
this.dispatch('ElFormItem', 'el.form.change', value);
this.showPicker = false;
},
clearValue() {
this.$emit('input', null);
this.$emit('change', null);
if (this.value !== null) {
this.dispatch('ElFormItem', 'el.form.change', null);
}
this.showPanelColor = false;
this.showPicker = false;
this.resetColor();
},
hide() {
this.showPicker = false;
this.resetColor();
},
resetColor() {
this.$nextTick(_ => {
if (this.value) {
this.color.fromString(this.value);
} else {
this.showPanelColor = false;
}
});
},
displayedRgb(color, showAlpha) {
if (!(color instanceof Color)) {
throw Error('color should be instance of Color Class');
}
const { r, g, b } = color.toRgb();
return showAlpha
? `rgba(${ r }, ${ g }, ${ b }, ${ color.get('alpha') / 100 })`
: `rgb(${ r }, ${ g }, ${ b })`;
}
},
mounted() {
const value = this.value;
if (value) {
this.color.fromString(value);
}
this.popperElm = this.$refs.dropdown.$el;
},
data() {
const color = new Color({
enableAlpha: this.showAlpha,
format: this.colorFormat
});
return {
color,
showPicker: false,
showPanelColor: false
};
},
components: {
PickerDropdown
}
};
</script>

View File

@@ -1,89 +0,0 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<div class="content-80">
<el-input
:value=displayValue
readonly
slot="reference"
@click.native="onInputClick"
></el-input>
</div>
<div class="content-20">
<color-picker
ref="colorPicker"
class="colorPicker"
v-model="pickerColor"
@change=onPickerChange
:colorList="golbalColorList"
></color-picker>
</div>
</div>
</section>
</template>
<style>
input {
cursor: pointer;
}
.colorPicker {
margin-left: 10px;
vertical-align: bottom;
}
</style>
<script>
import Mixin from './mixin';
import { getStyleDisplayValue, getStyleDisplayName } from '../utils/utils.js';
import ColorPicker from './color-picker';
export default {
components: {
ColorPicker
},
data() {
return {
pickerColor: ''
};
},
mixins: [Mixin],
watch: {
displayValue: {
immediate: true,
handler(value) {
if (value.startsWith('#')) {
this.pickerColor = value;
}
}
}
},
computed: {
golbalColor() {
return this.golbalValue.color;
},
displayValue() {
return getStyleDisplayValue(this.mergedValue, this.golbalColor);
},
golbalColorList() {
return this.isGlobal ? [] : Object.keys(this.golbalColor).map((c) => (
{
label: getStyleDisplayName(this.golbalColor[c]),
value: this.golbalColor[c].value,
variable: c
}
));
}
},
methods: {
onInputClick() {
this.$refs.colorPicker && this.$refs.colorPicker.handleTrigger();
},
onPickerChange(e) {
this.onChange(e.variable || e);
}
}
};
</script>

View File

@@ -1,101 +0,0 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<el-select
v-model="value"
class="select"
@change="onSelectChange"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</section>
</template>
<style>
.select {
width: 100%;
}
</style>
<script>
const defaultFontLineHeight = [
'1',
'1.3',
'1.5',
'1.7',
'12px',
'16px',
'20px',
'24px',
'28px'
];
import Mixin from './mixin';
import { getStyleDisplayName } from '../utils/utils.js';
export default {
props: {
componentName: {
type: String
},
golbalValue: {
type: Object
}
},
data() {
return {
options: [],
value: ''
};
},
mixins: [Mixin],
computed: {
isGlobalInputValue() {
return this.config.value.startsWith('$');
}
},
methods: {
onSelectChange(e) {
this.onChange(e);
},
initSelectOption() {
this.options = [];
defaultFontLineHeight.forEach((size) => {
this.options.push({
value: size,
label: size
});
});
const golbalTypography = this.golbalValue.typography;
if (this.isGlobalInputValue && golbalTypography) {
Object.keys(golbalTypography).forEach((font) => {
if (font.includes('font-line-height')) {
const size = golbalTypography[font];
this.options.push({
value: size.key,
label: getStyleDisplayName(size)
});
}
});
}
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.initSelectOption();
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@@ -1,101 +0,0 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<el-select
v-model="value"
class="select"
@change="onSelectChange"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</section>
</template>
<style>
.select {
width: 100%;
}
</style>
<script>
const defaultFontSize = [
'12px',
'13px',
'14px',
'16px',
'18px',
'20px',
'28px',
'36px',
'48px'
];
import Mixin from './mixin';
import { getStyleDisplayName } from '../utils/utils.js';
export default {
props: {
componentName: {
type: String
},
golbalValue: {
type: Object
}
},
data() {
return {
options: [],
value: ''
};
},
mixins: [Mixin],
computed: {
isGlobalInputValue() {
return this.config.value.startsWith('$');
}
},
methods: {
onSelectChange(e) {
this.onChange(e);
},
initSelectOption() {
this.options = [];
defaultFontSize.forEach((size) => {
this.options.push({
value: size,
label: size
});
});
const golbalTypography = this.golbalValue.typography;
if (this.isGlobalInputValue && golbalTypography) {
Object.keys(golbalTypography).forEach((font) => {
if (font.includes('font-size')) {
const size = golbalTypography[font];
this.options.push({
value: size.key,
label: getStyleDisplayName(size)
});
}
});
}
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.initSelectOption();
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@@ -1,106 +0,0 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<el-select
v-model="value"
class="select"
@change="onSelectChange"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</section>
</template>
<style>
.select {
width: 100%;
}
</style>
<script>
const defaultFontWeight = [
'normal',
'bold',
'bolder',
'lighter',
'100',
'200',
'300',
'400',
'500',
'600',
'700',
'800',
'900',
'inherit'
];
import Mixin from './mixin';
import { getStyleDisplayName } from '../utils/utils.js';
export default {
props: {
componentName: {
type: String
},
golbalValue: {
type: Object
}
},
data() {
return {
options: [],
value: ''
};
},
mixins: [Mixin],
computed: {
isGlobalInputValue() {
return this.config.value.startsWith('$');
}
},
methods: {
onSelectChange(e) {
this.onChange(e);
},
initSelectOption() {
this.options = [];
defaultFontWeight.forEach((weight) => {
this.options.push({
value: weight,
label: weight
});
});
const golbalTypography = this.golbalValue.typography;
if (this.isGlobalInputValue && golbalTypography) {
Object.keys(golbalTypography).forEach((font) => {
if (font.includes('font-weight')) {
const weight = golbalTypography[font];
this.options.push({
value: weight.key,
label: getStyleDisplayName(weight)
});
}
});
}
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.initSelectOption();
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@@ -1,45 +0,0 @@
<template>
<el-input
@keyup.enter.native="onUpdate"
v-model="value"
@blur="onUpdate"
v-bind="$attrs"
>
<template slot="suffix">
<slot name="suffix"></slot>
</template>
</el-input>
</template>
<script>
export default {
props: ['val', 'onChange'],
data() {
return {
value: '',
oldValue: ''
};
},
methods: {
onUpdate(e) {
const { value } = e.target;
if (value !== this.oldValue) {
this.oldValue = value;
this.$emit('change', value);
}
}
},
watch: {
val: {
immediate: true,
handler(value) {
this.value = value;
if (!this.oldValue) {
this.oldValue = value;
}
}
}
}
};
</script>

View File

@@ -1,75 +0,0 @@
<style>
.config {
padding: 5px 0;
}
.config-label {
color: #606266;;
font-size: 14px;
padding-bottom: 5px;
position: relative;
}
.config-content {
}
.content-80 {
box-sizing: border-box;
display: inline-block;
width: 80%;
}
.content-20 {
box-sizing: border-box;
display: inline-block;
width: 20%;
vertical-align: bottom;
}
.content-10 {
box-sizing: border-box;
display: inline-block;
width: 10%;
vertical-align: bottom;
}
.content-15 {
box-sizing: border-box;
display: inline-block;
width: 15%;
vertical-align: bottom;
}
</style>
<script>
import { getStyleDisplayName } from '../utils/utils.js';
export default {
props: {
config: {
type: Object
},
userConfig: {
type: Object
},
golbalValue: {
type: Object
},
componentName: {
type: String
}
},
computed: {
mergedValue() {
return this.userConfig[this.config.key] || this.config.value;
},
displayName() {
return getStyleDisplayName(this.config, this.componentName);
},
isGlobal() {
return !this.config.value.startsWith('$');
}
},
methods: {
onChange(value) {
this.$emit('onChange', {
key: this.config.key,
value
});
}
}
};
</script>

View File

@@ -1,38 +0,0 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<theme-input
:val="value"
@change="onChange"
></theme-input>
</div>
</section>
</template>
<script>
import Input from './input';
import Mixin from './mixin';
export default {
components: {
themeInput: Input
},
data() {
return {
value: ''
};
},
mixins: [Mixin],
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@@ -1,296 +0,0 @@
<template>
<div>
<el-button
round
type="primary"
size="mini"
style="background: #66b1ff;border-color: #66b1ff"
@click.stop="showConfigurator"
>{{getActionDisplayName("theme-editor")}}</el-button>
<transition name="fade">
<div v-show="visible" class="configurator" ref="configurator">
<div
class="main-configurator"
ref="mainConfigurator"
>
<div v-if="currentConfig">
<main-panel
:currentConfig="currentConfig"
:defaultConfig="defaultConfig"
:userConfig="userConfig"
:globalValue="globalValue"
@onChange="userConfigChange"
></main-panel>
</div>
<div v-if="init && !currentConfig" class="no-config">
<img src="../../assets/images/theme-no-config.png" alt>
<span v-if="pageCouldEdit">{{getActionDisplayName("no-config")}}</span>
<span v-else>{{getActionDisplayName("no-need-config")}}</span>
</div>
<download-area></download-area>
</div>
</div>
</transition>
</div>
</template>
<style>
.configurator {
height: 100%;
width: 24%;
max-width: 400px;
position: fixed;
overflow-y: auto;
top: 79px;
right: 0;
bottom: 0;
background: #fff;
color: #666;
line-height: 24px;
padding-right: 1%;
}
.configurator .main-configurator {
height: 100%;
overflow: auto;
background: #F5F7FA;
border: 1px solid #EBEEF5;
box-shadow: 0 2px 10px 0 rgba(0,0,0,0.06);
border-radius: 8px;
width: 97%;
box-sizing: border-box;
margin: 0 .5% 0 5%;
}
.no-config {
margin-top: 130px;
text-align: center;
img {
width: 50%;
display: block;
margin: 0 auto;
}
span {
margin-top: 10px;
display: block;
color: #909399;
font-size: 14px;
}
}
.fade-enter,.fade-leave-to {
transform:translateX(100%);
}
.fade-enter-active ,.fade-leave-active {
transition:all 0.3s ease;
}
@media (min-width: 1600px) {
.configurator {
padding-right: calc((100% - 1600px) / 2);
}
}
</style>
<script>
import bus from '../../bus';
import { getVars, updateVars } from './utils/api.js';
import mainPanel from './main';
import {
filterConfigType,
filterGlobalValue,
updateDomHeadStyle,
getActionDisplayName
} from './utils/utils.js';
import DocStyle from './docStyle';
import Loading from './loading';
import Shortcut from './shortcut';
import DownloadArea from './download';
const ELEMENT_THEME_USER_CONFIG = 'ELEMENT_THEME_USER_CONFIG';
const DEFAULT_USER_CONFIG = {
global: {},
local: {}
};
export default {
components: {
mainPanel,
DownloadArea
},
data() {
return {
init: false,
visible: false,
defaultConfig: null,
currentConfig: null,
userConfig: {
global: {},
local: {}
},
lastApply: 0,
userConfigHistory: [],
userConfigRedoHistory: [],
hasLocalConfig: false
};
},
mixins: [DocStyle, Loading, Shortcut],
computed: {
globalValue() {
return filterGlobalValue(this.defaultConfig, this.userConfig);
},
pageCouldEdit() {
const noNeedEdit = ['installation', 'quickstart', 'i18n', 'custom-theme', 'transition'];
const lastPath = this.$route.path.split('/').slice(-1).pop();
return noNeedEdit.indexOf(lastPath) < 0;
}
},
mounted() {
this.checkLocalThemeConfig();
},
methods: {
getActionDisplayName(key) {
return getActionDisplayName(key);
},
showConfigurator() {
this.visible = !this.visible;
this.visible ? this.enableShortcut() : this.disableShortcut();
bus.$emit('user-theme-config-visible', this.visible);
window.userThemeConfigVisible = Boolean(this.visible);
if (this.init) return;
this.$nextTick(() => {
const loading = this.$loading({
target: this.$refs.configurator
});
let defaultConfig;
getVars()
.then((res) => {
defaultConfig = res;
ga('send', 'event', 'ThemeConfigurator', 'Init');
})
.catch((err) => {
this.onError(err);
})
.then(() => {
setTimeout(() => {
if (defaultConfig) {
this.defaultConfig = defaultConfig;
this.filterCurrentConfig();
this.init = true;
this.checkLocalThemeConfig();
}
loading.close();
}, 300); // action after transition
});
});
},
checkLocalThemeConfig() {
try {
if (this.hasLocalConfig) {
this.$message(getActionDisplayName('load-local-theme-config'));
this.onAction();
return;
}
const config = JSON.parse(localStorage.getItem(ELEMENT_THEME_USER_CONFIG));
if (config && config.global) {
this.userConfig = config;
this.hasLocalConfig = true;
this.showConfigurator();
}
} catch (e) {
// bad local config
}
},
filterCurrentConfig() {
this.currentConfig = this.defaultConfig.find((config) => {
return config.name === this.$route.path.split('/').pop().toLowerCase().replace('-', '');
});
},
userConfigChange(e) {
this.userConfigHistory.push(JSON.stringify(this.userConfig));
this.userConfigRedoHistory = [];
this.$set(this.userConfig[filterConfigType(this.currentConfig.name)], e.key, e.value);
this.onAction();
},
applyStyle(res, time) {
if (time < this.lastApply) return;
this.updateDocs(() => {
updateDomHeadStyle('chalk-style', res);
});
this.lastApply = time;
},
onDownload() {
return updateVars(Object.assign({}, this.userConfig, {download: true}), (xhr) => {
xhr.responseType = 'blob';
});
},
onReset() {
this.userConfig = {
global: {},
local: {}
};
this.onAction();
},
onAction() {
this.triggerComponentLoading(true);
const time = +new Date();
const currentConfigString = JSON.stringify(this.userConfig);
if (JSON.stringify(DEFAULT_USER_CONFIG) === currentConfigString) {
localStorage.removeItem(ELEMENT_THEME_USER_CONFIG);
} else {
localStorage.setItem(ELEMENT_THEME_USER_CONFIG, currentConfigString);
}
updateVars(this.userConfig)
.then((res) => {
this.applyStyle(res, time);
})
.catch((err) => {
this.onError(err);
})
.then(() => {
this.triggerComponentLoading(false);
});
},
onError(err) {
let message;
try {
message = JSON.parse(err).message;
} catch (e) {
message = err;
}
this.$message.error(message);
},
triggerComponentLoading(val) {
bus.$emit('user-theme-config-loading', val);
},
updateDocs(cb) {
window.userThemeConfig = JSON.parse(JSON.stringify(this.userConfig));
bus.$emit('user-theme-config-update', this.userConfig);
this.updateDocStyle(this.userConfig, cb);
},
undo() {
if (this.userConfigHistory.length > 0) {
this.userConfigRedoHistory.push(JSON.stringify(this.userConfig));
this.userConfig = JSON.parse(this.userConfigHistory.pop());
this.onAction();
}
},
redo() {
if (this.userConfigRedoHistory.length > 0) {
this.userConfigHistory.push(JSON.stringify(this.userConfig));
this.userConfig = JSON.parse(this.userConfigRedoHistory.shift());
this.onAction();
}
}
},
watch: {
'$route.path'() {
this.defaultConfig && this.filterCurrentConfig();
if (!this.$refs.mainConfigurator) return;
this.$nextTick(() => {
this.$refs.mainConfigurator.scrollTop = 0;
});
}
}
};
</script>

View File

@@ -1,35 +0,0 @@
<style>
.loadingClass {
z-index: 0!important;
.el-loading-spinner {
top: 0%;
margin-top: 30%;
}
}
</style>
<script>
import bus from '../../bus.js';
import './progress.js';
export default {
data() {
return {
count: 0
};
},
created() {
bus.$on('user-theme-config-loading', val => {
if (val) {
this.count++;
if (this.count > 1) return;
this.$bar.start();
} else {
this.count--;
if (this.count) return;
this.$bar.finish();
}
});
}
};
</script>

View File

@@ -1,124 +0,0 @@
<template>
<div class="main">
<!-- <span>{{configName}}</span> -->
<div v-for="(config, key) in configByOrder" :key="key">
<span
v-if="showCategory(config.category, key + 1)"
class="category-name"
>
{{getCategoryDisplayName(config.category)}}
</span>
<component
:is="editorComponent(config.type)"
:componentName=configName
:config=config
:userConfig=userConfigByType
:golbalValue=globalValue
@onChange=onChange
>
</component>
</div>
</div>
</template>
<style>
.main {
margin-bottom: 140px;
padding: 10px;
}
.category-name {
color: #C0C4CC;
font-size: 18px;
display: block;
margin: 8px 0 4px 0;
}
</style>
<script>
import ColorEditor from './editor/color';
import fontWeightEditor from './editor/fontWeight';
import fontSizeEditor from './editor/fontSize';
import fontLineHeightEditor from './editor/fontLineHeight';
import borderRadiusEditor from './editor/borderRadius';
import boxShadowEditor from './editor/boxShadow';
import simpleTextEditor from './editor/simpleText';
import { filterConfigType, getCategoryDisplayName } from './utils/utils.js';
export default {
components: {
ColorEditor,
fontSizeEditor,
fontLineHeightEditor,
simpleTextEditor,
borderRadiusEditor,
boxShadowEditor,
fontWeightEditor
},
props: {
defaultConfig: {
type: Array
},
currentConfig: {
type: Object
},
userConfig: {
type: Object
},
globalValue: {
type: Object
}
},
computed: {
configName() {
return this.currentConfig.name;
},
userConfigByType() {
return this.userConfig[filterConfigType(this.configName)];
},
configByOrder() {
return this.currentConfig.config.sort((a, b) => (a.order - b.order));
}
},
methods: {
getCategoryDisplayName(key) {
return getCategoryDisplayName(key);
},
editorComponent(type) {
switch (type) {
case 'color':
return ColorEditor;
case 'fontWeight':
return fontWeightEditor;
case 'fontSize':
return fontSizeEditor;
case 'fontLineHeight':
return fontLineHeightEditor;
case 'borderRadius':
return borderRadiusEditor;
case 'boxShadow':
return boxShadowEditor;
default:
return simpleTextEditor;
}
},
onChange(e) {
this.$emit('onChange', e);
},
showCategory(name, key) {
if (!name) {
return false;
}
if (!this.categoryDisplay[name] || this.categoryDisplay[name] === key) {
this.categoryDisplay[name] = key;
return true;
}
return false;
}
},
data() {
return {
categoryDisplay: {}
};
}
};
</script>

View File

@@ -1,6 +0,0 @@
import Vue from 'vue';
import ProgressBar from './progress.vue';
Vue.prototype.$bar = new Vue(ProgressBar).$mount();
document.body.appendChild(Vue.prototype.$bar.$el);

View File

@@ -1,108 +0,0 @@
<template>
<div class="progress" :style="{
'width': percent+'%',
'height': height,
'background-color': canSuccess? successColor() : failedColor(),
'opacity': show ? 1 : 0
}"></div>
</template>
<script>
/* eslint-disable */
export default {
data () {
return {
percent: 0,
show: false,
canSuccess: true,
duration: 3000,
height: '2px'
}
},
methods: {
successColor() {
return this.userSelectColor()['$--color-primary'] || '#409EFF';
},
failedColor() {
return this.userSelectColor()['$--color-danger'] || '#F56C6C';
},
userSelectColor() {
return window.userThemeConfig && window.userThemeConfig.global || {}
},
start () {
this.show = true
this.canSuccess = true
if (this._timer) {
clearInterval(this._timer)
this.percent = 0
}
// Code from Nuxt.js!
this._cut = 10000 / Math.floor(this.duration)
this._timer = setInterval(() => {
this.increase(this._cut * Math.random())
if (this.percent >= 90) {
this.percent = 90;
}
}, 100)
return this
},
set (num) {
this.show = true
this.canSuccess = true
this.percent = Math.floor(num)
return this
},
get () {
return Math.floor(this.percent)
},
increase (num) {
this.percent = this.percent + Math.floor(num)
return this
},
decrease (num) {
this.percent = this.percent - Math.floor(num)
return this
},
finish () {
this.percent = 100
this.hide()
return this
},
pause () {
clearInterval(this._timer)
return this
},
hide () {
clearInterval(this._timer)
this._timer = null
setTimeout(() => {
this.show = false
this.$nextTick(() => {
setTimeout(() => {
this.percent = 0
}, 200)
})
}, 500)
return this
},
fail () {
this.canSuccess = false
return this
}
}
}
</script>
<style scoped>
.progress {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
height: 2px;
width: 0%;
transition: width 0.2s, opacity 0.4s;
opacity: 1;
z-index: 999999;
}
</style>

View File

@@ -1,27 +0,0 @@
<script>
export default {
data() {
return {
downloading: false
};
},
methods: {
shortcut(e) {
if (e.keyCode === 90 && (e.ctrlKey || e.metaKey)) {
if (e.shiftKey) {
this.redo();
} else {
this.undo();
}
}
},
enableShortcut() {
document.addEventListener('keydown', this.shortcut);
},
disableShortcut() {
document.removeEventListener('keydown', this.shortcut);
}
}
};
</script>

View File

@@ -1,65 +0,0 @@
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);
};

View File

@@ -1,20 +0,0 @@
import Element from 'main/index.js';
import { post, get } from './ajax';
const { version } = Element;
const hostList = {
local: 'http://localhost:3008/',
alpha: 'https://ssr.alpha.elenet.me/element-theme-server/',
production: 'https://ssr.elenet.me/element-theme-server/'
};
const host = hostList[process.env.FAAS_ENV] || hostList.production;
export const getVars = () => {
return get(`${host}getVariable?version=${version}`);
};
export const updateVars = (data, cb) => {
return post(`${host}updateVariable?version=${version}`, data, cb);
};

View File

@@ -1,59 +0,0 @@
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(', ');

View File

@@ -1,82 +0,0 @@
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}-`, '').replace();
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;
};
export const getCategoryDisplayName = (key) => {
return getNameFromI18N('category')[key] || key;
};
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{[^}]+}/, '');
};

View File

@@ -5,11 +5,11 @@
v-model="theme"></el-color-picker>
</template>
<style lang="scss">
<style>
.theme-picker {
height: 80px;
display: inline-block;
// @utils-vertical-center;
@utils-vertical-center;
}
.theme-picker .el-color-picker__trigger {

View File

@@ -1,7 +0,0 @@
.demo-block.demo-alert .el-alert {
margin: 20px 0 0;
}
.demo-block.demo-alert .el-alert:first-child {
margin: 0;
}

View File

@@ -1,19 +0,0 @@
.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;
}
}

View File

@@ -1,44 +0,0 @@
.demo-border .text {
width: 15%;
}
.demo-border .line {
width: 70%;
}
.demo-border .line div {
width: 100%;
height: 0;
border: 1px solid #eee;
}
.demo-border .line .dashed {
border: 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;
}

View File

@@ -1,21 +0,0 @@
.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;
}
}
}

View File

@@ -1,33 +0,0 @@
.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;
}
}

View File

@@ -1,47 +0,0 @@
.demo-carousel .block {
padding: 30px;
text-align: center;
border-right: solid 1px #eff2f6;
display: inline-block;
width: 50%;
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;
}
&:nth-child(2n) {
background-color: #99a9bf;
}
&:nth-child(2n + 1) {
background-color: #d3dce6;
}
}
.demo-carousel .small h3 {
font-size: 14px;
line-height: 150px;
}
.demo-carousel .medium h3 {
font-size: 14px;
line-height: 200px;
}

View File

@@ -1,30 +0,0 @@
.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;
}

View File

@@ -1,7 +0,0 @@
.demo-collapse {
.el-collapse-item__header {
.header-icon {
margin-left: 5px;
}
}
}

View File

@@ -1,20 +0,0 @@
.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;
}

View File

@@ -1,72 +0,0 @@
.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,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M0 98 L100 0 L100 1 L1 98' fill='%23FCC3C3' /></svg>");
background-repeat: no-repeat;
background-position: center center;
background-size: 100% 100%, auto;
}
.demo-color-box-lite {
color: #303133;
}

View File

@@ -1,43 +0,0 @@
.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;
}
}
}

View File

@@ -1,36 +0,0 @@
.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;
}

View File

@@ -1,21 +0,0 @@
.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;
}

View File

@@ -1,20 +0,0 @@
.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;
}
}

View File

@@ -1,37 +0,0 @@
.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;
}

Some files were not shown because too many files have changed in this diff Show More