Compare commits

..

4 Commits
dev ... next

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

* Timeline: add timeline component

* Timeline: add test case

* Timeline: fix icon class

* Timeline: update docs

* Timeline: fix test case

* Timeline: remove pending attribute

* Timeline: fix docs

* Timeline: make reverse default to false

* Timline: fix test case

* Timeline: update element-ui.d.ts

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

* Chore: upgrade to webpack@4

* Chore: add babel-preset-stage-2

* Chore: fix test case

* Chore: upgrade webpack@4

* Docs: update docs

* Docs: update docs

* Chore: fix coveralls

* Chore: update yarn.lock
2018-08-28 17:18:20 +08:00
851 changed files with 28481 additions and 96530 deletions

View File

@@ -15,18 +15,6 @@
"plugins": ["transform-vue-jsx"],
"env": {
"utils": {
"presets": [
[
"env",
{
"loose": true,
"modules": "commonjs",
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}
],
],
"plugins": [
["module-resolver", {
"root": ["element-ui"],

View File

@@ -1,6 +1,5 @@
src/utils/popper.js
src/utils/date.js
src/utils/lodash.js
examples/play
*.sh
node_modules

View File

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

View File

@@ -43,8 +43,6 @@ npm run dev
# open http://localhost:8085
```
> **Notice**: modify `examples/play/index.vue` file, use the component you contribute, then run `npm run dev:play`, go ahead [http://localhost:8085](http://localhost:8085), get result, more quickly and friendly.
To build:
```shell

View File

@@ -37,7 +37,7 @@ Estamos orgullosos de que usted esta interesado en contribuir al proyecto `Eleme
- Fusión de un PR requiere dos mantenedores: el primero aprueba los cambios después de revisar, y entonces el segundo mantenedor revisa los cambios y hace la fusión.
## Requerimientos Técnicos
## Requerimientos Técnicos
`Node.js 4+`, `yarn` y `npm 3+` son requisitos. Nota: Usamos yarn para bloquear versiones de dependencias, por lo que debería instalar dependencias usando `yarn` en lugar de `npm install`.
.
```shell
@@ -47,8 +47,6 @@ npm run dev
# abra http://localhost:8085
```
> **Notice**: modify `examples/play/index.vue` file, use the component you contribute, then run `npm run dev:play`, go ahead [http://localhost:8085](http://localhost:8085), get result, more quickly and friendly.
Para armar:
```

View File

@@ -1,60 +0,0 @@
# Guide à destination des contributeurs d'Element UI
Bonjour! Merci d'avoir choisi Element UI.
Element UI est une bibliothèque de composants basée sur Vue 2.0 pour les développeurs, les designers et les chefs de produits.
Nous sommes ravis que vous souhaitiez contribuer à Element. Avant de soumettre votre contribution, veuillez vous assurer de prendre un moment pour lire les indications suivantes.
## Concernant les issues
- Les issues concernent exclusivement les bugs, les demandes de fonctionnalités et les sujets liés à la conception. Les questions concernant d'autres sujets peuvent être fermées directement. Si vous avez des questions à propos de l'utilisation d'Element, veuillez vous rendre sur [Gitter](https://gitter.im/element-en/Lobby) pour obtenir de l'aide.
- Avant de soumettre une issue, veuillez vérifier si des problèmes similaires n'ont pas déjà été signalés.
- Veuillez spécifier la version de `Element` et `Vue` que vous utilisez, et fournir des informations sur le système d'exploitation et le navigateur. [JSFiddle](https://jsfiddle.net/) est recommandé afin de construire une démo pour que votre problème puisse être reproduit clairement.
## Concernant les pull requests
- Faites un fork de ce dépôt vers votre compte. Ne créez pas de branches ici.
- Les informations de validation doivent être formatées en tant que `[Nom du composant] : Info à propos de ce commit` (par exemple `Button : Fix xxx bug`)
- **NE PAS** inclure de fichiers dans le répertoire `lib`.
- Assurez-vous que l'exécution de `npm run dist` génère les bons fichiers.
- Pour des raisons de compatibilité et de taille de fichier, notre configuration babel n'importait que `preset-2015`, donc les API comme `Array.prototype.find` et `Object.assign` dans `ES2015` ne sont pas recommandées. Vous pouvez importer des polyfills si nécessaire.
- Faites un rebase avant la création d'une PR pour garder l'historique clair.
- Assurez-vous que les PRs sont créés dans la branche `dev` au lieu de la branche `master`.
- Si votre PR corrige un bug, veuillez fournir une description du bug en question.
- La fusion d'un PR nécessite deux responsables: l'un approuve les modifications après révision, puis l'autre les révise et les fusionne.
## Pré-requis
`Node.js 4+`, `yarn` et `npm 3+` sont requis. Note: nous utilisons yarn pour verrouiller les versions des dépendances, donc vous devriez installer les dépendances en utilisant `yarn` au lieu de `npm install`.
```shell
git clone git@github.com:ElemeFE/element.git
npm run dev
# open http://localhost:8085
```
> **Remarque** : modifiez le fichier `examples/play/index.vue`, utilisez le composant auquel vous contribuez, puis lancez `npm run dev:play`, allez sur [http://localhost:8085](http://localhost:8085), regardez le résultat rapidement et facilement.
Pour le build:
```shell
npm run dist
```
## Concernant le développement de composants
- Exécutez `make new <nom-du-composant>` pour créer un répertoire pour le nouveau composant. Les tests, le fichier d'entrée et la documentation sont inclus.
- Reportez-vous au `Button` pour les composants imbriqués.
- Reportez-vous à `Select` pour connaître les composants qui dépendent d'autres composants.
## Style du code
Il suffit de se conformer à la configuration [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) de [ElemeFE](https://github.com/elemefe).

View File

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

View File

@@ -1,5 +0,0 @@
blank_issues_enabled: true
contact_links:
- name: Create new issue
url: https://elementui.github.io/issue-generator
about: The issue which is not created via https://elementui.github.io/issue-generator will be closed immediately.

View File

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

17
.github/stale.yml vendored
View File

@@ -1,17 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 365
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
# exemptLabels:
# - pinned
# - security
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@@ -1,45 +0,0 @@
name: Preview Build
on: pull_request
jobs:
build:
name: Build
runs-on: ubuntu-latest
env:
PULL_REQUEST_NUMBER: ${{ github.event.number }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '10.15.0'
registry-url: https://registry.npmjs.com/
- name: Build
run: npm run bootstrap && npm run deploy:build
# share website dist
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: docs
path: examples/element-ui/
retention-days: 1
# write pr.txt for share
- name: Save pr number
if: ${{ always() }}
run: echo ${PULL_REQUEST_NUMBER} > ./pr.txt
# share pr number
- name: Upload pr number
if: ${{ always() }}
uses: actions/upload-artifact@v2
with:
name: pr
path: ./pr.txt
retention-days: 1

View File

@@ -1,83 +0,0 @@
name: Preview Deploy
on:
workflow_run:
workflows: ['Preview Build']
types:
- completed
jobs:
success:
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
steps:
- name: download pr artifact
uses: dawidd6/action-download-artifact@v2
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: pr
- name: save PR id
id: pr
run: echo "::set-output name=id::$(<pr.txt)"
- name: download docs artifact
uses: dawidd6/action-download-artifact@v2
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
workflow_conclusion: success
name: docs
- name: upload surge service
id: deploy
run: |
export DEPLOY_DOMAIN=https://preview-pr-${{ steps.pr.outputs.id }}-element-ui.surge.sh
npx surge --project ./ --domain $DEPLOY_DOMAIN --token ${{ secrets.SURGE_TOKEN }}
- name: update status comment
uses: actions-cool/maintain-one-comment@v1.2.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
body: |
🎊 PR Preview has been successfully built and deployed to https://preview-pr-${{ steps.pr.outputs.id }}-element-ui.surge.sh
<img width="300" src="https://user-images.githubusercontent.com/507615/90250366-88233900-de6e-11ea-95a5-84f0762ffd39.png">
<!-- Sticky Pull Request Comment -->
body-include: '<!-- Sticky Pull Request Comment -->'
number: ${{ steps.pr.outputs.id }}
- name: The job failed
if: ${{ failure() }}
uses: actions-cool/maintain-one-comment@v1.2.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
body: |
😭 Deploy PR Preview failed.
<img width="300" src="https://user-images.githubusercontent.com/507615/90250824-4e066700-de6f-11ea-8230-600ecc3d6a6b.png">
<!-- Sticky Pull Request Comment -->
body-include: '<!-- Sticky Pull Request Comment -->'
number: ${{ steps.pr.outputs.id }}
failed:
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'failure'
steps:
- name: download pr artifact
uses: dawidd6/action-download-artifact@v2
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: pr
- name: save PR id
id: pr
run: echo "::set-output name=id::$(<pr.txt)"
- name: The job failed
uses: actions-cool/maintain-one-comment@v1.2.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
body: |
😭 Deploy PR Preview failed.
<img width="300" src="https://user-images.githubusercontent.com/507615/90250824-4e066700-de6f-11ea-8230-600ecc3d6a6b.png">
<!-- Sticky Pull Request Comment -->
body-include: '<!-- Sticky Pull Request Comment -->'
number: ${{ steps.pr.outputs.id }}

6
.gitignore vendored
View File

@@ -1,12 +1,8 @@
node_modules
.DS_Store
npm-debug.log
yarn-debug.log
yarn-error.log
lerna-debug.log
npm-debug.log.*
yarn-debug.log.*
yarn-error.log.*
lerna-debug.log.*
lib
.idea
@@ -15,11 +11,9 @@ examples/element-ui
examples/pages/en-US
examples/pages/zh-CN
examples/pages/es
examples/pages/fr-FR
fe.element/element-ui
.npmrc
coverage
waiter.config.js
build/bin/algolia-key.js
.envrc
.history/

View File

@@ -1,9 +1,10 @@
sudo: false
language: node_js
node_js: 10
addons:
chrome: stable
node_js: lts/*
before_install:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- export TRAVIS_COMMIT_MSG="[deploy] $(git log --format='%h - %B' --no-merges -n 1)"
- export TRAVIS_COMMIT_USER="$(git log --no-merges -n 1 --format=%an)"
- export TRAVIS_COMMIT_EMAIL="$(git log --no-merges -n 1 --format=%ae)"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

123
README.md
View File

@@ -36,23 +36,45 @@
</a>
</p>
<p align="center">
<b>Special thanks to the generous sponsorship by:</b>
</p>
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://tipe.io/?ref=element" target="_blank">
<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">
</a>
</td>
<td align="center" valign="middle">
<a href="https://bitsrc.io/" target="_blank">
<img width="150px" src="https://user-images.githubusercontent.com/10095631/41342907-e44e7196-6f2f-11e8-92f2-47702dc8f059.png">
</a>
</td>
</tr>
</tbody>
</table>
> A Vue.js 2.0 UI Toolkit for Web.
Element will stay with Vue 2.x
For Vue 3.0, we recommend using [Element Plus](https://github.com/element-plus/element-plus)(Element Plus is a community develop project)
For MiniProgram development, we recommend using [MorJS](https://github.com/eleme/morjs)
## Links
- Homepage and documentation
- [International users](http://element.eleme.io/#/en-US)
- [Chinese users](http://element.eleme.io/#/zh-CN)
- [Chinese users](http://element-cn.eleme.io/#/zh-CN)
- [Spanish users](http://element.eleme.io/#/es)
- [French users](http://element.eleme.io/#/fr-FR)
- [awesome-element](https://github.com/ElementUI/awesome-element)
- [FAQ](./FAQ.md)
- [Vue.js 3.0 migration](https://github.com/element-plus/element-plus)
- [Customize theme](http://element.eleme.io/#/en-US/component/custom-theme)
- [Preview and generate theme online](https://elementui.github.io/theme-chalk-preview)
- [Element for React](https://github.com/elemefe/element-react)
@@ -97,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).
@@ -106,7 +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.
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:
@@ -133,15 +155,82 @@ Spanish documentation is made possible by these community developers:
- [sigfriedCub1990](https://github.com/sigfriedCub1990)
- [thechosenjuan](https://github.com/thechosenjuan)
French documentation is made possible by these community developers:
- [smalesys](https://github.com/smalesys)
- [blombard](https://github.com/blombard)
## Donation
If you find Element useful, you can buy us a cup of coffee
## Join Discussion Group
<img width="650" src="https://user-images.githubusercontent.com/10095631/42198577-587063dc-7ebb-11e8-892b-91e08f99ce1e.jpg" alt="donation">
Scan the QR code using [Dingtalk App](https://www.dingtalk.com/) to join in discussion group :
## Backers
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/element#backer)]
<a href="https://opencollective.com/element/backer/0/website" target="_blank"><img src="https://opencollective.com/element/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/1/website" target="_blank"><img src="https://opencollective.com/element/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/2/website" target="_blank"><img src="https://opencollective.com/element/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/3/website" target="_blank"><img src="https://opencollective.com/element/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/4/website" target="_blank"><img src="https://opencollective.com/element/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/5/website" target="_blank"><img src="https://opencollective.com/element/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/6/website" target="_blank"><img src="https://opencollective.com/element/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/7/website" target="_blank"><img src="https://opencollective.com/element/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/8/website" target="_blank"><img src="https://opencollective.com/element/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/9/website" target="_blank"><img src="https://opencollective.com/element/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/10/website" target="_blank"><img src="https://opencollective.com/element/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/11/website" target="_blank"><img src="https://opencollective.com/element/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/12/website" target="_blank"><img src="https://opencollective.com/element/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/13/website" target="_blank"><img src="https://opencollective.com/element/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/14/website" target="_blank"><img src="https://opencollective.com/element/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/15/website" target="_blank"><img src="https://opencollective.com/element/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/16/website" target="_blank"><img src="https://opencollective.com/element/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/17/website" target="_blank"><img src="https://opencollective.com/element/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/18/website" target="_blank"><img src="https://opencollective.com/element/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/19/website" target="_blank"><img src="https://opencollective.com/element/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/20/website" target="_blank"><img src="https://opencollective.com/element/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/21/website" target="_blank"><img src="https://opencollective.com/element/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/22/website" target="_blank"><img src="https://opencollective.com/element/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/23/website" target="_blank"><img src="https://opencollective.com/element/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/24/website" target="_blank"><img src="https://opencollective.com/element/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/25/website" target="_blank"><img src="https://opencollective.com/element/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/26/website" target="_blank"><img src="https://opencollective.com/element/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/27/website" target="_blank"><img src="https://opencollective.com/element/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/28/website" target="_blank"><img src="https://opencollective.com/element/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/element/backer/29/website" target="_blank"><img src="https://opencollective.com/element/backer/29/avatar.svg"></a>
## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/element#sponsor)]
<a href="https://opencollective.com/element/sponsor/0/website" target="_blank"><img src="https://opencollective.com/element/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/1/website" target="_blank"><img src="https://opencollective.com/element/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/2/website" target="_blank"><img src="https://opencollective.com/element/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/3/website" target="_blank"><img src="https://opencollective.com/element/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/4/website" target="_blank"><img src="https://opencollective.com/element/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/5/website" target="_blank"><img src="https://opencollective.com/element/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/6/website" target="_blank"><img src="https://opencollective.com/element/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/7/website" target="_blank"><img src="https://opencollective.com/element/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/8/website" target="_blank"><img src="https://opencollective.com/element/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/9/website" target="_blank"><img src="https://opencollective.com/element/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/10/website" target="_blank"><img src="https://opencollective.com/element/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/11/website" target="_blank"><img src="https://opencollective.com/element/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/12/website" target="_blank"><img src="https://opencollective.com/element/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/13/website" target="_blank"><img src="https://opencollective.com/element/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/14/website" target="_blank"><img src="https://opencollective.com/element/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/15/website" target="_blank"><img src="https://opencollective.com/element/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/16/website" target="_blank"><img src="https://opencollective.com/element/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/17/website" target="_blank"><img src="https://opencollective.com/element/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/18/website" target="_blank"><img src="https://opencollective.com/element/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/19/website" target="_blank"><img src="https://opencollective.com/element/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/20/website" target="_blank"><img src="https://opencollective.com/element/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/21/website" target="_blank"><img src="https://opencollective.com/element/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/22/website" target="_blank"><img src="https://opencollective.com/element/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/23/website" target="_blank"><img src="https://opencollective.com/element/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/24/website" target="_blank"><img src="https://opencollective.com/element/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/25/website" target="_blank"><img src="https://opencollective.com/element/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/26/website" target="_blank"><img src="https://opencollective.com/element/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/element/sponsor/27/website" target="_blank"><img src="https://opencollective.com/element/sponsor/27/avatar.svg"></a>
<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>
<img alt="Join Discusion Group" src="https://user-images.githubusercontent.com/17680888/93177882-0ae92d80-f766-11ea-870d-3fa2d7f06454.png" width="300">
## LICENSE

View File

@@ -27,7 +27,6 @@ const install = function(Vue, opts = {}) {
Vue.component(component.name, component);
});
Vue.use(InfiniteScroll);
Vue.use(Loading.directive);
Vue.prototype.$ELEMENT = {
@@ -77,7 +76,7 @@ ComponentNames.forEach(name => {
package: name
}));
if (['Loading', 'MessageBox', 'Notification', 'Message', 'InfiniteScroll'].indexOf(componentName) === -1) {
if (['Loading', 'MessageBox', 'Notification', 'Message'].indexOf(componentName) === -1) {
installTemplate.push(render(INSTALL_COMPONENT_TEMPLATE, {
name: componentName,
component: name

View File

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

View File

@@ -17,6 +17,4 @@ nodes.forEach((node) => {
}
});
classList.reverse(); // 希望按 css 文件顺序倒序排列
fs.writeFile(path.resolve(__dirname, '../../examples/icon.json'), JSON.stringify(classList), () => {});

View File

@@ -11,7 +11,6 @@ if (!process.argv[2]) {
}
const path = require('path');
const fs = require('fs');
const fileSave = require('file-save');
const uppercamelcase = require('uppercamelcase');
const componentname = process.argv[2];
@@ -54,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';
@@ -105,29 +100,6 @@ fileSave(path.join(__dirname, '../../components.json'))
.write(JSON.stringify(componentsFile, null, ' '), 'utf8')
.end('\n');
// 添加到 index.scss
const sassPath = path.join(__dirname, '../../packages/theme-chalk/src/index.scss');
const sassImportText = `${fs.readFileSync(sassPath)}@import "./${componentname}.scss";`;
fileSave(sassPath)
.write(sassImportText, 'utf8')
.end('\n');
// 添加到 element-ui.d.ts
const elementTsPath = path.join(__dirname, '../../types/element-ui.d.ts');
let elementTsText = `${fs.readFileSync(elementTsPath)}
/** ${ComponentName} Component */
export class ${ComponentName} extends El${ComponentName} {}`;
const index = elementTsText.indexOf('export') - 1;
const importString = `import { El${ComponentName} } from './${componentname}'`;
elementTsText = elementTsText.slice(0, index) + importString + '\n' + elementTsText.slice(index);
fileSave(elementTsPath)
.write(elementTsText, 'utf8')
.end('\n');
// 创建 package
Files.forEach(file => {
fileSave(path.join(PackagePath, file.filename))

View File

@@ -1,6 +1,6 @@
var fs = require('fs');
var path = require('path');
var version = process.env.VERSION || require('../../package.json').version;
var content = { '1.4.13': '1.4', '2.0.11': '2.0', '2.1.0': '2.1', '2.2.2': '2.2', '2.3.9': '2.3', '2.4.11': '2.4', '2.5.4': '2.5', '2.6.3': '2.6', '2.7.2': '2.7', '2.8.2': '2.8', '2.9.2': '2.9', '2.10.1': '2.10', '2.11.1': '2.11', '2.12.0': '2.12', '2.13.2': '2.13', '2.14.1': '2.14' };
if (!content[version]) content[version] = '2.15';
var content = { '1.4.13': '1.4', '2.0.11': '2.0', '2.1.0': '2.1', '2.2.2': '2.2', '2.3.9': '2.3' };
if (!content[version]) content[version] = '2.4';
fs.writeFileSync(path.resolve(__dirname, '../../examples/versions.json'), JSON.stringify(content));

View File

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

View File

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

View File

@@ -1,13 +1,12 @@
#! /bin/sh
set -ex
mkdir temp_web
npm run deploy:build
cd temp_web
git clone --depth 1 -b gh-pages --single-branch https://github.com/ElemeFE/element.git && cd element
# build sub folder
SUB_FOLDER='2.15'
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 daily -P element
rm -rf temp_web
faas deploy alpha
rm -rf temp_web

View File

@@ -1,26 +0,0 @@
const Config = require('markdown-it-chain');
const anchorPlugin = require('markdown-it-anchor');
const slugify = require('transliteration').slugify;
const containers = require('./containers');
const overWriteFenceRule = require('./fence');
const config = new Config();
config
.options.html(true).end()
.plugin('anchor').use(anchorPlugin, [
{
level: 2,
slugify: slugify,
permalink: true,
permalinkBefore: true
}
]).end()
.plugin('containers').use(containers).end();
const md = config.toMd();
overWriteFenceRule(md);
module.exports = md;

View File

@@ -1,24 +0,0 @@
const mdContainer = require('markdown-it-container');
module.exports = md => {
md.use(mdContainer, 'demo', {
validate(params) {
return params.trim().match(/^demo\s*(.*)$/);
},
render(tokens, idx) {
const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
if (tokens[idx].nesting === 1) {
const description = m && m.length > 1 ? m[1] : '';
const content = tokens[idx + 1].type === 'fence' ? tokens[idx + 1].content : '';
return `<demo-block>
${description ? `<div>${md.render(description)}</div>` : ''}
<!--element-demo: ${content}:element-demo-->
`;
}
return '</demo-block>';
}
});
md.use(mdContainer, 'tip');
md.use(mdContainer, 'warning');
};

View File

@@ -1,14 +0,0 @@
// 覆盖默认的 fence 渲染策略
module.exports = md => {
const defaultRender = md.renderer.rules.fence;
md.renderer.rules.fence = (tokens, idx, options, env, self) => {
const token = tokens[idx];
// 判断该 fence 是否在 :::demo 内
const prevToken = tokens[idx - 1];
const isInDemoContainer = prevToken && prevToken.nesting === 1 && prevToken.info.trim().match(/^demo\s*(.*)$/);
if (token.info === 'html' && isInDemoContainer) {
return `<template slot="highlight"><pre v-pre><code class="html">${md.utils.escapeHtml(token.content)}</code></pre></template>`;
}
return defaultRender(tokens, idx, options, env, self);
};
};

View File

@@ -1,67 +0,0 @@
const {
stripScript,
stripTemplate,
genInlineComponentText
} = require('./util');
const md = require('./config');
module.exports = function(source) {
const content = md.render(source);
const startTag = '<!--element-demo:';
const startTagLen = startTag.length;
const endTag = ':element-demo-->';
const endTagLen = endTag.length;
let componenetsString = '';
let id = 0; // demo 的 id
let output = []; // 输出的内容
let start = 0; // 字符串开始位置
let commentStart = content.indexOf(startTag);
let commentEnd = content.indexOf(endTag, commentStart + startTagLen);
while (commentStart !== -1 && commentEnd !== -1) {
output.push(content.slice(start, commentStart));
const commentContent = content.slice(commentStart + startTagLen, commentEnd);
const html = stripTemplate(commentContent);
const script = stripScript(commentContent);
let demoComponentContent = genInlineComponentText(html, script);
const demoComponentName = `element-demo${id}`;
output.push(`<template slot="source"><${demoComponentName} /></template>`);
componenetsString += `${JSON.stringify(demoComponentName)}: ${demoComponentContent},`;
// 重新计算下一次的位置
id++;
start = commentEnd + endTagLen;
commentStart = content.indexOf(startTag, start);
commentEnd = content.indexOf(endTag, commentStart + startTagLen);
}
// 仅允许在 demo 不存在时,才可以在 Markdown 中写 script 标签
// todo: 优化这段逻辑
let pageScript = '';
if (componenetsString) {
pageScript = `<script>
export default {
name: 'component-doc',
components: {
${componenetsString}
}
}
</script>`;
} else if (content.indexOf('<script>') === 0) { // 硬编码,有待改善
start = content.indexOf('</script>') + '</script>'.length;
pageScript = content.slice(0, start);
}
output.push(content.slice(start));
return `
<template>
<section class="content element-doc">
${output.join('')}
</section>
</template>
${pageScript}
`;
};

View File

@@ -1,79 +0,0 @@
const { compileTemplate } = require('@vue/component-compiler-utils');
const compiler = require('vue-template-compiler');
function stripScript(content) {
const result = content.match(/<(script)>([\s\S]+)<\/\1>/);
return result && result[2] ? result[2].trim() : '';
}
function stripStyle(content) {
const result = content.match(/<(style)\s*>([\s\S]+)<\/\1>/);
return result && result[2] ? result[2].trim() : '';
}
// 编写例子时不一定有 template。所以采取的方案是剔除其他的内容
function stripTemplate(content) {
content = content.trim();
if (!content) {
return content;
}
return content.replace(/<(script|style)[\s\S]+<\/\1>/g, '').trim();
}
function pad(source) {
return source
.split(/\r?\n/)
.map(line => ` ${line}`)
.join('\n');
}
function genInlineComponentText(template, script) {
// https://github.com/vuejs/vue-loader/blob/423b8341ab368c2117931e909e2da9af74503635/lib/loaders/templateLoader.js#L46
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() {
${demoComponentContent}
${script}
return {
render,
staticRenderFns,
...democomponentExport
}
})()`;
return demoComponentContent;
}
module.exports = {
stripScript,
stripStyle,
stripTemplate,
genInlineComponentText
};

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env sh
set -e
git checkout master
git merge dev
VERSION=`npx select-version-cli`
#!/usr/bin/env sh
set -e
echo "Enter release version: "
read VERSION
read -p "Releasing $VERSION - are you sure? (y/n)" -n 1 -r
echo # (optional) move to a new line
@@ -15,9 +15,6 @@ then
# build
VERSION=$VERSION npm run dist
# ssr test
node test/ssr/require.test.js
# publish theme
echo "Releasing theme-chalk $VERSION ..."
cd packages/theme-chalk

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

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

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

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

View File

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

View File

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

View File

@@ -1,7 +1,6 @@
const path = require('path');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const TerserPlugin = require('terser-webpack-plugin');
const config = require('./config');
@@ -16,10 +15,8 @@ module.exports = {
filename: 'index.js',
chunkFilename: '[id].js',
libraryTarget: 'umd',
libraryExport: 'default',
library: 'ELEMENT',
umdNamedDefine: true,
globalObject: 'typeof self !== \'undefined\' ? self : this'
umdNamedDefine: true
},
resolve: {
extensions: ['.js', '.vue', '.json'],
@@ -28,17 +25,6 @@ module.exports = {
externals: {
vue: config.vue
},
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
output: {
comments: false
}
}
})
]
},
performance: {
hints: false
},
@@ -61,6 +47,22 @@ module.exports = {
preserveWhitespace: false
}
}
},
{
test: /\.css$/,
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*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: path.posix.join('static', '[name].[hash:7].[ext]')
}
}
]
},

View File

@@ -5,19 +5,35 @@ 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 launchEditorMiddleware = require('launch-editor-middleware');
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 ? {
docs: './examples/entry.js'
docs: './examples/entry.js',
'element-ui': './src/index.js'
} : (isPlay ? './examples/play.js' : './examples/entry.js'),
output: {
path: path.resolve(process.cwd(), './examples/element-ui/'),
@@ -34,16 +50,7 @@ const webpackConfig = {
host: '0.0.0.0',
port: 8085,
publicPath: '/',
hot: true,
before: (app) => {
/*
* 编辑器类型 :此处的指令表示的时各个各个编辑器在cmd或terminal中的命令
* webstorm
* code // vscode
* idea
*/
app.use('/__open-in-editor', launchEditorMiddleware('code'));
}
noInfo: true
},
performance: {
hints: false
@@ -75,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'
@@ -84,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]')
@@ -110,7 +168,6 @@ const webpackConfig = {
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
template: './examples/index.tpl',
filename: './index.html',
@@ -121,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: {
@@ -131,43 +185,15 @@ const webpackConfig = {
}
}
})
],
optimization: {
minimizer: []
},
devtool: '#eval-source-map'
]
};
if (isProd) {
webpackConfig.externals = {
vue: 'Vue',
'vue-router': 'VueRouter',
'highlight.js': 'hljs'
};
webpackConfig.plugins.push(
new MiniCssExtractPlugin({
filename: '[name].[contenthash:7].css'
})
);
webpackConfig.optimization.minimizer.push(
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: false
}),
new OptimizeCSSAssetsPlugin({})
);
// https://webpack.js.org/configuration/optimization/#optimizationsplitchunks
webpackConfig.optimization.splitChunks = {
cacheGroups: {
vendor: {
test: /\/src\//,
name: 'element-ui',
chunks: 'all'
}
}
};
webpackConfig.devtool = false;
}
module.exports = webpackConfig;

View File

@@ -1,33 +0,0 @@
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const demoConfig = require('./webpack.demo');
const webpack = require('webpack');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
demoConfig.entry = {
background: path.join(process.cwd(), './examples/extension/src/background'),
entry: path.join(process.cwd(), './examples/extension/src/entry')
};
demoConfig.output = {
path: path.join(process.cwd(), './examples/extension/dist'),
filename: '[name].js'
};
demoConfig.plugins = [
new CopyWebpackPlugin([
{ from: 'examples/extension/src/manifest.json' },
{ from: 'examples/extension/src/icon.png' }
]),
new VueLoaderPlugin(),
new ProgressBarPlugin(),
new webpack.LoaderOptionsPlugin({
vue: {
compilerOptions: {
preserveWhitespace: false
}
}
}),
new webpack.HotModuleReplacementPlugin()
];
demoConfig.module.rules.find(a => a.loader === 'url-loader').query = {};
module.exports = demoConfig;

View File

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

View File

@@ -69,23 +69,5 @@
"main": "./packages/main/index.js",
"footer": "./packages/footer/index.js",
"timeline": "./packages/timeline/index.js",
"timeline-item": "./packages/timeline-item/index.js",
"link": "./packages/link/index.js",
"divider": "./packages/divider/index.js",
"image": "./packages/image/index.js",
"calendar": "./packages/calendar/index.js",
"backtop": "./packages/backtop/index.js",
"infinite-scroll": "./packages/infinite-scroll/index.js",
"page-header": "./packages/page-header/index.js",
"cascader-panel": "./packages/cascader-panel/index.js",
"avatar": "./packages/avatar/index.js",
"drawer": "./packages/drawer/index.js",
"statistic": "./packages/statistic/index.js",
"popconfirm": "./packages/popconfirm/index.js",
"skeleton": "./packages/skeleton/index.js",
"skeleton-item": "./packages/skeleton-item/index.js",
"empty": "./packages/empty/index.js",
"descriptions": "./packages/descriptions/index.js",
"descriptions-item": "./packages/descriptions-item/index.js",
"result": "./packages/result/index.js"
"timeline-item": "./packages/timeline-item/index.js"
}

View File

@@ -13,7 +13,6 @@
import zhLocale from 'main/locale/lang/zh-CN';
import enLocale from 'main/locale/lang/en';
import esLocale from 'main/locale/lang/es';
import frLocale from 'main/locale/lang/fr';
const lang = location.hash.replace('#', '').split('/')[1] || 'zh-CN';
const localize = lang => {
@@ -24,9 +23,6 @@
case 'es':
use(esLocale);
break;
case 'fr-FR':
use(frLocale);
break;
default:
use(enLocale);
}
@@ -60,13 +56,14 @@
const href = location.href;
const preferGithub = localStorage.getItem('PREFER_GITHUB');
const cnHref = href.indexOf('eleme.cn') > -1 || href.indexOf('element-cn') > -1 || href.indexOf('element.faas') > -1;
if (cnHref || preferGithub) return;
if (href.indexOf('element-cn') > -1 || href.indexOf('element.faas') > -1 || preferGithub) return;
setTimeout(() => {
if (this.lang !== 'zh-CN') return;
this.$confirm('建议大陆用户访问部署在国内的站点,是否跳转?', '提示')
.then(() => {
location.replace('https://element.eleme.cn');
location.href = location.href
.replace('https:', 'http:')
.replace('element.', 'element-cn.');
})
.catch(() => {
localStorage.setItem('PREFER_GITHUB', 'true');
@@ -83,3 +80,9 @@
}
};
</script>
<style>
@import 'highlight.js/styles/color-brewer.css';
@import 'assets/styles/common.css';
@import 'assets/styles/fonts/style.css';
</style>

View File

@@ -0,0 +1,24 @@
<svg width="98" height="150" viewBox="0 0 98 150" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>duohui-element</title>
<desc>Created using Figma</desc>
<g id="Canvas" transform="translate(-2216 140)">
<clipPath id="clip-0" clip-rule="evenodd">
<path d="M 2216 -140L 2314 -140L 2314 10L 2216 10L 2216 -140Z" fill="#FFFFFF"/>
</clipPath>
<g id="duohui-element" clip-path="url(#clip-0)">
<path d="M 2216 -140L 2314 -140L 2314 10L 2216 10L 2216 -140Z" fill="#FFFFFF"/>
<g id="Duohui Icon 2">
<g id="Vector">
<use xlink:href="#path0_fill" transform="matrix(1.26636 0 0 1.21929 2230 -75.7038)" fill="#3A88FD"/>
</g>
<g id="Vector">
<use xlink:href="#path1_fill" transform="matrix(1.41534 0 0 1.21834 2226 -112)" fill="#35AFFB"/>
</g>
</g>
</g>
</g>
<defs>
<path id="path0_fill" fill-rule="evenodd" d="M 25.7722 1.00635C 26.2 0.374983 26.8949 -2.6613e-07 27.6349 -2.6613e-07C 28.3755 -2.6613e-07 29.0699 0.374983 29.4983 1.00635C 34.409 8.24964 47.798 27.9964 54.5986 38.0262C 55.3878 39.1901 55.4896 40.7162 54.8623 41.983C 54.235 43.2498 52.9833 44.0452 51.6178 44.0452C 39.6694 44.0452 15.601 44.0452 3.6521 44.0452C 2.28712 44.0452 1.03545 43.2498 0.408173 41.983C -0.219106 40.7162 -0.117353 39.1901 0.671804 38.0262C 7.47242 27.9964 20.8609 8.24964 25.7722 1.00635Z"/>
<path id="path1_fill" fill-rule="evenodd" d="M 24.9939 1.44703C 25.6137 0.533117 26.5572 -3.01614e-07 27.5551 -3.01614e-07C 28.5535 -3.01614e-07 29.497 0.533117 30.1168 1.44703C 35.4674 9.33854 47.8725 27.6342 54.4043 37.2681C 55.1825 38.4157 55.3299 39.982 54.7847 41.2999C 54.2389 42.6185 53.096 43.4556 51.8426 43.4556C 39.9023 43.4556 15.2084 43.4556 3.26811 43.4556C 2.01471 43.4556 0.871739 42.6185 0.325978 41.2999C -0.219783 39.982 -0.0717813 38.4157 0.70639 37.2681C 7.23818 27.6342 19.6433 9.33854 24.9939 1.44703Z"/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

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

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="13px" height="12px" viewBox="0 0 13 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
<title>icon-redo</title>
<desc>Created with Sketch.</desc>
<g id="theme" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="element-theme-editor" transform="translate(-1118.000000, -167.000000)" fill="#606266" fill-rule="nonzero">
<g id="custom" transform="translate(1060.000000, 146.000000)">
<g id="Group-2" transform="translate(30.000000, 15.000000)">
<g id="Group" transform="translate(0.000000, 4.000000)">
<g id="icon-clockwise" transform="translate(26.000000, 0.000000)">
<path d="M12.2585,3.59833136 L12.2585,2.3085 L13.2585,2.3085 L13.2585,5.6365 L9.9295,5.6365 L9.9295,4.6365 L11.8833737,4.6365 C10.9510824,3.62012881 9.6272717,3.0179 8.2,3.0179 C5.43814237,3.0179 3.2,5.25604237 3.2,8.0179 C3.2,10.7797576 5.43814237,13.0179 8.2,13.0179 C10.9618576,13.0179 13.2,10.7797576 13.2,8.0179 L14.2,8.0179 C14.2,11.3320424 11.5141424,14.0179 8.2,14.0179 C4.88585763,14.0179 2.2,11.3320424 2.2,8.0179 C2.2,4.70375763 4.88585763,2.0179 8.2,2.0179 C9.73531163,2.0179 11.1716793,2.59926473 12.2585,3.59833136 Z" id="icon-redo"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="13px" height="12px" viewBox="0 0 13 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
<title>icon-undo</title>
<desc>Created with Sketch.</desc>
<g id="theme" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="element-theme-editor" transform="translate(-1092.000000, -167.000000)" fill="#606266" fill-rule="nonzero">
<g id="custom" transform="translate(1060.000000, 146.000000)">
<g id="Group-2" transform="translate(30.000000, 15.000000)">
<g id="Group" transform="translate(0.000000, 4.000000)">
<g id="icon-clockwise">
<path d="M12.2585,3.59833136 L12.2585,2.3085 L13.2585,2.3085 L13.2585,5.6365 L9.9295,5.6365 L9.9295,4.6365 L11.8833737,4.6365 C10.9510824,3.62012881 9.6272717,3.0179 8.2,3.0179 C5.43814237,3.0179 3.2,5.25604237 3.2,8.0179 C3.2,10.7797576 5.43814237,13.0179 8.2,13.0179 C10.9618576,13.0179 13.2,10.7797576 13.2,8.0179 L14.2,8.0179 C14.2,11.3320424 11.5141424,14.0179 8.2,14.0179 C4.88585763,14.0179 2.2,11.3320424 2.2,8.0179 C2.2,4.70375763 4.88585763,2.0179 8.2,2.0179 C9.73531163,2.0179 11.1716793,2.59926473 12.2585,3.59833136 Z" id="icon-undo" transform="translate(8.200000, 8.017900) scale(-1, 1) translate(-8.200000, -8.017900) "></path>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="26px" height="26px" viewBox="0 0 26 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
<title>icon_upload</title>
<desc>Created with Sketch.</desc>
<g id="theme" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="element-theme" transform="translate(-207.000000, -662.000000)" fill="#909399">
<g id="section" transform="translate(70.000000, 511.000000)">
<g id="card" transform="translate(0.000000, 60.000000)">
<g id="btn" transform="translate(108.000000, 91.000000)">
<g id="icon-upload" transform="translate(29.000000, 0.000000)">
<path d="M13,-0.000600000001 L3.015,9.9854 L4.429,11.3984 L12,3.8284 L12,20.4854 L14.001,20.4854 L14.001,3.8284 L21.572,11.3984 L22.986,9.9854 L14.415,1.4144 L13,-0.000600000001 Z M13,2.8284 L13.158,2.9844 L12.843,2.9844 L13,2.8284 Z M24.001,19.9854 L24.001,23.9854 L2,23.9854 L2,19.9854 L0,19.9854 L0,25.9854 L26.001,25.9854 L26.001,19.9854 L24.001,19.9854 Z" id="icon_upload"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 240"><defs><style>.cls-1{fill:none;}.cls-2{fill:#eff5fd;}.cls-3{fill:#fff;}.cls-4{fill:#26a1ff;}.cls-5{fill:snow;}.cls-6{fill:#fdaca9;}.cls-7{fill:#fd9da0;}.cls-8{fill:#fed5d0;}.cls-9{fill:#ffe8e6;}</style></defs><title>资源 104</title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><rect class="cls-1" width="320" height="240"/><circle class="cls-2" cx="160" cy="120" r="120"/><path class="cls-3" d="M160,55H105.64A20.64,20.64,0,0,0,85,75.64V200a5,5,0,0,0,5,5h70Z"/><rect class="cls-4" x="95" y="145" width="130" height="40" rx="5"/><path class="cls-5" d="M230,55H160V205h70a5,5,0,0,0,5-5V60A5,5,0,0,0,230,55Z"/><path class="cls-6" d="M220,145H160v40h60a5,5,0,0,0,5-5V150A5,5,0,0,0,220,145Z"/><path class="cls-6" d="M160,99.78a2.5,2.5,0,0,1,0-5c48.71,0,62.17-28.57,62.72-29.79a2.5,2.5,0,1,1,4.56,2C226.69,68.36,212.13,99.78,160,99.78Z"/><path class="cls-2" d="M124.26,171.58V154.4h6.44a7.91,7.91,0,0,1,3.16.52,4,4,0,0,1,1.86,1.6,4.26,4.26,0,0,1,.68,2.27,3.89,3.89,0,0,1-.6,2.08,4.36,4.36,0,0,1-1.8,1.57,4.45,4.45,0,0,1,2.39,1.56,4.15,4.15,0,0,1,.84,2.6,5,5,0,0,1-.51,2.24,4.32,4.32,0,0,1-1.26,1.6,5.18,5.18,0,0,1-1.88.85,11.48,11.48,0,0,1-2.77.29Zm2.27-10h3.72a8.34,8.34,0,0,0,2.16-.2,2.39,2.39,0,0,0,1.31-.86,2.49,2.49,0,0,0,.44-1.5,2.76,2.76,0,0,0-.41-1.5,2,2,0,0,0-1.17-.89,9.84,9.84,0,0,0-2.62-.24h-3.43Zm0,7.93h4.28a10.68,10.68,0,0,0,1.55-.08,3.81,3.81,0,0,0,1.31-.47,2.44,2.44,0,0,0,.86-1,2.92,2.92,0,0,0,.34-1.44,2.84,2.84,0,0,0-.49-1.67,2.56,2.56,0,0,0-1.36-1,8.51,8.51,0,0,0-2.52-.29h-4Z"/><path class="cls-2" d="M148.25,171.58v-1.83a4.55,4.55,0,0,1-3.95,2.11,5.06,5.06,0,0,1-2.06-.42,3.42,3.42,0,0,1-1.42-1.06,4.06,4.06,0,0,1-.65-1.57,11.22,11.22,0,0,1-.13-2v-7.71h2.11V166a11.86,11.86,0,0,0,.13,2.23,2.18,2.18,0,0,0,.84,1.31,2.68,2.68,0,0,0,1.6.47,3.52,3.52,0,0,0,1.78-.48,2.76,2.76,0,0,0,1.18-1.33,6.68,6.68,0,0,0,.34-2.43v-6.67h2.11v12.45Z"/><path class="cls-2" d="M158,169.69l.31,1.86a7.59,7.59,0,0,1-1.6.19,3.64,3.64,0,0,1-1.78-.36,2,2,0,0,1-.89-1,7.55,7.55,0,0,1-.26-2.49v-7.16h-1.54v-1.64h1.54v-3.08l2.1-1.27v4.35H158v1.64h-2.12v7.28a3.83,3.83,0,0,0,.11,1.16.92.92,0,0,0,.37.41,1.38,1.38,0,0,0,.72.15A6,6,0,0,0,158,169.69Z"/><path class="cls-5" d="M167.69,169.69l.3,1.86a7.43,7.43,0,0,1-1.59.19,3.61,3.61,0,0,1-1.78-.36,2,2,0,0,1-.89-1,7.28,7.28,0,0,1-.26-2.49v-7.16h-1.55v-1.64h1.55v-3.08l2.1-1.27v4.35h2.12v1.64h-2.12v7.28a3.51,3.51,0,0,0,.11,1.16.84.84,0,0,0,.36.41,1.43,1.43,0,0,0,.72.15A6.1,6.1,0,0,0,167.69,169.69Z"/><path class="cls-5" d="M169,165.35a6.43,6.43,0,0,1,1.93-5.12,5.79,5.79,0,0,1,3.91-1.38,5.6,5.6,0,0,1,4.2,1.68,6.42,6.42,0,0,1,1.62,4.65,8.25,8.25,0,0,1-.72,3.78,5.13,5.13,0,0,1-2.09,2.14,6.2,6.2,0,0,1-3,.76,5.57,5.57,0,0,1-4.22-1.68A6.65,6.65,0,0,1,169,165.35Zm2.17,0a5.26,5.26,0,0,0,1.05,3.58,3.47,3.47,0,0,0,5.23,0,5.41,5.41,0,0,0,1.05-3.65,5.13,5.13,0,0,0-1.05-3.49,3.48,3.48,0,0,0-5.23,0A5.25,5.25,0,0,0,171.13,165.35Z"/><path class="cls-5" d="M183.1,171.58V159.13H185v1.77a4.46,4.46,0,0,1,4-2.05,5.2,5.2,0,0,1,2.07.41,3.25,3.25,0,0,1,1.41,1.06,4,4,0,0,1,.65,1.55,11.89,11.89,0,0,1,.12,2.06v7.65H191.1V164a5.85,5.85,0,0,0-.24-1.93,2,2,0,0,0-.88-1,2.82,2.82,0,0,0-1.47-.38,3.39,3.39,0,0,0-2.32.85c-.66.57-1,1.66-1,3.25v6.8Z"/><circle class="cls-4" cx="71.9" cy="76.81" r="30"/><path class="cls-3" d="M62.69,68.35h4.89v2.5H59.25V62.53h2.5v3.23a15,15,0,0,1,25.15,11H84.4A12.5,12.5,0,0,0,63.06,68C62.93,68.09,62.81,68.22,62.69,68.35Zm19.36,19.5a15,15,0,0,1-25.15-11h2.5a12.51,12.51,0,0,0,21.34,8.85l.37-.39H76.22v-2.5h8.33v8.32h-2.5Z"/><path class="cls-7" d="M46.94,47.79a2.92,2.92,0,0,1-2.25-1l-7-8.38a2.93,2.93,0,1,1,4.48-3.77L49.17,43a2.92,2.92,0,0,1-.35,4.12A2.88,2.88,0,0,1,46.94,47.79Z"/><path class="cls-8" d="M37.06,59.93h-.25L25.89,59a2.93,2.93,0,0,1,.51-5.83l10.91,1a2.93,2.93,0,0,1-.25,5.84Z"/><path class="cls-8" d="M60.58,40.14l-.25,0A2.93,2.93,0,0,1,57.66,37l.94-10.91a2.93,2.93,0,1,1,5.83.5l-.94,10.91A2.93,2.93,0,0,1,60.58,40.14Z"/><rect class="cls-2" x="99" y="128.31" width="15" height="6.27"/><rect class="cls-2" x="123.56" y="112.59" width="15" height="22"/><rect class="cls-9" x="160" y="106.81" width="7.5" height="27.78"/><rect class="cls-2" x="152.5" y="106.81" width="7.5" height="27.78"/><rect class="cls-9" x="206" y="91.81" width="15" height="42.78"/><rect class="cls-9" x="179.25" y="103.64" width="15" height="30.94"/><path class="cls-4" d="M95,130.81a2.62,2.62,0,0,1-1-.21,2.5,2.5,0,0,1-1.26-3.31C93.31,126,107.88,94.78,160,94.78a2.5,2.5,0,0,1,0,5c-48.91,0-62.59,29.26-62.72,29.56A2.5,2.5,0,0,1,95,130.81Z"/><path class="cls-6" d="M226,63.73a2.5,2.5,0,0,0-3.3,1.26c-.55,1.22-14,29.79-62.72,29.79h0v5h0c52.13,0,66.69-31.42,67.28-32.75A2.5,2.5,0,0,0,226,63.73Z"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -0,0 +1,175 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 148.32 226.69">
<defs>
<style>
.cls-1 {
isolation: isolate;
}
.cls-2 {
fill: url(#radial-gradient);
}
.cls-3 {
fill: url(#linear-gradient);
}
.cls-4 {
fill: url(#linear-gradient-2);
}
.cls-5 {
fill: url(#linear-gradient-3);
}
.cls-6 {
fill: url(#linear-gradient-4);
}
.cls-7 {
fill: url(#linear-gradient-5);
}
.cls-8 {
fill: url(#linear-gradient-6);
}
.cls-9 {
opacity: 0.7;
}
.cls-11, .cls-9 {
mix-blend-mode: multiply;
}
.cls-10 {
fill: url(#linear-gradient-7);
}
.cls-12 {
fill: url(#linear-gradient-8);
}
.cls-13 {
fill: url(#linear-gradient-9);
}
.cls-14 {
fill: #3c2e36;
}
.cls-15 {
fill: url(#linear-gradient-10);
}
.cls-16 {
fill: url(#radial-gradient-2);
}
</style>
<radialGradient id="radial-gradient" cx="74.93" cy="117.87" r="86.39" gradientTransform="translate(0 22.72) scale(1 1.07)" gradientUnits="userSpaceOnUse">
<stop offset="0.32" stop-color="#e4dce1"/>
<stop offset="0.48" stop-color="#e1dadf"/>
<stop offset="0.59" stop-color="#d9d3da"/>
<stop offset="0.68" stop-color="#cac7d2"/>
<stop offset="0.76" stop-color="#b5b6c6"/>
<stop offset="0.79" stop-color="#aaadc0"/>
<stop offset="1" stop-color="#6f6f85"/>
</radialGradient>
<linearGradient id="linear-gradient" x1="38.85" y1="122.53" x2="108.18" y2="108.38" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#e4dce1"/>
<stop offset="0.19" stop-color="#d7d0d7"/>
<stop offset="0.53" stop-color="#b5b2be"/>
<stop offset="0.97" stop-color="#808296"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="32.25" y1="64.7" x2="148.44" y2="64.7" gradientUnits="userSpaceOnUse">
<stop offset="0.32" stop-color="#e4dce1"/>
<stop offset="0.49" stop-color="#e1dadf"/>
<stop offset="0.6" stop-color="#d9d3da"/>
<stop offset="0.69" stop-color="#cac7d2"/>
<stop offset="0.78" stop-color="#b5b6c6"/>
<stop offset="0.81" stop-color="#aaadc0"/>
<stop offset="1" stop-color="#6f6f85"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="139.11" y1="68.34" x2="139.11" y2="1.17" gradientUnits="userSpaceOnUse">
<stop offset="0.12" stop-color="#888aa0"/>
<stop offset="0.54" stop-color="#716f8a"/>
<stop offset="0.89" stop-color="#635d7c"/>
</linearGradient>
<linearGradient id="linear-gradient-4" x1="111.94" y1="16.05" x2="135.36" y2="16.05" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#3c314b"/>
<stop offset="0.54" stop-color="#534a67"/>
<stop offset="0.89" stop-color="#635d7c"/>
</linearGradient>
<linearGradient id="linear-gradient-5" x1="6752.04" y1="68.34" x2="6752.04" y2="-3.45" gradientTransform="matrix(-1, 0, 0, 1, 6787.68, 0)" gradientUnits="userSpaceOnUse">
<stop offset="0.19" stop-color="#e4dce1"/>
<stop offset="0.42" stop-color="#c2bac6"/>
<stop offset="0.92" stop-color="#6b6582"/>
<stop offset="0.97" stop-color="#635d7c"/>
</linearGradient>
<linearGradient id="linear-gradient-6" x1="39.39" y1="16.05" x2="62.82" y2="16.05" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#3c314b"/>
<stop offset="0.02" stop-color="#3d324c"/>
<stop offset="0.35" stop-color="#524a66"/>
<stop offset="0.65" stop-color="#5f5876"/>
<stop offset="0.89" stop-color="#635d7c"/>
</linearGradient>
<linearGradient id="linear-gradient-7" x1="79.66" y1="229.05" x2="79.66" y2="194.82" gradientUnits="userSpaceOnUse">
<stop offset="0.03" stop-color="#808296"/>
<stop offset="0.31" stop-color="#b7b8c3" stop-opacity="0.78"/>
<stop offset="0.79" stop-color="#fff" stop-opacity="0.5"/>
</linearGradient>
<linearGradient id="linear-gradient-8" x1="87.38" y1="117.84" x2="87.38" y2="41.77" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#e3dddf" stop-opacity="0"/>
<stop offset="0.04" stop-color="#cbc5cd" stop-opacity="0.12"/>
<stop offset="0.15" stop-color="#9d97a9" stop-opacity="0.37"/>
<stop offset="0.25" stop-color="#7b758f" stop-opacity="0.54"/>
<stop offset="0.35" stop-color="#67617f" stop-opacity="0.65"/>
<stop offset="0.45" stop-color="#605a7a" stop-opacity="0.68"/>
<stop offset="0.54" stop-color="#575070" stop-opacity="0.75"/>
<stop offset="1" stop-color="#382e4a"/>
</linearGradient>
<linearGradient id="linear-gradient-9" x1="11357.22" y1="78.8" x2="11361.46" y2="58.49" gradientTransform="matrix(-1, 0, 0, 1, 11419.34, 0)" gradientUnits="userSpaceOnUse">
<stop offset="0.07" stop-color="#28ffff"/>
<stop offset="0.41" stop-color="#51d2ff"/>
<stop offset="0.8" stop-color="#7ba3ff"/>
<stop offset="1" stop-color="#8b91ff"/>
</linearGradient>
<linearGradient id="linear-gradient-10" x1="113" y1="78.8" x2="117.24" y2="58.49" gradientTransform="matrix(1, 0, 0, 1, 0, 0)" xlink:href="#linear-gradient-9"/>
<radialGradient id="radial-gradient-2" cx="36.09" cy="124.71" r="36.13" gradientUnits="userSpaceOnUse">
<stop offset="0.11" stop-color="#635d7c"/>
<stop offset="0.35" stop-color="#5f5876"/>
<stop offset="0.65" stop-color="#524a66"/>
<stop offset="0.98" stop-color="#3d324c"/>
<stop offset="1" stop-color="#3c314b"/>
</radialGradient>
</defs>
<title>Asset 3</title>
<g class="cls-1">
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<g>
<path class="cls-2" d="M138.13,128.27c-4.7-9.78-11.29-21.28-9.75-33.55a15.83,15.83,0,0,1,3.26-8.26A65.12,65.12,0,0,1,114.75,99a64.1,64.1,0,0,1-6.11,2.76,66.61,66.61,0,0,0-14.35,9.42c-13.43,11.7-26.21,44.39-48.51,50.6h0a23.9,23.9,0,0,1-9.81,2c-9.41-.07-20.4-6.21-26.26-15.43C1,134.68,3.58,115.85,9.49,103.81c-.18.37-.37.74-.55,1.13a102.51,102.51,0,0,0-4.2,10.42v0A86.37,86.37,0,0,0,0,143.69c0,45.84,35.49,83,79.27,83,11.19,0,29-3.38,43.66-13.61a57.75,57.75,0,0,0,22.57-32C151.54,158.58,144.94,142.45,138.13,128.27Z"/>
<path class="cls-3" d="M51.46,158.37a27,27,0,0,1-5.67,3.38h0c22.3-6.21,35.07-38.9,48.51-50.6a66.61,66.61,0,0,1,14.35-9.42,58.67,58.67,0,0,1-21.26,4.09c-19.75,0-37.75-10.49-48.31-24,1,1.39,13,15.46,22.29,43.72A30,30,0,0,1,51.46,158.37Z"/>
<path class="cls-4" d="M145.33,59.56c-2.08,22.29-28.26,46.26-58,46.26-29.95,0-55.88-24.12-58-46.26-1.45-15.6,7.34-36,58-36S146.78,44,145.33,59.56Z"/>
<path class="cls-5" d="M135.36,0h0a51.59,51.59,0,0,0-4.68,32.1A37.21,37.21,0,0,1,134,34.24c10,7.23,12.12,17,11.34,25.32a35.2,35.2,0,0,1-1.6,7.61A73.45,73.45,0,0,0,142.08,12,71.18,71.18,0,0,0,135.36,0Z"/>
<path class="cls-6" d="M130.68,32.1A51.59,51.59,0,0,1,135.36,0h0a57.92,57.92,0,0,0-9.41,6.87,59.8,59.8,0,0,0-14,18.75q3.35.64,6.29,1.45A53.09,53.09,0,0,1,130.68,32.1Z"/>
<path class="cls-7" d="M39.39,0h0a51.59,51.59,0,0,1,4.68,32.1,37.21,37.21,0,0,0-3.31,2.14c-10,7.23-12.12,17-11.34,25.32A35.2,35.2,0,0,0,31,67.17,73.45,73.45,0,0,1,32.67,12,71.18,71.18,0,0,1,39.39,0Z"/>
<path class="cls-8" d="M48.81,6.87A57.92,57.92,0,0,0,39.39,0h0a51.59,51.59,0,0,1,4.68,32.1,53.09,53.09,0,0,1,12.45-5q2.94-.82,6.29-1.45A59.8,59.8,0,0,0,48.81,6.87Z"/>
<g class="cls-9">
<path class="cls-10" d="M84.24,182.6c-26.08,0-49.56,5.42-66,14.08,14.54,18.33,36.47,30,61,30,11.19,0,29-3.38,43.66-13.61A58.81,58.81,0,0,0,141,192.47C125.56,186.3,105.79,182.6,84.24,182.6Z"/>
</g>
<g>
<g class="cls-11">
<path class="cls-12" d="M138.51,52.94c-.56-2.94-2-5.19-5-5.88-7.88-1.85-27,9.84-37.8,15.34-4,2.06-6.16,3.05-8.34,3s-4.31-.94-8.34-3c-10.77-5.5-29.92-17.18-37.8-15.34-3,.7-4.44,2.94-5,5.88-1,5.16.35,18,9.89,27.49,7.14,7.11,16.68,10.46,24.69,12.71l.18.08a4.2,4.2,0,0,0-.09.88c0,3.28,3.83,5.94,8.56,5.94,2.34,0,6.35-.65,7.9-1.71h0c1.55,1.06,5.56,1.71,7.9,1.71,4.73,0,8.56-2.66,8.56-5.94a4.2,4.2,0,0,0-.09-.88l.18-.08c8-2.25,17.56-5.6,24.69-12.71C138.16,70.92,139.49,58.1,138.51,52.94Z"/>
</g>
<path class="cls-13" d="M75.26,75.35C64.56,86.85,47.81,77.09,45,63.28c-1.83-9.07,3.63-7.73,8.71-5.67C60.14,60.2,68.84,66.27,75.26,75.35Z"/>
<path class="cls-14" d="M60.43,68.26a15.16,15.16,0,0,1-2.19,8,15.56,15.56,0,0,1,0-15.92A15.16,15.16,0,0,1,60.43,68.26Z"/>
<path d="M87.36,86.64a8.15,8.15,0,0,0-6.27,2.49c8.25,5.17,4.31,5.17,12.55,0A8.15,8.15,0,0,0,87.36,86.64Z"/>
<path class="cls-15" d="M99.86,75.35c10.69,11.5,27.45,1.74,30.23-12.07,1.83-9.07-3.63-7.73-8.71-5.67C115,60.2,106.28,66.27,99.86,75.35Z"/>
<path class="cls-14" d="M114.69,68.26a15.16,15.16,0,0,0,2.19,8,15.56,15.56,0,0,0,0-15.92A15.16,15.16,0,0,0,114.69,68.26Z"/>
</g>
<path class="cls-16" d="M9.71,148.35c5.86,9.22,16.85,15.37,26.26,15.43a23.7,23.7,0,0,0,8.21-1.41l0,0c-15,4.18-19.32-25.16-10.92-43.06v0c1.09-3.38,2.35-6.34,3.42-8.83.37-.86,2.53-5.15,2.09-9.8-.84-9-14-17.33-24-5.37A44.52,44.52,0,0,0,9.39,104C3.55,116.06,1.08,134.76,9.71,148.35Z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,6 @@ html, body {
font-family: 'Helvetica Neue',Helvetica,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',SimSun,sans-serif;
font-weight: 400;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
&.is-component {
overflow: hidden;
@@ -15,7 +14,7 @@ html, body {
#app {
height: 100%;
&.is-component {
@when component {
overflow-y: hidden;
.main-cnt {

View File

@@ -1,18 +0,0 @@
export const tintColor = (c, tint) => {
const color = c.replace('#', '');
let red = parseInt(color.slice(0, 2), 16);
let green = parseInt(color.slice(2, 4), 16);
let blue = parseInt(color.slice(4, 6), 16);
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',');
} else {
red += Math.round(tint * (255 - red));
green += Math.round(tint * (255 - green));
blue += Math.round(tint * (255 - blue));
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
return `#${ red }${ green }${ blue }`;
}
};

View File

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

View File

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

View File

@@ -7,10 +7,10 @@
<a href="https://github.com/ElemeFE/element/releases" class="footer-main-link" target="_blank">{{ langConfig.changelog }}</a>
<a href="https://github.com/ElemeFE/element/blob/dev/FAQ.md" class="footer-main-link" target="_blank">{{ langConfig.faq }}</a>
<a href="https://github.com/ElementUI/element-starter" class="footer-main-link" target="_blank">{{ langConfig.starter }}</a>
<a :href="'/#/' + lang + '/component/custom-theme'" class="footer-main-link" target="_blank">{{ langConfig.theme }}</a>
<a href="https://github.com/ElementUI/element-theme" class="footer-main-link" target="_blank">{{ langConfig.theme }}</a>
<a href="https://github.com/ElementUI/theme-chalk-preview" class="footer-main-link" target="_blank">{{ langConfig.preview }}</a>
<a href="https://github.com/elemefe/element-react" class="footer-main-link" target="_blank">Element-React</a>
<a href="https://github.com/ElemeFE/element-angular" class="footer-main-link" target="_blank">Element-Angular</a>
<a href="https://github.com/eleme/morjs" class="footer-main-link" target="_blank">MorJS</a>
</div>
<div class="footer-main">
<h4>{{ langConfig.community }}</h4>
@@ -28,17 +28,8 @@
width="120"
popper-class="footer-popover"
trigger="hover">
<div class="footer-popover-title">{{ langConfig.elemeTech }}</div>
<img src="https://gw.alicdn.com/imgextra/i4/O1CN01dBDgJP1t4R3qikGBP_!!6000000005848-0-tps-344-344.jpg" alt="">
</el-popover>
<el-popover
ref="weixin"
placement="top"
width="120"
popper-class="footer-popover"
trigger="hover">
<div class="footer-popover-title">{{ langConfig.elemeDesign }}</div>
<img src="https://gw.alicdn.com/imgextra/i4/O1CN015ha1O71yg3g1QaKEi_!!6000000006607-0-tps-1280-1280.jpg" alt="">
<div class="footer-popover-title">{{ langConfig.eleme }} UED</div>
<img src="../assets/images/qrcode.png" alt="">
</el-popover>
<i class="doc-icon-weixin elementdoc" v-popover:weixin></i>
<a href="https://github.com/elemefe" target="_blank">
@@ -52,7 +43,7 @@
</footer>
</template>
<style lang="scss">
<style>
.footer {
background-color: #F7FBFD;
width: 100%;
@@ -71,7 +62,7 @@
display: inline-block;
vertical-align: top;
margin-right: 110px;
h4 {
font-size: 18px;
color: #333;
@@ -95,7 +86,7 @@
.footer-social {
float: right;
text-align: right;
.footer-social-title {
color: #666;
font-size: 18px;
@@ -144,7 +135,7 @@
}
img {
width: 100px;
size: 100px;
margin: 10px;
}
}
@@ -153,13 +144,13 @@
height: auto;
}
}
@media (max-width: 1000px) {
.footer-social {
display: none;
}
}
@media (max-width: 768px) {
.footer {
.footer-main {

View File

@@ -1,23 +1,8 @@
<style lang="scss" scoped>
<style scoped>
.headerWrapper {
height: 80px;
}
#v3-banner {
background-color: #409EFF;
min-height: 30px;
padding: 5px 60px;
z-index: 19;
box-sizing: border-box;
text-align: center;
color: #eee;
}
#v3-banner a {
color: #FFF;
font-weight: bold;
}
.header {
height: 80px;
background-color: #fff;
@@ -25,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 {
@@ -70,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 {
@@ -112,11 +90,11 @@
list-style: none;
position: relative;
cursor: pointer;
&.nav-algolia-search {
cursor: default;
}
&.lang-item,
&:last-child {
cursor: default;
@@ -144,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;
}
}
@@ -195,7 +172,7 @@
transform: translateY(-2px);
}
.is-active {
@when active {
span, i {
color: #409EFF;
}
@@ -210,7 +187,7 @@
}
}
}
.nav-dropdown-list {
width: auto;
}
@@ -230,7 +207,7 @@
&:last-child {
margin-left: 10px;
}
a {
padding: 0 5px;
}
@@ -254,11 +231,11 @@
&.lang-item {
height: 100%;
.nav-lang {
display: flex;
align-items: center;
span {
padding-bottom: 0;
}
@@ -282,18 +259,6 @@
</style>
<template>
<div class="headerWrapper">
<div id="v3-banner" v-if="isHome">
<template v-if="lang === 'zh-CN'">
您正在浏览基于 Vue 2.x 的文档;
<a href="https://element-plus.org/#/zh-CN">点击查看 Vue 3.x 版本</a>
饿了么开源了自研多端框架 MorJS
<a href="https://github.com/eleme/morjs">欢迎点击查看或试用 👏🏻</a>
</template>
<template v-else>
Youre browsing the documentation of Element UI for Vue 2.x version.
<a href="https://element-plus.org">Click here</a> for Vue 3.x version
</template>
</div>
<header class="header" ref="header">
<div class="container">
<h1><router-link :to="`/${ lang }`">
@@ -328,14 +293,6 @@
:to="`/${ lang }/component`">{{ langConfig.components }}
</router-link>
</li>
<li
class="nav-item nav-item-theme"
>
<router-link
active-class="active"
:to="`/${ lang }/theme`">{{ langConfig.theme }}
</router-link>
</li>
<li class="nav-item">
<router-link
active-class="active"
@@ -396,6 +353,11 @@
</el-dropdown-menu>
</el-dropdown>
</li>
<!--theme picker-->
<li class="nav-item nav-theme-switch" v-show="isComponentPage">
<theme-picker></theme-picker>
</li>
</ul>
</div>
</header>
@@ -406,10 +368,6 @@
import AlgoliaSearch from './search.vue';
import compoLang from '../i18n/component.json';
import Element from 'main/index.js';
import themeLoader from './theme/loader';
import bus from '../bus';
import { ACTION_USER_CONFIG_UPDATE } from './theme/constant.js';
const { version } = Element;
export default {
@@ -423,14 +381,11 @@
langs: {
'zh-CN': '中文',
'en-US': 'English',
'es': 'Español',
'fr-FR': 'Français'
'es': 'Español'
}
};
},
mixins: [themeLoader],
components: {
ThemePicker,
AlgoliaSearch
@@ -448,23 +403,9 @@
},
isComponentPage() {
return /^component/.test(this.$route.name);
},
isHome() {
return /^home/.test(this.$route.name);
}
},
mounted() {
const testInnerImg = new Image();
testInnerImg.onload = () => {
this.$isEle = true;
ga('send', 'event', 'DocView', 'Ali', 'Inner');
};
testInnerImg.onerror = (err) => {
ga('send', 'event', 'DocView', 'Ali', 'Outer');
console.error(err);
};
testInnerImg.src = `https://private-alipayobjects.alipay.com/alipay-rmsdeploy-image/rmsportal/VmvVUItLdPNqKlNGuRHi.png?t=${Date.now()}`;
},
methods: {
switchVersion(version) {
if (version === this.version) return;
@@ -499,17 +440,6 @@
};
xhr.open('GET', '/versions.json');
xhr.send();
let primaryLast = '#409EFF';
bus.$on(ACTION_USER_CONFIG_UPDATE, (val) => {
let primaryColor = val.global['$--color-primary'];
if (!primaryColor) primaryColor = '#409EFF';
const base64svg = 'data:image/svg+xml;base64,';
const imgSet = document.querySelectorAll('h1 img');
imgSet.forEach((img) => {
img.src = `${base64svg}${window.btoa(window.atob(img.src.replace(base64svg, '')).replace(primaryLast, primaryColor))}`;
});
primaryLast = primaryColor;
});
}
};
</script>

View File

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

View File

@@ -1,4 +1,4 @@
<style lang="scss">
<style>
.side-nav {
width: 100%;
box-sizing: border-box;
@@ -122,6 +122,26 @@
:class="{ 'is-fade': isFade }"
:style="navStyle">
<ul>
<li class="nav-item sponsors">
<a>{{ lang === 'zh-CN' ? '赞助商' : 'Sponsors' }}</a>
<ul class="pure-menu-list sub-nav">
<li class="nav-item" v-show="lang !== 'zh-CN'">
<a href="https://tipe.io/?ref=element" target="_blank">
<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">
</a>
</li>
</ul>
</li>
<li
class="nav-item"
v-for="(item, key) in data"
@@ -160,7 +180,7 @@
<li
class="nav-item"
v-for="(navItem, key) in group.list"
v-show="!navItem.disabled"
v-if="!navItem.disabled"
:key="key">
<router-link
active-class="active"

View File

@@ -1,153 +0,0 @@
<template>
<div class="configurator-action">
<div class="action-group">
<el-tooltip :content="getActionDisplayName('undo')">
<img
src="../../assets/images/icon-undo.svg"
@click="onUndo"
:class="{ 'active': userConfigHistory.length > 0 }"
/>
</el-tooltip>
<el-tooltip :content="getActionDisplayName('redo')">
<img
src="../../assets/images/icon-redo.svg"
@click="onRedo"
:class="{ 'active': userConfigRedoHistory.length > 0 }"
/>
</el-tooltip>
<div class="button-group">
<el-button
class="reset"
type="primary"
round
size="mini"
:disabled="isOfficial"
@click="onReset"
>
{{getActionDisplayName('reset-theme')}}
</el-button>
<el-button
class="download"
type="primary"
round
size="mini"
:disabled="downloadDisabled"
@click="onDownload"
>
{{getActionDisplayName('download-theme')}}
</el-button>
</div>
</div>
<el-select v-model="selectedComponent" class="selector">
<el-option
v-for="item in selectOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<div class="line"></div>
</div>
</template>
<style lang="scss">
.configurator-action {
padding: 15px 18px 0;
.action-group {
padding: 5px 0;
img {
cursor: not-allowed;
width: 16px;
height: 16px;
padding: 7px 0;
margin-left: 5px;
opacity: .5;
&.active {
opacity: 1;
cursor: pointer;
}
&:last-of-type {
margin-left: 10px;
}
}
.button-group {
float: right;
.el-button {
padding: 6px 15px;
&.is-disabled {
color: #C0C4CC;
background-color: #fff;
border-color: #EBEEF5;
}
}
.reset {
background: #E6F1FC;
color: #1989FA;
border-color: #A2CFFC;
}
.download {
background: #1989FA;
color: #FFF;
border-color: #1989FA
}
}
}
.selector {
width: 100%;
input {
background: #f5f7fa;
border: none;
font-size: 18px;
padding-left: 0;
color: #606266;
}
}
.line {
width: 100%;
height: 0;
border-bottom: 1px solid #DCDFE6;
}
}
</style>
<script>
import { getActionDisplayName } from './utils/utils';
export default {
props: {
selectOptions: Array,
userConfigHistory: Array,
userConfigRedoHistory: Array,
isOfficial: Boolean,
onUndo: Function,
onRedo: Function
},
data() {
return {
selectedComponent: 'color',
downloadDisabled: false
};
},
watch: {
selectedComponent: {
handler(val) {
this.$emit('select', val);
}
}
},
methods: {
getActionDisplayName(key) {
return getActionDisplayName(key);
},
onReset() {
this.$parent.onReset();
},
onDownload() {
this.downloadDisabled = true;
this.$parent.onDownload();
setTimeout(() => {
this.downloadDisabled = false;
}, 2500);
}
}
};
</script>

View File

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

View File

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

View File

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

View File

@@ -1,316 +0,0 @@
const hsv2hsl = function(hue, sat, val) {
return [
hue,
(sat * val / ((hue = (2 - sat) * val) < 1 ? hue : 2 - hue)) || 0,
hue / 2
];
};
// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
const isOnePointZero = function(n) {
return typeof n === 'string' && n.indexOf('.') !== -1 && parseFloat(n) === 1;
};
const isPercentage = function(n) {
return typeof n === 'string' && n.indexOf('%') !== -1;
};
// Take input from [0, n] and return it as [0, 1]
const bound01 = function(value, max) {
if (isOnePointZero(value)) value = '100%';
const processPercent = isPercentage(value);
value = Math.min(max, Math.max(0, parseFloat(value)));
// Automatically convert percentage into number
if (processPercent) {
value = parseInt(value * max, 10) / 100;
}
// Handle floating point rounding errors
if ((Math.abs(value - max) < 0.000001)) {
return 1;
}
// Convert into [0, 1] range if it isn't already
return (value % max) / parseFloat(max);
};
const INT_HEX_MAP = { 10: 'A', 11: 'B', 12: 'C', 13: 'D', 14: 'E', 15: 'F' };
const toHex = function({ r, g, b }) {
const hexOne = function(value) {
value = Math.min(Math.round(value), 255);
const high = Math.floor(value / 16);
const low = value % 16;
return '' + (INT_HEX_MAP[high] || high) + (INT_HEX_MAP[low] || low);
};
if (isNaN(r) || isNaN(g) || isNaN(b)) return '';
return '#' + hexOne(r) + hexOne(g) + hexOne(b);
};
const HEX_INT_MAP = { A: 10, B: 11, C: 12, D: 13, E: 14, F: 15 };
const parseHexChannel = function(hex) {
if (hex.length === 2) {
return (HEX_INT_MAP[hex[0].toUpperCase()] || +hex[0]) * 16 + (HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1]);
}
return HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1];
};
const hsl2hsv = function(hue, sat, light) {
sat = sat / 100;
light = light / 100;
let smin = sat;
const lmin = Math.max(light, 0.01);
let sv;
let v;
light *= 2;
sat *= (light <= 1) ? light : 2 - light;
smin *= lmin <= 1 ? lmin : 2 - lmin;
v = (light + sat) / 2;
sv = light === 0 ? (2 * smin) / (lmin + smin) : (2 * sat) / (light + sat);
return {
h: hue,
s: sv * 100,
v: v * 100
};
};
// `rgbToHsv`
// Converts an RGB color value to HSV
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
// *Returns:* { h, s, v } in [0,1]
const rgb2hsv = function(r, g, b) {
r = bound01(r, 255);
g = bound01(g, 255);
b = bound01(b, 255);
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h, s;
let v = max;
const d = max - min;
s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0; // achromatic
} else {
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return { h: h * 360, s: s * 100, v: v * 100 };
};
// `hsvToRgb`
// Converts an HSV color value to RGB.
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
// *Returns:* { r, g, b } in the set [0, 255]
const hsv2rgb = function(h, s, v) {
h = bound01(h, 360) * 6;
s = bound01(s, 100);
v = bound01(v, 100);
const i = Math.floor(h);
const f = h - i;
const p = v * (1 - s);
const q = v * (1 - f * s);
const t = v * (1 - (1 - f) * s);
const mod = i % 6;
const r = [v, q, p, p, t, v][mod];
const g = [t, v, v, q, p, p][mod];
const b = [p, p, t, v, v, q][mod];
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
};
export default class Color {
constructor(options) {
this._hue = 0;
this._saturation = 100;
this._value = 100;
this._alpha = 100;
this.enableAlpha = false;
this.format = 'hex';
this.value = '';
options = options || {};
for (let option in options) {
if (options.hasOwnProperty(option)) {
this[option] = options[option];
}
}
this.doOnChange();
}
set(prop, value) {
if (arguments.length === 1 && typeof prop === 'object') {
for (let p in prop) {
if (prop.hasOwnProperty(p)) {
this.set(p, prop[p]);
}
}
return;
}
this['_' + prop] = value;
this.doOnChange();
}
get(prop) {
return this['_' + prop];
}
toRgb() {
return hsv2rgb(this._hue, this._saturation, this._value);
}
fromString(value) {
if (!value) {
this._hue = 0;
this._saturation = 100;
this._value = 100;
this.doOnChange();
return;
}
const fromHSV = (h, s, v) => {
this._hue = Math.max(0, Math.min(360, h));
this._saturation = Math.max(0, Math.min(100, s));
this._value = Math.max(0, Math.min(100, v));
this.doOnChange();
};
if (value.indexOf('hsl') !== -1) {
const parts = value.replace(/hsla|hsl|\(|\)/gm, '')
.split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10));
if (parts.length === 4) {
this._alpha = Math.floor(parseFloat(parts[3]) * 100);
} else if (parts.length === 3) {
this._alpha = 100;
}
if (parts.length >= 3) {
const { h, s, v } = hsl2hsv(parts[0], parts[1], parts[2]);
fromHSV(h, s, v);
}
} else if (value.indexOf('hsv') !== -1) {
const parts = value.replace(/hsva|hsv|\(|\)/gm, '')
.split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10));
if (parts.length === 4) {
this._alpha = Math.floor(parseFloat(parts[3]) * 100);
} else if (parts.length === 3) {
this._alpha = 100;
}
if (parts.length >= 3) {
fromHSV(parts[0], parts[1], parts[2]);
}
} else if (value.indexOf('rgb') !== -1) {
const parts = value.replace(/rgba|rgb|\(|\)/gm, '')
.split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10));
if (parts.length === 4) {
this._alpha = Math.floor(parseFloat(parts[3]) * 100);
} else if (parts.length === 3) {
this._alpha = 100;
}
if (parts.length >= 3) {
const { h, s, v } = rgb2hsv(parts[0], parts[1], parts[2]);
fromHSV(h, s, v);
}
} else if (value.indexOf('#') !== -1) {
const hex = value.replace('#', '').trim();
let r, g, b;
if (hex.length === 3) {
r = parseHexChannel(hex[0] + hex[0]);
g = parseHexChannel(hex[1] + hex[1]);
b = parseHexChannel(hex[2] + hex[2]);
} else if (hex.length === 6 || hex.length === 8) {
r = parseHexChannel(hex.substring(0, 2));
g = parseHexChannel(hex.substring(2, 4));
b = parseHexChannel(hex.substring(4, 6));
}
if (hex.length === 8) {
this._alpha = Math.floor(parseHexChannel(hex.substring(6)) / 255 * 100);
} else if (hex.length === 3 || hex.length === 6) {
this._alpha = 100;
}
const { h, s, v } = rgb2hsv(r, g, b);
fromHSV(h, s, v);
}
}
compare(color) {
return Math.abs(color._hue - this._hue) < 2 &&
Math.abs(color._saturation - this._saturation) < 1 &&
Math.abs(color._value - this._value) < 1 &&
Math.abs(color._alpha - this._alpha) < 1;
}
doOnChange() {
const { _hue, _saturation, _value, _alpha, format } = this;
if (this.enableAlpha) {
switch (format) {
case 'hsl':
const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100);
this.value = `hsla(${ _hue }, ${ Math.round(hsl[1] * 100) }%, ${ Math.round(hsl[2] * 100) }%, ${ _alpha / 100})`;
break;
case 'hsv':
this.value = `hsva(${ _hue }, ${ Math.round(_saturation) }%, ${ Math.round(_value) }%, ${ _alpha / 100})`;
break;
default:
const { r, g, b } = hsv2rgb(_hue, _saturation, _value);
this.value = `rgba(${r}, ${g}, ${b}, ${ _alpha / 100 })`;
}
} else {
switch (format) {
case 'hsl':
const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100);
this.value = `hsl(${ _hue }, ${ Math.round(hsl[1] * 100) }%, ${ Math.round(hsl[2] * 100) }%)`;
break;
case 'hsv':
this.value = `hsv(${ _hue }, ${ Math.round(_saturation) }%, ${ Math.round(_value) }%)`;
break;
case 'rgb':
const { r, g, b } = hsv2rgb(_hue, _saturation, _value);
this.value = `rgb(${r}, ${g}, ${b})`;
break;
default:
this.value = toHex(hsv2rgb(_hue, _saturation, _value));
}
}
}
};

View File

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

View File

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

View File

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

View File

@@ -1,135 +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"
type="primary"
class="el-color-dropdown__btn"
@click="confirmValue">
{{ t('el.colorpicker.confirm') }}
</el-button>
</div>
<color-list
v-if="colorList && colorList.length > 0"
:color="color"
:colors="colorList"
@select=onColorListSelect
></color-list>
</div>
</transition>
</template>
<script>
import SvPanel from './sv-panel';
import HueSlider from './hue-slider';
import AlphaSlider from './alpha-slider';
import Predefine from './predefine';
import ColorList from './color-list';
import Popper from 'element-ui/src/utils/vue-popper';
import Locale from 'element-ui/src/mixins/locale';
import ElInput from 'element-ui/packages/input';
import ElButton from 'element-ui/packages/button';
export default {
name: 'el-color-picker-dropdown',
mixins: [Popper, Locale],
components: {
SvPanel,
HueSlider,
AlphaSlider,
ElInput,
ElButton,
Predefine,
ColorList
},
props: {
color: {
required: true
},
showAlpha: Boolean,
predefine: Array,
colorList: Array
},
data() {
return {
customInput: ''
};
},
computed: {
currentColor() {
const parent = this.$parent;
return !parent.value && !parent.showPanelColor ? '' : parent.color.value;
}
},
methods: {
confirmValue() {
this.$emit('pick');
},
onColorListSelect(e) {
this.$emit('pick', e);
},
handleConfirm() {
this.color.fromString(this.customInput);
}
},
mounted() {
this.$parent.popperElm = this.popperElm = this.$el;
this.referenceElm = this.$parent.$el;
},
watch: {
showPopper(val) {
if (val === true) {
this.$nextTick(() => {
const { sl, hue, alpha } = this.$refs;
sl && sl.update();
hue && hue.update();
alpha && alpha.update();
});
}
},
currentColor: {
immediate: true,
handler(val) {
this.customInput = val;
}
}
}
};
</script>

View File

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

View File

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

View File

@@ -1,36 +0,0 @@
import Vue from 'vue';
let isDragging = false;
export default function(element, options) {
if (Vue.prototype.$isServer) return;
const moveFn = function(event) {
if (options.drag) {
options.drag(event);
}
};
const upFn = function(event) {
document.removeEventListener('mousemove', moveFn);
document.removeEventListener('mouseup', upFn);
document.onselectstart = null;
document.ondragstart = null;
isDragging = false;
if (options.end) {
options.end(event);
}
};
element.addEventListener('mousedown', function(event) {
if (isDragging) return;
document.onselectstart = function() { return false; };
document.ondragstart = function() { return false; };
document.addEventListener('mousemove', moveFn);
document.addEventListener('mouseup', upFn);
isDragging = true;
if (options.start) {
options.start(event);
}
});
}

View File

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

View File

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

View File

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

View File

@@ -1,105 +0,0 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
<el-tooltip :content="displayName" placement="top">
<span>{{displayKeyName}}</span>
</el-tooltip>
</div>
<div class="config-content">
<el-select
v-model="value"
class="select"
size="medium"
@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',
'22px',
'28px',
'36px',
'48px'
];
import Mixin from './mixin';
import { getStyleDisplayName } from '../utils/utils.js';
export default {
props: {
componentName: {
type: String
},
golbalValue: {
type: Object
}
},
data() {
return {
options: [],
value: ''
};
},
mixins: [Mixin],
computed: {
isGlobalInputValue() {
return this.config.value.startsWith('$');
}
},
methods: {
onSelectChange(e) {
this.onChange(e);
},
initSelectOption() {
this.options = [];
defaultFontSize.forEach((size) => {
this.options.push({
value: size,
label: size
});
});
const golbalTypography = this.golbalValue.typography;
if (this.isGlobalInputValue && golbalTypography) {
Object.keys(golbalTypography).forEach((font) => {
if (font.includes('font-size')) {
const size = golbalTypography[font];
this.options.push({
value: size.key,
label: getStyleDisplayName(size)
});
}
});
}
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.initSelectOption();
this.value = this.mergedValue;
}
}
}
};
</script>

View File

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

View File

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

View File

@@ -1,81 +0,0 @@
<style>
.config {
padding: 5px 0;
}
.config-label {
color: #606266;;
font-size: 14px;
padding-bottom: 8px;
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);
},
displayKeyName() {
if (this.config.name) {
return this.config.key.replace('$--', '');
}
return this.config.key.replace(`$--${this.componentName}-`, '');
},
isGlobal() {
return !this.config.value.startsWith('$');
}
},
methods: {
onChange(value) {
this.$emit('onChange', {
key: this.config.key,
value
});
}
}
};
</script>

View File

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

View File

@@ -1,195 +0,0 @@
<template>
<div class="main-configurator" ref='configurator'>
<action-panel
:selectOptions="selectOptions"
:userConfigHistory="userConfigHistory"
:userConfigRedoHistory="userConfigRedoHistory"
:onUndo="undo"
:onRedo="redo"
:isOfficial="isOfficial"
@select="onSelectChange"
></action-panel>
<main-panel
v-if="defaultConfig"
:currentConfig="currentConfig"
:defaultConfig="defaultConfig"
:userConfig="userConfig"
:globalValue="globalValue"
@onChange="userConfigChange"
></main-panel>
</div>
</template>
<style lang="scss">
.main-configurator {
height: 100%;
display: flex;
flex-direction: column;
}
</style>
<script>
import bus from '../../bus.js';
import { getVars } from '../theme/loader/api.js';
import mainPanel from './main';
import actionPanel from './action';
import {
filterConfigType,
filterGlobalValue,
getActionDisplayName
} from './utils/utils.js';
import Shortcut from './shortcut';
import {
ACTION_APPLY_THEME,
ACTION_DOWNLOAD_THEME,
ACTION_COMPONECT_SELECT
} from '../theme/constant.js';
export default {
props: {
themeConfig: Object,
previewConfig: Object,
isOfficial: Boolean,
onUserConfigUpdate: Function
},
components: {
mainPanel,
actionPanel
},
data() {
return {
init: false,
defaultConfig: null,
currentConfig: null,
userConfig: {
global: {},
local: {}
},
userConfigHistory: [],
userConfigRedoHistory: [],
hasLocalConfig: false,
selectOptions: [],
selectedComponent: 'color'
};
},
mixins: [Shortcut],
computed: {
globalValue() {
return filterGlobalValue(this.defaultConfig, this.userConfig);
}
},
mounted() {
ga('send', 'event', 'ThemeConfigurator', 'Init');
this.showConfigurator();
this.enableShortcut();
},
beforeDestroy() {
this.disableShortcut();
},
methods: {
getActionDisplayName(key) {
return getActionDisplayName(key);
},
showConfigurator() {
if (this.init) return;
this.$nextTick(() => {
const loading = this.$loading({
target: this.$refs.configurator
});
let defaultConfig;
getVars()
.then(res => {
defaultConfig = res;
})
.catch(err => {
this.onError && this.onError(err);
})
.then(() => {
setTimeout(() => {
if (defaultConfig) {
this.defaultConfig = defaultConfig;
this.setSelectOption();
this.filterCurrentConfig();
this.init = true;
}
loading.close();
}, 300); // action after transition
});
});
},
setSelectOption() {
this.selectOptions = this.defaultConfig.map((config) => ({
label: config.name.charAt(0).toUpperCase() + config.name.slice(1),
value: config.name
})).sort((a, b) => {
const A = a.label;
const B = b.label;
if (A < B) return -1;
if (A > B) return 1;
return 0;
});
},
filterCurrentConfig() {
this.currentConfig = this.defaultConfig.find(config => {
return (
config.name === this.selectedComponent
);
});
},
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();
},
onReset() {
this.userConfigRedoHistory = [];
this.userConfigHistory = [];
this.userConfig = {
global: {},
local: {}
};
this.onAction();
},
onDownload() {
bus.$emit(ACTION_DOWNLOAD_THEME, this.userConfig, this.previewConfig.name);
},
onAction() {
this.onUserConfigUpdate(this.userConfig);
bus.$emit(ACTION_APPLY_THEME, this.userConfig);
},
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();
}
},
onSelectChange(val) {
bus.$emit(ACTION_COMPONECT_SELECT, val);
this.selectedComponent = val;
this.filterCurrentConfig();
}
},
watch: {
themeConfig: {
handler(val, oldVal) {
if (!oldVal.globnal) {
this.userConfig = val;
}
}
}
}
};
</script>

View File

@@ -1,130 +0,0 @@
<template>
<div class="editor-main" ref="mainPanel">
<!-- <span>{{configName}}</span> -->
<div v-for="(config, key) in configByOrder" :key="key">
<span
v-if="showCategory(config.category, key + 1)"
class="category-name"
>
{{config.category}}
</span>
<component
:is="editorComponent(config.type)"
:componentName=configName
:config=config
:userConfig=userConfigByType
:golbalValue=globalValue
@onChange=onChange
>
</component>
</div>
</div>
</template>
<style>
.editor-main {
padding: 0 18px 15px;
overflow-y: auto;
}
.category-name {
color: #C0C4CC;
font-size: 18px;
display: block;
margin: 13px 0 3px 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 } 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: {
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: {}
};
},
watch: {
currentConfig: {
handler() {
this.$nextTick(() => {
this.$refs.mainPanel.scrollTo(0, 0);
});
}
}
}
};
</script>

View File

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

View File

@@ -1,59 +0,0 @@
const VALUES_REG = /,(?![^\(]*\))/;
const PARTS_REG = /\s(?![^(]*\))/;
const LENGTH_REG = /^[0-9]+[a-zA-Z%]+?$/;
const parseValue = str => {
const parts = str.split(PARTS_REG);
const inset = parts.includes('inset');
const last = parts.slice(-1)[0];
const color = !isLength(last) ? last : undefined;
const nums = parts
.filter(n => n !== 'inset')
.filter(n => n !== color)
.map(toNum);
const [ offsetX, offsetY, blurRadius, spreadRadius ] = nums;
return {
inset,
offsetX,
offsetY,
blurRadius,
spreadRadius,
color
};
};
const stringifyValue = obj => {
const {
inset,
offsetX = 0,
offsetY = 0,
blurRadius = 0,
spreadRadius,
color
} = obj || {};
return [
(inset ? 'inset' : null),
offsetX,
offsetY,
blurRadius,
spreadRadius,
color
].filter(v => v !== null && v !== undefined)
.map(toPx)
.map(s => ('' + s).trim())
.join(' ');
};
const isLength = v => v === '0' || LENGTH_REG.test(v);
const toNum = v => {
if (!/px$/.test(v) && v !== '0') return v;
const n = parseFloat(v);
return !isNaN(n) ? n : v;
};
const toPx = n => typeof n === 'number' && n !== 0 ? (n + 'px') : n;
export const parse = str => str.split(VALUES_REG).map(s => s.trim()).map(parseValue);
export const stringify = arr => arr.map(stringifyValue).join(', ');

View File

@@ -1,68 +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}-`, '');
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;
};

View File

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

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