Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
799c42d337 | ||
|
|
ef33295a54 | ||
|
|
c71ad7f471 | ||
|
|
8cf15eda72 |
12
.babelrc
@@ -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"],
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"globals": {
|
||||
"ga": true
|
||||
"expect": true,
|
||||
"sinon": true
|
||||
},
|
||||
"plugins": ["html", "json"],
|
||||
"extends": "elemefe",
|
||||
|
||||
2
.github/CONTRIBUTING.en-US.md
vendored
@@ -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
|
||||
|
||||
4
.github/CONTRIBUTING.es.md
vendored
@@ -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:
|
||||
|
||||
```
|
||||
|
||||
60
.github/CONTRIBUTING.fr-FR.md
vendored
@@ -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).
|
||||
2
.github/CONTRIBUTING.zh-CN.md
vendored
@@ -41,8 +41,6 @@ npm run dev
|
||||
# open http://localhost:8085
|
||||
```
|
||||
|
||||
> **提示**:可以运行 `npm run dev:play`,修改 `examples/play/index.vue` 文件,调用你修改后的组件,仍然访问 http://localhost:8085,查看修改效果,更快更方便。
|
||||
|
||||
打包代码:
|
||||
|
||||
```shell
|
||||
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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 file,add new components (by @ziyoung in #13773)
|
||||
|
||||
#### Bug fixes
|
||||
- Autocomplete
|
||||
- Fix dropdown's last line beging clipped (by @ziyoung in #13597)
|
||||
- Fix missing popper arrow (by @liuchuzhang in #13762)
|
||||
- Carousel
|
||||
- Cleanup timer when component is destroyed (by @elfman in #13820)
|
||||
- Cascader
|
||||
- Remove deprecated property of computed props (by @iamkun in #13737)
|
||||
- Fix CascaderOption's type definition in TypeScript (by @NateScarlet in #13613)
|
||||
- Fix icon covering the text (by @ziyoung in #13596)
|
||||
- Checkbox
|
||||
- Refine style (by @PanJiaChen)
|
||||
- DatePicker
|
||||
- Add missing v-for `key` in TimeSpinner (by @Ende93 in #13547)
|
||||
- Fix week highlight on year boundary (by @suyi91 in #13883)
|
||||
- Input
|
||||
- Fix textarea DOM node reference (by @laomu1988 @island205 in #13803)
|
||||
- Pagination
|
||||
- Input value won't be less than 1 (by @elfman in #13727)
|
||||
- Popover
|
||||
- Fix popover issues with hover trigger (by @goldengecko in #13104)
|
||||
- Fix popper instance memory leak (by @qpxtWhite in #13988)
|
||||
- Radio
|
||||
- Refine style (by @ohhoney1)
|
||||
- Table
|
||||
- Enhanced table sorting when clicking on the sorting arrow (by @ohhoney1 in #12890)
|
||||
- Fix empty text vertical alignment issue on IE10+ (by @imzjy in #13638)
|
||||
- Fix index type documentation (by @ilovefafa in #13628)
|
||||
- Fix `show-summary` display issue when multilevel header has fixed attr (by @luckyCao in #13914)
|
||||
- Tabs
|
||||
- Fix auto scroll bug (by @iamkun in #13696)
|
||||
- Get the correct tab through tab name (by @iamkun in #13705)
|
||||
- Use paneName instead of name to determine pane style (by @iamkun in #13733)
|
||||
- Tree
|
||||
- Fix `showCheckbox` prop on `Tree` can not affect their children `tree-node` (by @KidneyFlower)
|
||||
- Update doc and definition file (by @ziyoung in #13540)
|
||||
- Upload
|
||||
- Add `url` prop to upload file when `list-type` changed (by @elfman in #13771)
|
||||
- Slider
|
||||
- Fix source code indentation (by @wacky6 in #13955)
|
||||
- I18n
|
||||
- Add missing Catalan translations (by @jaumesala)
|
||||
- Add missing ru translation (by @justlp in #13658)
|
||||
- Fix Finnish translations (by @jenkrisu in #14137)
|
||||
- Doc
|
||||
- Update Spanish doc 2.4.11 (by @Gonzalo2310 in #13522)
|
||||
- Others
|
||||
- Remove unnecessary script (by @ziyoung)
|
||||
- Fix error anchor link (by @iamkun in #13753)
|
||||
- Fix inconsistent capitalization in documentation (by @wonderjar)
|
||||
- Add DingDing chat group qr code to readme (by @iamkun in #13957)
|
||||
- Add yarn logs to .gitignore (by @mimimi in #13922)
|
||||
- Remove sponsor duotai (by @island205 in #14156)
|
||||
- Update readme qr code src (by @iamkun in #13960)
|
||||
- Update CDN link, fix typo (by @ziyoung)
|
||||
|
||||
### 2.4.11
|
||||
|
||||
*2018-11-21*
|
||||
|
||||
- Revert pr #13296. Fixed clicking on Menu external causing Submenu collapsed, #13478
|
||||
- Adjust small screen (xs) media query breakpoints, #13468 (by @alekoshen712)
|
||||
|
||||
### 2.4.10
|
||||
|
||||
*2018-11-16*
|
||||
|
||||
- Fixed multiple clicks on Select to display the drop-down list, #13268
|
||||
- The clear icon for input is not displayed when Form is disabled, #13208
|
||||
- Adjust the style of Select, Progress, Autocomplete, Tooltip, Collaspe, TimePicker, #13188 (by @porcelainHeart) #13210 #13266 #13257 #13290 #13347 (by @PanJiaChen)
|
||||
- Carousel component added `loop` attribute, #13217
|
||||
- When the data of Table changes, the highlighted line will remain, #13200
|
||||
- Table header scoped slot can receive parameters, #13263
|
||||
- Table's `clearFilter` method supports arguments, #13176
|
||||
- Tooltip is no longer created when there is no content in the Table cell, #13152 (by @rongxingsun)
|
||||
- The input box contents of the ColorPicker panel can be displayed correctly, #13278
|
||||
- ColorPicker no longer triggers form validation when dragging, #13299
|
||||
- InputNumber added `select `method, #13286 (by @st-sloth)
|
||||
- Autocomplete added `clear` event, #12171(by arthurdenner) #13326
|
||||
- You can close Menu by clicking on Menu outside, #13296
|
||||
- Form's `validateField` method can receive arguments, #13319
|
||||
- Cascader added `visible-change` event, #13415
|
||||
- DatePicker added range-separator slot, #13272 (by @milworm)
|
||||
- Tree adds `iconClass` and `currentNodeKey` properties, #13337 #13197 (by @isnifer)
|
||||
- Progress's` status` added text #13198 (by @ali-master)
|
||||
- Fixing tree's `defaultCheckedKeys` caused an error, #13349 (by @dive2Pro)
|
||||
|
||||
### 2.4.9
|
||||
|
||||
*2018-10-26*
|
||||
|
||||
- The parameter of Form's `clearValidate` supports string, #12990 (by @codinglobster)
|
||||
- Added type attribute for Badge, #12991
|
||||
- Users can use scoped-slot to customize table column header #13012 (by @ivanseidel)
|
||||
- Fixed the input box of Select unable to type text under IE, #13034 (by @GaliMU)
|
||||
- Select option does not wrap when space is enough, #12329 (by @akki-jat)
|
||||
- When dropdown list of Select is expanded, the arrow icon will also display correctly, #12353 (by @firesh)
|
||||
- Fixed that the size attribute of Select does not work, #13070
|
||||
- Select multiple values can be cleared, #13049 (by @ZSkycat)
|
||||
- Fixed the last TabNav unable be deleted, #13039
|
||||
- Fixed that TabNav label is not displayed correctly, #13178
|
||||
- Added title slot for Alert, #13082 (by @Kingwl)
|
||||
- Fixed an issue where the tooltip content in Table was incorrect, #13159 (by @elfman)
|
||||
- Optimize the animation of Upload when file is deleted, #12987
|
||||
- Adjusted style of InputNumber when control button is not displayed, #13052
|
||||
|
||||
### 2.4.8
|
||||
|
||||
- Not displaying outline when Switch is focused, #12771
|
||||
- Fixed Dropdown's style in ButtonGroup, #12819 (by @bluejfox)
|
||||
- Added opened event for Dialog, #12828
|
||||
- Fixed the incorrect display order of TabNav, #12846
|
||||
- Fixed the problem that Tabs did not scroll to the selected tab, #12948
|
||||
- Fixed the problem that the identifier does not display when the Tree node is dragged, #12854
|
||||
- The validate event parameter of Form contains the validation message, #12860 (by @YamenSharaf)
|
||||
- Fixed DatePicker not to verify the validity of user input time, #12898
|
||||
- Fixed the problem that `render-header` attribute of Table header doesn't work, #12914
|
||||
|
||||
### 2.4.7
|
||||
|
||||
*2018-09-14*
|
||||
|
||||
- Fixed DatePicker not triggering form validation, #12328 #12348
|
||||
- Fixed DatePicker throwing errors in multiple mode, #12347
|
||||
- Fixed incorrect position of DatePicker spinner, #12415 (by @rang-ali)
|
||||
- Fixed automatic filling of DatePicker input box, #12521 (by @abdallanayer)
|
||||
- Fixed Input not highlighted in Cascader, #12341
|
||||
- Fixed wrong order of Tabpane, #12346
|
||||
- Fixed incorrect position of ColorPicker cursor, #12376 (by @cnwhy)
|
||||
- Fixed the style of Submenu, #2457
|
||||
- Fixed not highlighted after Submenu is selected, #12479
|
||||
- Fixed incorrect values selected by Cascader, #12508 (by @huangjinqiang)
|
||||
- Fixed incorrect value of Pagination input box, #12525
|
||||
- Fixed order that Pagination triggers events, #12530
|
||||
- Fixed Table Filter not displayed, #12539
|
||||
- Fixed Tree unable to delete nodes, #12684
|
||||
- Fixed height of Select Input changing in single mode, #12719
|
||||
- Fixed style of FormItem label in nested Form, #12748
|
||||
- Added `autocomplete` attribute for Input, deprecated `auto-complete`, #12514 (by @axetroy)
|
||||
- Added slots-scope for Form to display validation information, #12715 (by @YamenSharaf)
|
||||
|
||||
### 2.4.6
|
||||
|
||||
*2018-08-09*
|
||||
@@ -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, #11167(by @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, #10174(by @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, #9188(by @kolesoffac)
|
||||
- Fixed the border of the last column of the grouped header not properly displayed, #9326
|
||||
- Fixed incorrect positioning of table header in Safari, #9327
|
||||
- Fixed expanded row collapsing when the table data changes, #9462
|
||||
@@ -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>
|
||||
421
CHANGELOG.es.md
@@ -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>
|
||||
1080
CHANGELOG.fr-FR.md
@@ -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
|
||||
- 调整 Select,Progress,Autocomplete,Tooltip,Collaspe,TimePicker 的样式,#13188 (by @porcelainHeart) #13210 #13266 #13257 #13290 #13347 (by @PanJiaChen)
|
||||
- Carousel 组件新增 `loop` 属性,#13217
|
||||
- Table 的 data 改变时,高亮行会继续保留,#13200
|
||||
- Table 的 header slot 可以接收参数,#13263
|
||||
- Table 的 `clearFilter` 方法支持参数,#13176
|
||||
- Table 单元格内没有内容时不再创建 Tooltip,#13152 (by @rongxingsun)
|
||||
- ColorPicker 面板的输入框内容可以正常显示了,#13278
|
||||
- 在拖拽时,ColorPicker 不再触发表单校验,#13299
|
||||
- InputNumber 新增 `select` 方法,#13286 (by @st-sloth)
|
||||
- Autocomplete 新增 `clear` 事件,#12171(by arthurdenner) #13326
|
||||
- 可以通过点击 Menu 外部来关闭 Menu,#13296
|
||||
- Form 的 `validateField` 方法可以接收参数,#13319
|
||||
- Cascader 新增 `visible-change` 事件,#13415
|
||||
- DatePicker 新增 range-separator slot, #13272 (by @milworm)
|
||||
- Tree 新增 `iconClass` 与 `currentNodeKey` 属性,#13337 #13197 (by @isnifer)
|
||||
- Progress 的 `status` 添加了 text #13198 (by @ali-master)
|
||||
- 修复 Tree 的 `defaultCheckedKeys` 导致显示的错误,#13349 (by @dive2Pro)
|
||||
|
||||
### 2.4.9
|
||||
|
||||
*2018-10-26*
|
||||
|
||||
- Form 组件 clearValidate 方法参数支持字符串,#12990 (by @codinglobster)
|
||||
- Badge 新增 type 属性,#12991
|
||||
- 用户可以使用 scoped-slot 来自定义表头,#13012(by @ivanseidel)
|
||||
- 修复 IE 下 Select 输入框不能输入的问题,#13034(by @GaliMU)
|
||||
- Select 多选时,选项不换行,#12329 (by @akki-jat)
|
||||
- Select 下拉列表展开后,箭头图标也可以正确显示,#12353(by @firesh)
|
||||
- 修复 Select 的 size 属性不生效的问题,#13070
|
||||
- 多选时可以清除 Select 已选中的值,#13049(by @ZSkycat)
|
||||
- 修复最后一个 TabNav 不能删除的问题,#13039
|
||||
- 修复 TabNav 中 label 显示不正确的问题,#13178
|
||||
- Alert 新增 title slot,#13082(by @Kingwl)
|
||||
- 修复 Table 中的 tooltip 内容不正确的问题,#13159(by @elfman)
|
||||
- 优化 Upload 文件列表删除时的动画,#12987
|
||||
- 当 InputNumber 控制按钮不显示时,调整了边距,#13052
|
||||
|
||||
### 2.4.8
|
||||
|
||||
- Switch 聚焦时不显示轮廓,#12771
|
||||
- 修复 Dropdown 在 ButtonGroup 中样式问题,#12819 (by @bluejfox)
|
||||
- Dialog 新增 opened 事件,#12828
|
||||
- 修复 TabNav 显示顺序不正确的问题,#12846
|
||||
- 修复 Tabs 没有滑动到选中 tab 的问题,#12948
|
||||
- 修复 Tree 节点在拖拽时标识符不显示的问题,#12854
|
||||
- Form 的 validate 事件参数中包含了校验的信息,#12860 (by @YamenSharaf)
|
||||
- 修复 DatePicker 没有校验用户输入时间的合法性问题,#12898
|
||||
- 修复 Table 表头的 `render-header`属性不生效的问题,#12914
|
||||
|
||||
### 2.4.7
|
||||
|
||||
*2018-09-14*
|
||||
|
||||
- 修复 DatePicker 未触发表单检验的问题,#12328,#12348
|
||||
- 修复 DatePicker 多选时报错的问题,#12347
|
||||
- 修复 DatePicker 选择时间时 spinner 位置不正确的问题,#12415 (by @rang-ali)
|
||||
- 修复 Datepicker 输入框自动填充的问题,#12521 (by @abdallanayer)
|
||||
- 修复 Cascader 中 Input 未高亮的问题,#12341
|
||||
- 修复 Tabpane 顺序不正确的问题,#12346
|
||||
- 修复 ColorPicker 取色光标位置不正确的问题,#12376 (by @cnwhy)
|
||||
- 调整 Submenu 的样式,#12457
|
||||
- 修复 Submenu 选中后没有高亮的问题,#12479
|
||||
- 修复 Cascader 选择值不正确的问题,#12508 (by @huangjinqiang)
|
||||
- 修复 Pagination 输入框值不正确的问题,#12525
|
||||
- 调整 Pagination 触发事件的顺序,#12530
|
||||
- 修复 Table 的 filter 不显示的问题,#12539
|
||||
- 修复 Tree 无法删除节点的问题,#12684
|
||||
- 修复 Select 在单选时 Input 高度变化的问题,#12719
|
||||
- 修复 Form 在嵌套时 label 显示不正确的问题,#12748
|
||||
- 新增 Input 的 autocomplete 属性,废弃 auto-complete 属性,#12514 (by @axetroy)
|
||||
- 新增 Form 的 slot-scope 展示表单校验信息,#12715 (by @YamenSharaf)
|
||||
|
||||
### 2.4.6
|
||||
|
||||
*2018-08-09*
|
||||
@@ -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>
|
||||
19
README.md
@@ -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.
|
||||
|
||||
[](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
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
];
|
||||
};
|
||||
|
||||
@@ -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/**
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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');
|
||||
};
|
||||
@@ -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);
|
||||
};
|
||||
};
|
||||
@@ -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}
|
||||
`;
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
};
|
||||
@@ -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*)?$/,
|
||||
|
||||
@@ -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*)?$/,
|
||||
|
||||
@@ -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*)?$/,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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*)?$/,
|
||||
|
||||
@@ -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>
|
||||
|
||||
16
examples/assets/images/duotai.svg
Normal 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 |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
3108
examples/assets/restaurants.json
Normal 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 {
|
||||
|
||||
@@ -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 }`;
|
||||
}
|
||||
};
|
||||
@@ -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];
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
<style>
|
||||
.footer-nav {
|
||||
padding: 40px 0;
|
||||
color: #333;
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
<style>
|
||||
.footer {
|
||||
background-color: #F7FBFD;
|
||||
width: 100%;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -1,8 +0,0 @@
|
||||
import ColorPicker from './src/main';
|
||||
|
||||
/* istanbul ignore next */
|
||||
ColorPicker.install = function(Vue) {
|
||||
Vue.component(ColorPicker.name, ColorPicker);
|
||||
};
|
||||
|
||||
export default ColorPicker;
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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(', ');
|
||||
@@ -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{[^}]+}/, '');
|
||||
};
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
.demo-block.demo-alert .el-alert {
|
||||
margin: 20px 0 0;
|
||||
}
|
||||
|
||||
.demo-block.demo-alert .el-alert:first-child {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
.demo-collapse {
|
||||
.el-collapse-item__header {
|
||||
.header-icon {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||