Compare commits
120 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
19b005867f | |
|
|
e8a1a4a217 | |
|
|
69d5aa795a | |
|
|
bda27eb39b | |
|
|
4136b3b62a | |
|
|
43a48ed422 | |
|
|
2afccac35e | |
|
|
dac22759db | |
|
|
3a85220a57 | |
|
|
acaad27135 | |
|
|
80da77aee0 | |
|
|
773ca392d8 | |
|
|
24ce72ef83 | |
|
|
2c81ccc6f0 | |
|
|
7eb0422f79 | |
|
|
11e0994012 | |
|
|
233ef9f2cf | |
|
|
441024b993 | |
|
|
115ca4d8ec | |
|
|
e70738137e | |
|
|
ef7d0cf0d2 | |
|
|
911ea488bd | |
|
|
7779c0469c | |
|
|
2b1b81b6ff | |
|
|
7b317a2765 | |
|
|
74133d18af | |
|
|
f1488e1545 | |
|
|
72b1312209 | |
|
|
e99e382ce6 | |
|
|
89c134a7b7 | |
|
|
b0d226d33e | |
|
|
4c559c86ab | |
|
|
66219e2b86 | |
|
|
6953698385 | |
|
|
a4ce890dd6 | |
|
|
74007fbb16 | |
|
|
833cd47955 | |
|
|
72ca67b103 | |
|
|
9b5a36186b | |
|
|
4eb26eaec3 | |
|
|
5c8b82ccf4 | |
|
|
56991e5488 | |
|
|
e1ac8ce6f0 | |
|
|
e218afd787 | |
|
|
d0c7c0b128 | |
|
|
fb94e7c119 | |
|
|
2f1eb4bbb7 | |
|
|
9bb90e78d1 | |
|
|
23ab83c533 | |
|
|
23fb9fae7c | |
|
|
f4d8db07fa | |
|
|
45c7163b58 | |
|
|
3e617bd4d2 | |
|
|
c0c3b93f0f | |
|
|
958e5e488e | |
|
|
bb56898edc | |
|
|
cc257200e5 | |
|
|
5cec702e0c | |
|
|
c2449f568e | |
|
|
96709926e8 | |
|
|
e95eb61bcb | |
|
|
663aa34d84 | |
|
|
3761eddb4b | |
|
|
6fca13fb2c | |
|
|
61fa2cfdf6 | |
|
|
8fc617a4d7 | |
|
|
e0967d9d7e | |
|
|
cdde89b17e | |
|
|
7c1a14bb5e | |
|
|
28325c0507 | |
|
|
5e139a13e8 | |
|
|
976b0b409c | |
|
|
dfcdf92f7a | |
|
|
dced59c65c | |
|
|
48181af9d6 | |
|
|
e427ca15bf | |
|
|
7f4eba3e93 | |
|
|
961524b0a7 | |
|
|
391309aad7 | |
|
|
5e063ba9a3 | |
|
|
22dccf46c5 | |
|
|
1031e46926 | |
|
|
76d8408045 | |
|
|
48bf9ff1b5 | |
|
|
96e5e836b7 | |
|
|
e179dedb4a | |
|
|
1e2814608d | |
|
|
0f467695e2 | |
|
|
6175fdbb0c | |
|
|
ec064fe8c2 | |
|
|
c74c621e7f | |
|
|
8ba75419b6 | |
|
|
1581ff3057 | |
|
|
6ecbaaa547 | |
|
|
388ed15e82 | |
|
|
d552a41e96 | |
|
|
c57df7db0c | |
|
|
bb8bf0e0f8 | |
|
|
1d2b93c871 | |
|
|
ee0470c280 | |
|
|
aa1c9b237e | |
|
|
1aca897b97 | |
|
|
5eb57fb1a9 | |
|
|
a60ba677c2 | |
|
|
f194973151 | |
|
|
ef9797d337 | |
|
|
ce1148838b | |
|
|
dae751368b | |
|
|
5597ec0a91 | |
|
|
f26c0218d5 | |
|
|
aed1ff0660 | |
|
|
a43b128262 | |
|
|
6c521620b6 | |
|
|
4a3e310db7 | |
|
|
5c8b77957c | |
|
|
346a5ce2ba | |
|
|
4851d10f60 | |
|
|
6e35cec375 | |
|
|
b690b38b7e | |
|
|
ab7bb9068b |
|
|
@ -1,36 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const restCssPath = path.join(process.cwd(), 'components', 'style', 'reset.css');
|
||||
const tokenStatisticPath = path.join(process.cwd(), 'components', 'version', 'token.json');
|
||||
const tokenMetaPath = path.join(process.cwd(), 'components', 'version', 'token-meta.json');
|
||||
|
||||
function finalizeCompile() {
|
||||
if (fs.existsSync(path.join(__dirname, './es'))) {
|
||||
fs.copyFileSync(restCssPath, path.join(process.cwd(), 'es', 'style', 'reset.css'));
|
||||
fs.copyFileSync(tokenStatisticPath, path.join(process.cwd(), 'es', 'version', 'token.json'));
|
||||
fs.copyFileSync(tokenMetaPath, path.join(process.cwd(), 'es', 'version', 'token-meta.json'));
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.join(__dirname, './lib'))) {
|
||||
fs.copyFileSync(restCssPath, path.join(process.cwd(), 'lib', 'style', 'reset.css'));
|
||||
fs.copyFileSync(tokenStatisticPath, path.join(process.cwd(), 'lib', 'version', 'token.json'));
|
||||
fs.copyFileSync(tokenMetaPath, path.join(process.cwd(), 'lib', 'version', 'token-meta.json'));
|
||||
}
|
||||
}
|
||||
|
||||
function finalizeDist() {
|
||||
if (fs.existsSync(path.join(__dirname, './dist'))) {
|
||||
fs.copyFileSync(restCssPath, path.join(process.cwd(), 'dist', 'reset.css'));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
compile: {
|
||||
finalize: finalizeCompile,
|
||||
},
|
||||
dist: {
|
||||
finalize: finalizeDist,
|
||||
},
|
||||
bail: true,
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"env": {
|
||||
"test": {
|
||||
"presets": [["env", { "targets": { "node": "current" } }]],
|
||||
"plugins": [
|
||||
"transform-vue-jsx",
|
||||
"transform-object-assign",
|
||||
"transform-object-rest-spread",
|
||||
"transform-class-properties",
|
||||
"transform-runtime"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,3 @@ es/
|
|||
lib/
|
||||
_site/
|
||||
dist/
|
||||
site/dist/
|
||||
components/version/version.ts
|
||||
site/src/router/demoRoutes.js
|
||||
locale/
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"jasmine": true,
|
||||
"jest": true,
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"extends": ["plugin:vue/recommended", "prettier"],
|
||||
"plugins": ["markdown"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/demo/*.md"],
|
||||
"processor": "markdown/markdown",
|
||||
"rules": {
|
||||
"no-console": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": {
|
||||
"comma-dangle": [2, "always-multiline"],
|
||||
"no-var": "error",
|
||||
"no-console": [2, { "allow": ["warn", "error"] }],
|
||||
"object-shorthand": 2,
|
||||
"no-unused-vars": [2, { "ignoreRestSiblings": true, "argsIgnorePattern": "^h$" }],
|
||||
"no-undef": 2,
|
||||
"camelcase": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
"semi": ["error", "always"],
|
||||
"vue/require-prop-types": "off",
|
||||
"vue/require-default-prop": "off",
|
||||
"vue/no-reserved-keys": "off",
|
||||
"vue/comment-directive": "off",
|
||||
"vue/prop-name-casing": "off",
|
||||
"vue/max-attributes-per-line": [
|
||||
2,
|
||||
{
|
||||
"singleline": 20,
|
||||
"multiline": {
|
||||
"max": 1,
|
||||
"allowFirstLine": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"globals": {
|
||||
"h": true
|
||||
}
|
||||
}
|
||||
112
.eslintrc.js
112
.eslintrc.js
|
|
@ -1,112 +0,0 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
jasmine: true,
|
||||
jest: true,
|
||||
es6: true,
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
},
|
||||
extends: [
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'@vue/typescript/recommended',
|
||||
'@vue/prettier',
|
||||
// 'prettier',
|
||||
],
|
||||
// extends: [
|
||||
// 'eslint:recommended',
|
||||
// 'plugin:vue/vue3-recommended',
|
||||
// '@vue/typescript/recommended',
|
||||
// '@vue/prettier',
|
||||
// ],
|
||||
plugins: ['markdown', 'jest', '@typescript-eslint', 'import'],
|
||||
globals: {
|
||||
h: true,
|
||||
defineProps: 'readonly',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.md'],
|
||||
processor: 'markdown/markdown',
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*.ts', '*.tsx'],
|
||||
// extends: ['@vue/typescript/recommended', '@vue/prettier'],
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/ban-types': 0,
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 0,
|
||||
'@typescript-eslint/no-empty-function': 0,
|
||||
'@typescript-eslint/no-non-null-assertion': 0,
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{ vars: 'all', args: 'after-used', ignoreRestSiblings: true },
|
||||
],
|
||||
'@typescript-eslint/ban-ts-comment': 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*.vue'],
|
||||
parser: 'vue-eslint-parser',
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser',
|
||||
ecmaVersion: 2021,
|
||||
},
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
'vue/no-reserved-component-names': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 0,
|
||||
'@typescript-eslint/no-empty-function': 0,
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{ vars: 'all', args: 'after-used', ignoreRestSiblings: true, argsIgnorePattern: '^_' },
|
||||
],
|
||||
'import/no-named-as-default': 'off',
|
||||
'import/namespace': [2, { allowComputed: true }],
|
||||
'import/no-named-as-default-member': 'off',
|
||||
'import/no-unresolved': [2, { ignore: ['ant-design-vue'] }],
|
||||
'comma-dangle': [2, 'always-multiline'],
|
||||
'no-var': 'error',
|
||||
'no-console': [2, { allow: ['warn', 'error'] }],
|
||||
'object-shorthand': 2,
|
||||
'no-unused-vars': [2, { ignoreRestSiblings: true, argsIgnorePattern: '^_' }],
|
||||
'no-undef': 2,
|
||||
camelcase: 'off',
|
||||
'no-extra-boolean-cast': 'off',
|
||||
semi: ['error', 'always'],
|
||||
'vue/no-v-html': 'off',
|
||||
'vue/require-explicit-emits': 'off',
|
||||
'vue/require-prop-types': 'off',
|
||||
'vue/require-default-prop': 'off',
|
||||
'vue/no-reserved-keys': 'off',
|
||||
'vue/comment-directive': 'off',
|
||||
'vue/prop-name-casing': 'off',
|
||||
'vue/one-component-per-file': 'off',
|
||||
'vue/custom-event-name-casing': 'off',
|
||||
'vue/v-on-event-hyphenation': 'off',
|
||||
'vue/max-attributes-per-line': [
|
||||
2,
|
||||
{
|
||||
singleline: 20,
|
||||
multiline: 1,
|
||||
},
|
||||
],
|
||||
'vue/multi-word-component-names': 'off',
|
||||
},
|
||||
};
|
||||
|
|
@ -1,2 +1 @@
|
|||
*.jsx linguist-language=Vue
|
||||
*.tsx linguist-language=Vue
|
||||
|
|
|
|||
|
|
@ -3,3 +3,10 @@
|
|||
github: # [tangjinzhou]
|
||||
open_collective: ant-design-vue
|
||||
patreon: tangjinzhou
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
custom:
|
||||
[
|
||||
"https://www.paypal.me/tangjinzhou",
|
||||
"https://www.buymeacoffee.com/antdv"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
blank_issues_enabled: true
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Create new issue
|
||||
url: https://vuecomponent.github.io/issue-helper/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
First of all, thank you for your contribution! 😄
|
||||
|
||||
New feature please send pull request to feature branch, and rest to master branch. Pull request will be merged after one of collaborators approve. Please makes sure that these form are filled before submitting your pull request, thank you!
|
||||
|
||||
[[中文版模板 / Chinese template](https://github.com/vueComponent/ant-design-vue/blob/master/.github/PULL_REQUEST_TEMPLATE/pr_cn.md)]
|
||||
|
||||
### This is a ...
|
||||
|
||||
- [ ] New feature
|
||||
- [ ] Bug fix
|
||||
- [ ] Site / document update
|
||||
- [ ] Component style update
|
||||
- [ ] TypeScript definition update
|
||||
- [ ] Refactoring
|
||||
- [ ] Code style optimization
|
||||
- [ ] Branch merge
|
||||
- [ ] Other (about what?)
|
||||
|
||||
### What's the background?
|
||||
|
||||
> 1. Describe the source of requirement.
|
||||
> 2. Resolve what problem.
|
||||
> 3. Related issue link.
|
||||
|
||||
### API Realization (Optional if not new feature)
|
||||
|
||||
> 1. Basic thought of solution and other optional proposal.
|
||||
> 2. List final API realization and usage sample.
|
||||
> 3. GIF or snapshot should be provided if includes UI/interactive modification.
|
||||
|
||||
### What's the effect? (Optional if not new feature)
|
||||
|
||||
> 1. Does this PR affect user? Which part will be affected?
|
||||
> 2. What will say in changelog?
|
||||
> 3. Does this PR contains potential break change or other risk?
|
||||
|
||||
### Changelog description (Optional if not new feature)
|
||||
|
||||
> 1. English description
|
||||
> 2. Chinese description (optional)
|
||||
|
||||
### Self Check before Merge
|
||||
|
||||
- [ ] Doc is updated/provided or not needed
|
||||
- [ ] Demo is updated/provided or not needed
|
||||
- [ ] TypeScript definition is updated/provided or not needed
|
||||
- [ ] Changelog is provided or not needed
|
||||
|
||||
### Additional Plan? (Optional if not new feature)
|
||||
|
||||
> If this PR related with other PR or following info. You can type here.
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
首先,感谢你的贡献! 😄
|
||||
|
||||
新特性请提交至 feature 分支,其余可提交至 main 分支。在一个维护者审核通过后合并。请确保填写以下 pull request 的信息,谢谢!~
|
||||
新特性请提交至 feature 分支,其余可提交至 master 分支。在一个维护者审核通过后合并。请确保填写以下 pull request 的信息,谢谢!~
|
||||
|
||||
[[English Template / 英文模板](./pr_en.md)]
|
||||
[[English Template / 英文模板](?expand=1)]
|
||||
|
||||
### 这个变动的性质是
|
||||
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
First of all, thank you for your contribution! 😄
|
||||
|
||||
New feature please send pull request to feature branch, and rest to main branch. Pull request will be merged after one of collaborators approve. Please makes sure that these form are filled before submitting your pull request, thank you!
|
||||
|
||||
[[中文版模板 / Chinese template](./pr_cn.md)]
|
||||
|
||||
### This is a ...
|
||||
|
||||
- [ ] New feature
|
||||
- [ ] Bug fix
|
||||
- [ ] Site / document update
|
||||
- [ ] Component style update
|
||||
- [ ] TypeScript definition update
|
||||
- [ ] Refactoring
|
||||
- [ ] Code style optimization
|
||||
- [ ] Branch merge
|
||||
- [ ] Other (about what?)
|
||||
|
||||
### What's the background?
|
||||
|
||||
> 1. Describe the source of requirement.
|
||||
> 2. Resolve what problem.
|
||||
> 3. Related issue link.
|
||||
|
||||
### API Realization (Optional if not new feature)
|
||||
|
||||
> 1. Basic thought of solution and other optional proposal.
|
||||
> 2. List final API realization and usage sample.
|
||||
> 3. GIF or snapshot should be provided if includes UI/interactive modification.
|
||||
|
||||
### What's the effect? (Optional if not new feature)
|
||||
|
||||
> 1. Does this PR affect user? Which part will be affected?
|
||||
> 2. What will say in changelog?
|
||||
> 3. Does this PR contains potential break change or other risk?
|
||||
|
||||
### Changelog description (Optional if not new feature)
|
||||
|
||||
> 1. English description
|
||||
> 2. Chinese description (optional)
|
||||
|
||||
### Self Check before Merge
|
||||
|
||||
- [ ] Doc is updated/provided or not needed
|
||||
- [ ] Demo is updated/provided or not needed
|
||||
- [ ] TypeScript definition is updated/provided or not needed
|
||||
- [ ] Changelog is provided or not needed
|
||||
|
||||
### Additional Plan? (Optional if not new feature)
|
||||
|
||||
> If this PR related with other PR or following info. You can type here.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
name: Build and Deploy to Cloudflare
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
branches: [ 1.x ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
@ -20,17 +20,22 @@ jobs:
|
|||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Install dependencies
|
||||
- name: Install root dependencies
|
||||
run: npm install --force
|
||||
|
||||
- name: Install antdv-demo dependencies
|
||||
working-directory: antdv-demo
|
||||
run: npm install --force
|
||||
|
||||
- name: Build application
|
||||
working-directory: antdv-demo
|
||||
run: npm run build
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-files
|
||||
path: site/dist/
|
||||
path: antdv-demo/_site/
|
||||
retention-days: 1
|
||||
|
||||
deploy:
|
||||
|
|
@ -52,7 +57,7 @@ jobs:
|
|||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-files
|
||||
path: site/dist/
|
||||
path: antdv-demo/_site/
|
||||
|
||||
- name: Deploy (Workers + Static Assets)
|
||||
uses: cloudflare/wrangler-action@v3.14.1
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: cache package-lock.json
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: create package-lock.json
|
||||
run: npm i --package-lock-only --ignore-scripts
|
||||
run: npm i --package-lock-only
|
||||
|
||||
- name: hack for singe file
|
||||
run: |
|
||||
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
|
||||
- name: cache node_modules
|
||||
id: node_modules_cache_id
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
@ -41,24 +41,17 @@ jobs:
|
|||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
# with:
|
||||
# token: ${{ secrets.ACCESS_TOKEN }}
|
||||
# - name: Checkout submodules
|
||||
# uses: actions/checkout@v2
|
||||
# with:
|
||||
# repository: tangjinzhou/antdv-demo
|
||||
# token: ${{ secrets.ACCESS_TOKEN }}
|
||||
# path: antdv-demo
|
||||
# submodules: true
|
||||
with:
|
||||
token: ${{ secrets.ACCESS_TOKEN }}
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
name: Emoji Helper
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
emoji:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions-cool/emoji-helper@v1.0.0
|
||||
with:
|
||||
type: 'release'
|
||||
emoji: '+1, laugh, heart, hooray, rocket, eyes'
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
name: Issue Close Require
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: need reproduce
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'close-issues'
|
||||
labels: '🤔 Need Reproduce'
|
||||
inactive-day: 7
|
||||
body: |
|
||||
Since the issue was labeled with `Need Reproduce`, but no response in 7 days. This issue will be closed. If you have any questions, you can comment and reply.
|
||||
|
||||
由于该 issue 被标记为需要复现信息,却 7 天未收到回应。现关闭 issue,若有任何问题,可评论回复。
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
name: Issue Labeled
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
issue-labeled:
|
||||
permissions:
|
||||
issues: write # for actions-cool/issues-helper to update issues
|
||||
pull-requests: write # for actions-cool/issues-helper to update PRs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Need Reproduce
|
||||
if: github.event.label.name == '🤔 Need Reproduce'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'create-comment'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hello @${{ github.event.issue.user.login }}. Please provide a online reproduction by forking this [link for vue2](https://codesandbox.io/s/2wpk21kzvr)、 [link for vue3](https://codesandbox.io/s/agitated-franklin-1w72v) or a minimal GitHub repository. Make sure to choose the correct version.
|
||||
|
||||
你好 @${{ github.event.issue.user.login }}, 我们需要你提供一个在线的重现实例以便于我们帮你排查问题。你可以通过点击 [此处 for vue2](https://codesandbox.io/s/2wpk21kzvr)、 [此处 for vue3](https://codesandbox.io/s/agitated-franklin-1w72v) 创建一个 codesandbox 或者提供一个最小化的 GitHub 仓库。请确保选择准确的版本。
|
||||
|
||||
- name: help wanted
|
||||
if: github.event.label.name == 'help wanted'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'create-comment'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hello @${{ github.event.issue.user.login }}. We totally like your proposal/feedback, welcome to send us a Pull Request for it. Please send your Pull Request to proper branch, fill the Pull Request Template here, provide changelog/TypeScript/documentation/test cases if needed and make sure CI passed, we will review it soon. We appreciate your effort in advance and looking forward to your contribution!
|
||||
|
||||
你好 @${{ github.event.issue.user.login }},我们完全同意你的提议/反馈,欢迎直接在此仓库创建一个 Pull Request 来解决这个问题。请将 Pull Request 发到正确的分支,务必填写 Pull Request 内的预设模板,提供改动所需相应的 changelog、TypeScript 定义、测试用例、文档等,并确保 CI 通过,我们会尽快进行 Review,提前感谢和期待您的贡献。
|
||||
|
||||
- name: Usage
|
||||
if: github.event.label.name == 'Usage'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'create-comment, close-issue'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hello @${{ github.event.issue.user.login }}, we use GitHub issues to trace bugs or discuss plans of Ant Design Vue. So, please don't ask usage questions here. You can try to open a new discussion in [antdv discussions](https://github.com/vueComponent/ant-design-vue/discussions), select `Q&A` to ask questions, also can ask questions on [Stack Overflow](http://stackoverflow.com/questions/) or [Segment Fault](https://segmentfault.com).
|
||||
|
||||
你好 @${{ github.event.issue.user.login }},Ant Design Vue Issue 板块是用于 bug 反馈与需求讨论的地方。请勿询问如何使用的问题,你可以试着在 [antdv discussions](https://github.com/vueComponent/ant-design-vue/discussions) 新开一个 discussion,选择 `Q&A` 类别进行提问,也可以在 [Stack Overflow](http://stackoverflow.com/questions/) 或者 [Segment Fault](https://segmentfault.com/) 中提问。
|
||||
|
||||
- name: 1.x
|
||||
if: github.event.label.name == '1.x'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'create-comment,close-issue'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hi @${{ github.event.issue.user.login }}. Current version (1.x) is off the maintenance period. We may not accept pull request or fix bug with it anymore. This topic will be auto closed.
|
||||
|
||||
你好 @${{ github.event.issue.user.login }},当前版本(1.x)已经过了维护期。我们不会再接受对其的相关 PR 与 issue。当前 topic 会被自动关闭。
|
||||
|
||||
- name: 2.x
|
||||
if: github.event.label.name == '2.x'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'create-comment,close-issue'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hi @${{ github.event.issue.user.login }}. Current version (2.x) is off the maintenance period. We may not accept pull request or fix bug with it anymore. This topic will be auto closed.
|
||||
|
||||
你好 @${{ github.event.issue.user.login }},当前版本(2.x)已经过了维护期。我们不会再接受对其的相关 PR 与 issue。当前 topic 会被自动关闭。
|
||||
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
name: Issue Open Check
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
issue-open-check:
|
||||
permissions:
|
||||
contents: read # for visiky/dingtalk-release-notify to get latest release
|
||||
issues: write # for actions-cool/issues-helper to update issues
|
||||
pull-requests: write # for actions-cool/issues-helper to update PRs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions-cool/check-user-permission@v1.0.0
|
||||
id: checkUser
|
||||
with:
|
||||
require: 'write'
|
||||
|
||||
- name: check invalid
|
||||
if: (contains(github.event.issue.body, 'issue-helper') == false) && (steps.checkUser.outputs.result == 'false')
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'create-comment,add-labels,close-issue'
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: 'Invalid'
|
||||
body: |
|
||||
Hello @${{ github.event.issue.user.login }}, your issue has been closed because it does not conform to our issue requirements. Please use the [Issue Helper](https://vuecomponent.github.io/issue-helper/) to create an issue, thank you!
|
||||
|
||||
你好 @${{ github.event.issue.user.login }},为了能够进行高效沟通,我们对 issue 有一定的格式要求,你的 issue 因为不符合要求而被自动关闭。你可以通过 [issue 助手](https://vuecomponent.github.io/issue-helper/) 来创建 issue 以方便我们定位错误。谢谢配合!
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
name: "Close stale issues"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
|
||||
stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
|
||||
exempt-issue-labels: 'bug,enhancement'
|
||||
days-before-stale: 60
|
||||
days-before-close: 7
|
||||
|
||||
|
|
@ -10,13 +10,13 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: cache package-lock.json
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: create package-lock.json
|
||||
run: npm i --package-lock-only --ignore-scripts
|
||||
run: npm i --package-lock-only
|
||||
|
||||
- name: hack for singe file
|
||||
run: |
|
||||
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
|
||||
- name: cache node_modules
|
||||
id: node_modules_cache_id
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
@ -43,25 +43,25 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: cache lib
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: lib
|
||||
key: lib-${{ github.sha }}
|
||||
|
||||
- name: cache es
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: es
|
||||
key: es-${{ github.sha }}
|
||||
|
|
@ -77,13 +77,13 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
@ -99,13 +99,13 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ build/Release
|
|||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
|
|
@ -59,11 +62,9 @@ jspm_packages/
|
|||
dist
|
||||
lib
|
||||
es
|
||||
/locale
|
||||
_site
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
/coverage
|
||||
|
||||
# 备份文件
|
||||
|
|
@ -71,16 +72,5 @@ pnpm-lock.yaml
|
|||
list.txt
|
||||
|
||||
site/dev.js
|
||||
|
||||
# IDE 语法提示临时文件
|
||||
v2-doc/
|
||||
vetur/
|
||||
|
||||
report.html
|
||||
|
||||
site/src/router/demoRoutes.js
|
||||
|
||||
components/version/version.ts
|
||||
components/version/version.tsx
|
||||
components/version/token.json
|
||||
components/version/token-meta.json
|
||||
~component-api.json
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
_
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no-install pretty-quick --staged
|
||||
49
.jest.js
49
.jest.js
|
|
@ -2,59 +2,42 @@ const libDir = process.env.LIB_DIR;
|
|||
|
||||
const transformIgnorePatterns = [
|
||||
'/dist/',
|
||||
// Ignore modules without es dir.
|
||||
// Update: @babel/runtime should also be transformed
|
||||
// 'node_modules/(?!.*(@babel|lodash-es))',
|
||||
'node_modules/(?!@ant-design/icons-vue|@ant-design/icons-svg|lodash-es)/',
|
||||
'node_modules/[^/]+?/(?!(es|node_modules)/)', // Ignore modules without es dir
|
||||
];
|
||||
const testPathIgnorePatterns = ['/node_modules/', 'node'];
|
||||
|
||||
function getTestRegex(libDir) {
|
||||
if (libDir === 'dist') {
|
||||
return 'demo\\.test\\.js$';
|
||||
}
|
||||
return '.*\\.test\\.(j|t)sx?$';
|
||||
}
|
||||
module.exports = {
|
||||
verbose: true,
|
||||
testURL: 'http://localhost/',
|
||||
setupFiles: ['./tests/setup.js'],
|
||||
setupFilesAfterEnv: ['./tests/setupAfterEnv.ts'],
|
||||
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json', 'vue', 'md', 'jpg'],
|
||||
moduleFileExtensions: ['js', 'jsx', 'json', 'vue', 'md', 'jpg'],
|
||||
modulePathIgnorePatterns: ['/_site/'],
|
||||
testPathIgnorePatterns: testPathIgnorePatterns,
|
||||
testPathIgnorePatterns: ['/node_modules/', 'node'],
|
||||
transform: {
|
||||
'\\.(vue|md)$': '<rootDir>/node_modules/@vue/vue3-jest',
|
||||
'\\.(js|jsx)$': '<rootDir>/node_modules/babel-jest',
|
||||
'\\.(ts|tsx)$': '<rootDir>/node_modules/ts-jest',
|
||||
'\\.svg$': '<rootDir>/node_modules/jest-transform-stub',
|
||||
'.*\\.(vue|md)$': '<rootDir>/node_modules/vue-jest',
|
||||
'^.+\\.(js|jsx)$': '<rootDir>/node_modules/babel-jest',
|
||||
'^.+\\.svg$': '<rootDir>/node_modules/jest-transform-stub',
|
||||
},
|
||||
testRegex: getTestRegex(libDir),
|
||||
testRegex: libDir === 'dist' ? 'demo\\.test\\.js$' : '.*\\.test\\.js$',
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$/': '<rootDir>/$1',
|
||||
'^ant-design-vue$': '<rootDir>/components/index',
|
||||
'^ant-design-vue/es/(.*)$': '<rootDir>/components/$1',
|
||||
'^@/(.*)$': '<rootDir>/$1',
|
||||
'ant-design-vue$': '<rootDir>/components/index.js',
|
||||
'ant-design-vue/es': '<rootDir>/components',
|
||||
'^vue$': 'vue/dist/vue.common.js',
|
||||
},
|
||||
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
|
||||
collectCoverage: process.env.COVERAGE === 'true',
|
||||
collectCoverageFrom: [
|
||||
'components/**/*.{js,jsx,vue}',
|
||||
'!components/*/style/index.{js,jsx}',
|
||||
'!components/style/*.{js,jsx}',
|
||||
'!components/*/locale/*.{js,jsx}',
|
||||
'!components/*/__tests__/**/type.{js,jsx}',
|
||||
'!components/vc-*/**/*',
|
||||
'!components/*/demo/**/*',
|
||||
'!components/_util/**/*',
|
||||
'!components/align/**/*',
|
||||
'!components/trigger/**/*',
|
||||
'!components/style.js',
|
||||
'!**/node_modules/**',
|
||||
],
|
||||
testEnvironment: 'jsdom',
|
||||
testEnvironmentOptions: {
|
||||
url: 'http://localhost',
|
||||
customExportConditions: ['node', 'node-addons'],
|
||||
},
|
||||
transformIgnorePatterns,
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
babelConfig: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ yarn-error.log
|
|||
.editorconfig
|
||||
.eslintignore
|
||||
**/*.yml
|
||||
components/style/color/*.less
|
||||
**/assets
|
||||
.gitattributes
|
||||
.stylelintrc
|
||||
|
|
@ -27,5 +28,4 @@ yarn-error.log
|
|||
.huskyrc
|
||||
.gitmodules
|
||||
*.png
|
||||
v2-doc/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"endOfLine": "lf",
|
||||
"printWidth": 100,
|
||||
"proseWrap": "never",
|
||||
"arrowParens": "avoid",
|
||||
"htmlWhitespaceSensitivity": "ignore",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ".prettierrc",
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"stylelint-config-standard",
|
||||
"stylelint-config-rational-order",
|
||||
"stylelint-config-prettier"
|
||||
],
|
||||
"customSyntax": "postcss-less",
|
||||
"plugins": ["stylelint-declaration-block-no-ignored-properties"],
|
||||
"rules": {
|
||||
"function-name-case": ["lower"],
|
||||
"function-no-unknown": [
|
||||
true,
|
||||
{
|
||||
"ignoreFunctions": [
|
||||
"fade",
|
||||
"fadeout",
|
||||
"tint",
|
||||
"darken",
|
||||
"ceil",
|
||||
"fadein",
|
||||
"floor",
|
||||
"unit",
|
||||
"shade",
|
||||
"lighten",
|
||||
"percentage",
|
||||
"-"
|
||||
]
|
||||
}
|
||||
],
|
||||
"import-notation": null,
|
||||
"no-descending-specificity": null,
|
||||
"no-invalid-position-at-import-rule": null,
|
||||
"declaration-empty-line-before": null,
|
||||
"keyframes-name-pattern": null,
|
||||
"custom-property-pattern": null,
|
||||
"number-max-precision": 8,
|
||||
"alpha-value-notation": "number",
|
||||
"color-function-notation": "legacy",
|
||||
"selector-class-pattern": null,
|
||||
"selector-id-pattern": null,
|
||||
"selector-not-notation": null
|
||||
}
|
||||
}
|
||||
3
.vcmrc
3
.vcmrc
|
|
@ -9,8 +9,7 @@
|
|||
"perf",
|
||||
"test",
|
||||
"chore",
|
||||
"revert",
|
||||
"ci"
|
||||
"revert"
|
||||
],
|
||||
"warnOnFail": false,
|
||||
"autoFix": false
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
<h2 align="center">Backers</h2>
|
||||
<p align="center">
|
||||
<a href="https://github.com/chuzhixin/vue-admin-beautiful" target="_blank"><img width="64" style="border-radius: 50%;" src="https://gitee.com/chu1204505056/image/raw/master/vue-admin-beautiful.png" title="vue-admin-beautiful"></a>
|
||||
<a href="https://github.com/limichange" target="_blank"><img width="64" style="border-radius: 50%;" src="https://avatars0.githubusercontent.com/u/1947344?s=400&v=4" title="limichange donation total 24$ by qq from 2018.9"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/backer/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/backer/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/1/avatar.svg"></a>
|
||||
|
|
|
|||
1242
CHANGELOG.en-US.md
1242
CHANGELOG.en-US.md
File diff suppressed because it is too large
Load Diff
1248
CHANGELOG.zh-CN.md
1248
CHANGELOG.zh-CN.md
File diff suppressed because it is too large
Load Diff
22
LICENSE
22
LICENSE
|
|
@ -44,25 +44,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019-PRESENT Anthony Fu<https://github.com/antfu>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
|
|||
|
|
@ -1,49 +1,56 @@
|
|||
<p align="center">
|
||||
<a href="https://www.antdv.com/">
|
||||
<img width="200" src="https://www.antdv.com/logo.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h1 align="center">
|
||||
<a href="https://www.antdv.com/" target="_blank">Ant Design Vue</a>
|
||||
</h1>
|
||||
|
||||
<div align="center">
|
||||
|
||||
基于 Ant Design 和 Vue 3 的企业级 UI 组件库。
|
||||
An enterprise-class UI components based on Ant Design and Vue.
|
||||
|
||||
 [](https://codecov.io/gh/vueComponent/ant-design-vue) [](https://www.npmjs.org/package/ant-design-vue) [](http://www.npmtrends.com/ant-design-vue) [](#backers) [](#sponsors) [](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper) [](https://github.com/actions-cool/issues-helper)
|
||||
 [](https://codecov.io/gh/vueComponent/ant-design-vue) [](https://www.npmjs.org/package/ant-design-vue) [](http://www.npmtrends.com/ant-design-vue) [](https://gitter.im/vueComponent/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) (English) [](https://gitter.im/vueComponent/ant-design-vue?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)(中文) [](#backers) [](#sponsors) [](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper)
|
||||
|
||||
</div>
|
||||
|
||||
[](https://www.antdv.com/)
|
||||
|
||||
<div align="center">
|
||||
<sup><strong>赞助商</strong></sup>
|
||||
<br>
|
||||
<a href="https://mentorbook.ai/" target="_blank">
|
||||
<img src="/site/public/mentorbook_banner_zh.svg" alt="Mentorbook.AI - 你的 AI 导师,你的学习之旅" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
[English](./README.md) | 简体中文
|
||||
|
||||
<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=ant-design-vue" target="_blank">
|
||||
<img width="120px" src="https://user-images.githubusercontent.com/1016365/34124854-48fafa06-e3e9-11e7-8c04-251055feebee.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 特性
|
||||
|
||||
- 提炼自企业级中后台产品的交互语言和视觉风格。
|
||||
- 开箱即用的高质量 Vue 组件。
|
||||
- 共享 [Ant Design of React](http://ant-design.gitee.io/docs/spec/introduce-cn) 设计工具体系。
|
||||
|
||||
## 关注我们
|
||||
|
||||
收藏加关注,第一时间获取更新动态!
|
||||
|
||||

|
||||
- 从 [2.x](https://2x.antdv.com/) 版本开始支持 Vue 3
|
||||
|
||||
## 支持环境
|
||||
|
||||
- 现代浏览器。1.x 版本支持 IE 9+(需要 [polyfills](https://www.antdv.com/docs/vue/getting-started-cn/#兼容性))
|
||||
- 现代浏览器和 IE9 及以上(需要 [polyfills](https://www.antdv.com/docs/vue/getting-started-cn/#兼容性))。
|
||||
- 支持服务端渲染。
|
||||
- [Electron](https://electronjs.org/)
|
||||
- 支持 Vue 2 和 Vue 3
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Electron |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
| IE9, IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
## 安装
|
||||
|
||||
|
|
@ -74,8 +81,6 @@ $ yarn add ant-design-vue
|
|||
| [vue-cli-plugin-ant-design](https://github.com/vueComponent/vue-cli-plugin-ant-design) | 使用 vue-cli3 快速使用 ant-design-vue 组件库 |
|
||||
| [vue-dash-event](https://github.com/vueComponent/vue-dash-event) | 在 DOM 模板中,您可以使用 ant-design-vue 组件的自定义事件(camelCase) |
|
||||
| [@formily/antdv](https://github.com/formilyjs/antdv) | 这是一个结合了 Formily 和 ant-design-vue 的组件库 |
|
||||
| [@ant-design-vue/nuxt](https://github.com/vueComponent/ant-design-vue-nuxt) | ant-design-vue 的 nuxt 模块扩展 |
|
||||
| [ant-design-x-vue](https://github.com/wzc520pyfm/ant-design-x-vue) | 基于 Ant Design X 设计规范的 Vue AI 界面解决方案 |
|
||||
|
||||
## 问答
|
||||
|
||||
|
|
@ -90,32 +95,23 @@ ant-design-vue 是 MIT 协议的开源项目。为了项目能够更好的持续
|
|||
- [Patreon](https://www.patreon.com/tangjinzhou)
|
||||
- [opencollective](https://opencollective.com/ant-design-vue)
|
||||
- [paypal](https://www.paypal.me/tangjinzhou)
|
||||
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
|
||||
|
||||
## 赞助商
|
||||
## Sponsors
|
||||
|
||||
成为赞助商,并在 Github 上的自述文件上获得您的徽标,并链接到您的网站。 [[成为赞助商](https://opencollective.com/ant-design-vue#sponsor)]
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)]
|
||||
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
|
||||
|
||||
## 支持者
|
||||
## Backers
|
||||
|
||||
每月捐款支持我们,帮助我们继续我们的活动。 [[成为支持者](https://opencollective.com/ant-design-vue#backer)]
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/ant-design-vue#backer)]
|
||||
|
||||
<a href="https://github.com/chuzhixin/vue-admin-beautiful" target="_blank"><img width="64" style="border-radius: 50%;" src="https://gitee.com/chu1204505056/image/raw/master/vue-admin-beautiful.png" title="vue-admin-beautiful"></a> <a href="https://opencollective.com/ant-design-vue/backer/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/backer/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/10/avatar.svg"></a>
|
||||
|
||||
## Patreon
|
||||
|
||||
每月捐款支持我们,帮助我们继续我们的活动。 [[成为支持者](https://www.patreon.com/tangjinzhou)]
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://www.patreon.com/tangjinzhou)]
|
||||
|
||||
<a href="https://www.mokeyjay.com" target="_blank"><img width="64" style="border-radius: 50%;" src="https://www.mokeyjay.com/headimg.png" title="donation by Patreon"></a>
|
||||
|
||||
## [更多赞助者 (通过 Patreon、支付宝、微信、paypal 等等)](https://github.com/vueComponent/ant-design-vue/blob/master/BACKERS.md)
|
||||
|
||||
## 贡献者
|
||||
|
||||
感谢所有为 ant-design-vue 做出贡献的人!
|
||||
|
||||
<a href="https://github.com/vueComponent/ant-design-vue/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=vueComponent/ant-design-vue&max=100&columns=15" />
|
||||
</a>
|
||||
|
|
|
|||
68
README.md
68
README.md
|
|
@ -12,48 +12,49 @@
|
|||
|
||||
An enterprise-class UI components based on Ant Design and Vue.
|
||||
|
||||
 [](https://codecov.io/gh/vueComponent/ant-design-vue) [](https://www.npmjs.org/package/ant-design-vue) [](http://www.npmtrends.com/ant-design-vue) [](#backers) [](#sponsors) [](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper) [](https://github.com/actions-cool/issues-helper)
|
||||
 [](https://codecov.io/gh/vueComponent/ant-design-vue) [](https://www.npmjs.org/package/ant-design-vue) [](http://www.npmtrends.com/ant-design-vue) [](https://gitter.im/vueComponent/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) (English) [](https://gitter.im/vueComponent/ant-design-vue?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)(中文) [](#backers) [](#sponsors) [](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper)
|
||||
|
||||
</div>
|
||||
|
||||
[](https://www.antdv.com/)
|
||||
|
||||
<div align="center">
|
||||
<sup><strong>Sponsored by</strong></sup>
|
||||
<br>
|
||||
<a href="https://mentorbook.ai/" target="_blank">
|
||||
<img src="/site/public/mentorbook_banner_en.svg" alt="Mentorbook.AI - Your AI Mentor, Your Learning Journey" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
English | [简体中文](./README-zh_CN.md)
|
||||
|
||||
<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=ant-design-vue" target="_blank">
|
||||
<img width="120px" src="https://user-images.githubusercontent.com/1016365/34124854-48fafa06-e3e9-11e7-8c04-251055feebee.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Features
|
||||
|
||||
- An enterprise-class UI design system for desktop applications.
|
||||
- A set of high-quality Vue components out of the box.
|
||||
- Shared [Ant Design of React](https://ant.design/docs/spec/introduce) design resources.
|
||||
|
||||
## Getting started & staying tuned with us.
|
||||
|
||||
Star us, and you will receive all releases notifications from GitHub without any delay!
|
||||
|
||||

|
||||
- Support Vue 3 from [2.x](https://2x.antdv.com/)
|
||||
|
||||
## Environment Support
|
||||
|
||||
- Modern browsers. v1.x support Internet Explorer 9+ (with [polyfills](https://www.antdv.com/docs/vue/getting-started/#compatibility))
|
||||
- Modern browsers and Internet Explorer 9+ (with [polyfills](https://www.antdv.com/docs/vue/getting-started/#Compatibility))
|
||||
- Server-side Rendering
|
||||
- Support Vue 2 & Vue 3
|
||||
- [Electron](https://electronjs.org/)
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Electron |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
| IE9, IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
## Using npm or yarn
|
||||
|
||||
**We recommend using npm or yarn to install**, it not only makes development easier, but also allow you to take advantage of the rich ecosystem of Javascript packages and tooling.
|
||||
**We recommend using npm or yarn to install**,it not only makes development easier,but also allow you to take advantage of the rich ecosystem of Javascript packages and tooling.
|
||||
|
||||
```bash
|
||||
$ npm install ant-design-vue --save
|
||||
|
|
@ -63,7 +64,7 @@ $ npm install ant-design-vue --save
|
|||
$ yarn add ant-design-vue
|
||||
```
|
||||
|
||||
If you are in a bad network environment, you can try other registries and tools like [cnpm](https://github.com/cnpm/cnpm).
|
||||
If you are in a bad network environment,you can try other registries and tools like [cnpm](https://github.com/cnpm/cnpm).
|
||||
|
||||
## Links
|
||||
|
||||
|
|
@ -80,8 +81,6 @@ If you are in a bad network environment, you can try other registries and tools
|
|||
| [vue-cli-plugin-ant-design](https://github.com/vueComponent/vue-cli-plugin-ant-design) | Vue-cli 3 plugin to add ant-design-vue |
|
||||
| [vue-dash-event](https://github.com/vueComponent/vue-dash-event) | The library function, implemented in the DOM template, can use the custom event of the ant-design-vue component (camelCase) |
|
||||
| [@formily/antdv](https://github.com/formilyjs/antdv) | The Library with Formily and ant-design-vue |
|
||||
| [@ant-design-vue/nuxt](https://github.com/vueComponent/ant-design-vue-nuxt) | A nuxt module for ant-design-vue |
|
||||
| [ant-design-x-vue](https://github.com/wzc520pyfm/ant-design-x-vue) | A Vue AI interface solutions base on the Ant Design X design specification |
|
||||
|
||||
## Donation
|
||||
|
||||
|
|
@ -90,24 +89,25 @@ ant-design-vue is an MIT-licensed open source project. In order to achieve bette
|
|||
- [Patreon](https://www.patreon.com/tangjinzhou)
|
||||
- [opencollective](https://opencollective.com/ant-design-vue)
|
||||
- [paypal](https://www.paypal.me/tangjinzhou)
|
||||
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
|
||||
|
||||
## 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/ant-design-vue#sponsor)]
|
||||
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
|
||||
|
||||
## Backers
|
||||
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/ant-design-vue#backer)]
|
||||
|
||||
<a href="https://opencollective.com/ant-design-vue/backer/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/10/avatar.svg"></a><a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a>
|
||||
|
||||
## Patreon
|
||||
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://www.patreon.com/tangjinzhou)]
|
||||
|
||||
<a href="https://www.mokeyjay.com" target="_blank"><img width="64" style="border-radius: 50%;" src="https://www.mokeyjay.com/headimg.png" title="donation by Patreon"></a>
|
||||
|
||||
## [More Sponsor (From Patreon、alipay、wechat、paypal...)](https://github.com/vueComponent/ant-design-vue/blob/master/BACKERS.md)
|
||||
|
||||
## Contributors
|
||||
|
||||
Thank you to all the people who already contributed to ant-design-vue!
|
||||
|
||||
<a href="https://github.com/vueComponent/ant-design-vue/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=vueComponent/ant-design-vue&max=100&columns=15" />
|
||||
</a>
|
||||
|
||||
[](https://issuehunt.io/repos/104172832)
|
||||
|
||||
This project is tested with BrowserStack.
|
||||
|
|
|
|||
17
SECURITY.md
17
SECURITY.md
|
|
@ -1,17 +0,0 @@
|
|||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Use this section to tell people about which versions of your project are currently being supported with security updates.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 1.x | :white_check_mark: |
|
||||
| 2.x | :x: |
|
||||
| 3.x | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Use this section to tell people how to report a vulnerability.
|
||||
|
||||
Tell them where to go, how often they can expect to get an update on a reported vulnerability, what to expect if the vulnerability is accepted or declined, etc.
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
// Read all the api from current documents
|
||||
|
||||
const glob = require('glob');
|
||||
const fs = require('fs');
|
||||
|
||||
const COMPONENT_NAME = /components\/([^/]*)/;
|
||||
const PROP_NAME = /^\s*\|\s*([^\s|]*)/;
|
||||
|
||||
const components = {};
|
||||
|
||||
function mappingPropLine(component, line) {
|
||||
const propMatch = line.match(PROP_NAME);
|
||||
if (!propMatch) return;
|
||||
|
||||
const propName = propMatch[1];
|
||||
if (!/^[a-z]/.test(propName)) return;
|
||||
|
||||
components[component] = Array.from(new Set([...(components[component] || []), propName]));
|
||||
}
|
||||
|
||||
function apiReport(entities) {
|
||||
const apis = {};
|
||||
Object.keys(entities).forEach(component => {
|
||||
const apiList = entities[component];
|
||||
apiList.forEach(api => {
|
||||
if (typeof apis[api] === 'function') {
|
||||
apis[api] = [];
|
||||
}
|
||||
apis[api] = [...(apis[api] || []), component];
|
||||
});
|
||||
});
|
||||
|
||||
return apis;
|
||||
}
|
||||
|
||||
function printReport(apis) {
|
||||
const apiList = Object.keys(apis).map(api => ({
|
||||
name: api,
|
||||
componentList: apis[api],
|
||||
}));
|
||||
apiList.sort((a, b) => b.componentList.length - a.componentList.length);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('| name | components | comments |');
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('| ---- | ---------- | -------- |');
|
||||
apiList.forEach(({ name, componentList }) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('|', name, '|', componentList.join(', '), '| |');
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = () => {
|
||||
glob('components/*/*.md', (error, files) => {
|
||||
files.forEach(filePath => {
|
||||
// Read md file to parse content
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const component = filePath.match(COMPONENT_NAME)[1];
|
||||
|
||||
// Parse lines to get API
|
||||
const lines = content.split(/[\r\n]+/);
|
||||
lines.forEach(line => {
|
||||
mappingPropLine(component, line);
|
||||
});
|
||||
});
|
||||
|
||||
printReport(apiReport(components));
|
||||
});
|
||||
};
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
'use strict';
|
||||
|
||||
require('colorful').colorful();
|
||||
require('colorful').isatty = true;
|
||||
|
||||
const program = require('commander');
|
||||
const packageInfo = require('../../package.json');
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
#!/usr/bin/env node
|
||||
/* eslint-disable no-console */
|
||||
|
||||
'use strict';
|
||||
|
||||
require('colorful').colorful();
|
||||
require('colorful').isatty = true;
|
||||
const gulp = require('gulp');
|
||||
const program = require('commander');
|
||||
|
||||
program.option('-c --npm-tag <type>', 'add --npm-tag=xxx');
|
||||
|
||||
program.on('--help', () => {
|
||||
console.log(' Usage:'.to.bold.blue.color);
|
||||
console.log();
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
fork github.com/youzan/vant packages/generator-types
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
const path = require('path');
|
||||
const pkg = require('../../package.json');
|
||||
const { parseAndWrite } = require('./lib/index.js');
|
||||
const rootPath = path.resolve(__dirname, '../../');
|
||||
|
||||
parseAndWrite({
|
||||
version: pkg.version,
|
||||
name: 'ant-design-vue',
|
||||
path: path.resolve(rootPath, './components'),
|
||||
typingsPath: path.resolve(rootPath, './typings/global.d.ts'),
|
||||
// default match lang
|
||||
test: /en-US\.md/,
|
||||
outputDir: path.resolve(rootPath, './vetur'),
|
||||
tagPrefix: 'a-',
|
||||
})
|
||||
.then(result => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`generator types success: ${result} tags generated`);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('generator types error', error);
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
import type { Articals } from './parser';
|
||||
import { formatType, removeVersion, toKebabCase } from './utils';
|
||||
import type { VueTag } from './type';
|
||||
|
||||
function getComponentName(name: string, tagPrefix: string) {
|
||||
if (name) {
|
||||
return tagPrefix + toKebabCase(name.split(' ')[0]);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function parserProps(tag: VueTag, line: any) {
|
||||
const [name, desc, type, defaultVal] = line;
|
||||
if (
|
||||
type &&
|
||||
(type.includes('v-slot') ||
|
||||
type.includes('slot') ||
|
||||
type.includes('slots') ||
|
||||
type.includes('slot-scoped'))
|
||||
) {
|
||||
tag.slots!.push({
|
||||
name: removeVersion(name),
|
||||
description: desc,
|
||||
});
|
||||
}
|
||||
tag.attributes!.push({
|
||||
name: removeVersion(name),
|
||||
default: defaultVal,
|
||||
description: desc,
|
||||
value: {
|
||||
type: formatType(type || ''),
|
||||
kind: 'expression',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function formatter(
|
||||
articals: Articals,
|
||||
componentName: string,
|
||||
kebabComponentName: string,
|
||||
tagPrefix = '',
|
||||
) {
|
||||
if (!articals.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tags: VueTag[] = [];
|
||||
const tag: VueTag = {
|
||||
name: kebabComponentName,
|
||||
slots: [],
|
||||
events: [],
|
||||
attributes: [],
|
||||
};
|
||||
tags.push(tag);
|
||||
|
||||
const tables = articals.filter(artical => artical.type === 'table');
|
||||
|
||||
tables.forEach(item => {
|
||||
const { table } = item;
|
||||
const prevIndex = articals.indexOf(item) - 1;
|
||||
const prevArtical = articals[prevIndex];
|
||||
|
||||
if (!prevArtical || !prevArtical.content || !table || !table.body) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tableTitle = prevArtical.content;
|
||||
|
||||
if (tableTitle.includes('API')) {
|
||||
table.body.forEach(line => {
|
||||
parserProps(tag, line);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (tableTitle.includes('events') && !tableTitle.includes(componentName)) {
|
||||
table.body.forEach(line => {
|
||||
const [name, desc] = line;
|
||||
tag.events!.push({
|
||||
name: removeVersion(name),
|
||||
description: desc,
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 额外的子组件
|
||||
if (
|
||||
tableTitle.includes(componentName) &&
|
||||
!tableTitle.includes('events') &&
|
||||
!tableTitle.includes('()')
|
||||
) {
|
||||
const childTag: VueTag = {
|
||||
name: getComponentName(tableTitle.replace(/\.|\//g, ''), tagPrefix),
|
||||
slots: [],
|
||||
events: [],
|
||||
attributes: [],
|
||||
};
|
||||
table.body.forEach(line => {
|
||||
parserProps(childTag, line);
|
||||
});
|
||||
tags.push(childTag);
|
||||
return;
|
||||
}
|
||||
|
||||
// 额外的子组件事件
|
||||
if (tableTitle.includes(componentName) && tableTitle.includes('events')) {
|
||||
const childTagName = getComponentName(
|
||||
tableTitle.replace('.', '').replace('events', ''),
|
||||
tagPrefix,
|
||||
);
|
||||
const childTag: VueTag | undefined = tags.find(item => item.name === childTagName.trim());
|
||||
if (!childTag) {
|
||||
return;
|
||||
}
|
||||
table.body.forEach(line => {
|
||||
const [name, desc] = line;
|
||||
childTag.events!.push({
|
||||
name: removeVersion(name),
|
||||
description: desc,
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
import glob from 'fast-glob';
|
||||
import { dirname, join } from 'path';
|
||||
import { mdParser } from './parser';
|
||||
import { formatter } from './formatter';
|
||||
import { genWebTypes } from './web-types';
|
||||
import { outputFileSync, readFileSync } from 'fs-extra';
|
||||
import type { Options, VueTag } from './type';
|
||||
import { getComponentName, normalizePath, toKebabCase } from './utils';
|
||||
import { flatMap } from 'lodash';
|
||||
|
||||
async function readMarkdown(options: Options): Promise<Map<String, VueTag>> {
|
||||
const mdPaths = await glob(normalizePath(`${options.path}/**/*.md`));
|
||||
const data = mdPaths
|
||||
.filter(md => options.test.test(md))
|
||||
.map(path => {
|
||||
const docPath = dirname(path);
|
||||
const kebabComponentName =
|
||||
options.tagPrefix + docPath.substring(docPath.lastIndexOf('/') + 1) || '';
|
||||
const componentName = getComponentName(docPath.substring(docPath.lastIndexOf('/') + 1) || '');
|
||||
const fileContent = readFileSync(path, 'utf-8');
|
||||
return formatter(mdParser(fileContent), componentName, kebabComponentName, options.tagPrefix);
|
||||
})
|
||||
.filter(item => item) as VueTag[][];
|
||||
const tags = new Map<String, VueTag>();
|
||||
flatMap(data, item => item).forEach(mergedTag => mergeTag(tags, mergedTag));
|
||||
return tags;
|
||||
}
|
||||
|
||||
function readTypings(options: Options): Map<String, VueTag> {
|
||||
const tags = new Map<String, VueTag>();
|
||||
const fileContent = readFileSync(options.typingsPath, 'utf-8');
|
||||
fileContent
|
||||
.split('\n')
|
||||
.filter(line => line && line.includes('typeof'))
|
||||
.map(line => {
|
||||
const l = line.trim();
|
||||
return toKebabCase(l.substring(0, l.indexOf(':')));
|
||||
})
|
||||
.forEach(tagName =>
|
||||
tags.set(tagName, {
|
||||
name: tagName,
|
||||
slots: [],
|
||||
events: [],
|
||||
attributes: [],
|
||||
}),
|
||||
);
|
||||
return tags;
|
||||
}
|
||||
|
||||
function mergeTag(tags: Map<String, VueTag>, mergedTag: VueTag) {
|
||||
const tagName = mergedTag.name;
|
||||
const vueTag = tags.get(tagName);
|
||||
if (vueTag) {
|
||||
vueTag.slots = [...vueTag.slots, ...mergedTag.slots];
|
||||
vueTag.events = [...vueTag.events, ...mergedTag.events];
|
||||
vueTag.attributes = [...vueTag.attributes, ...mergedTag.attributes];
|
||||
} else {
|
||||
tags.set(tagName, mergedTag);
|
||||
}
|
||||
}
|
||||
|
||||
function mergeTags(mergedTagsArr: Map<String, VueTag>[]): VueTag[] {
|
||||
if (mergedTagsArr.length === 1) return [...mergedTagsArr[0].values()];
|
||||
const tags = new Map<String, VueTag>();
|
||||
if (mergedTagsArr.length === 0) return [];
|
||||
mergedTagsArr.forEach(mergedTags => {
|
||||
mergedTags.forEach(mergedTag => mergeTag(tags, mergedTag));
|
||||
});
|
||||
return [...tags.values()];
|
||||
}
|
||||
|
||||
export async function parseAndWrite(options: Options): Promise<Number> {
|
||||
if (!options.outputDir) {
|
||||
throw new Error('outputDir can not be empty.');
|
||||
}
|
||||
const tagsFromMarkdown = await readMarkdown(options);
|
||||
const tagsFromTypings = await readTypings(options);
|
||||
const tags = mergeTags([tagsFromMarkdown, tagsFromTypings]);
|
||||
const webTypes = genWebTypes(tags, options);
|
||||
outputFileSync(join(options.outputDir, 'web-types.json'), JSON.stringify(webTypes, null, 2));
|
||||
return tags.length;
|
||||
}
|
||||
|
||||
export default { parseAndWrite };
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/* eslint-disable no-cond-assign */
|
||||
const TITLE_REG = /^(#+)\s+([^\n]*)/;
|
||||
const TABLE_REG = /^\|.+\r?\n\|\s*-+/;
|
||||
const TD_REG = /\s*`[^`]+`\s*|([^|`]+)/g;
|
||||
const TABLE_SPLIT_LINE_REG = /^\|\s*-/;
|
||||
|
||||
type TableContent = {
|
||||
head: string[];
|
||||
body: string[][];
|
||||
};
|
||||
|
||||
export type Artical = {
|
||||
type: string;
|
||||
content?: string;
|
||||
table?: TableContent;
|
||||
level?: number;
|
||||
};
|
||||
|
||||
export type Articals = Artical[];
|
||||
|
||||
function readLine(input: string) {
|
||||
const end = input.indexOf('\n');
|
||||
|
||||
return input.substring(0, end !== -1 ? end : input.length);
|
||||
}
|
||||
|
||||
function splitTableLine(line: string) {
|
||||
line = line.replace(/\\\|/g, 'JOIN');
|
||||
|
||||
const items = line.split('|').map(item => item.trim().replace(/JOIN/g, '|'));
|
||||
|
||||
// remove pipe character on both sides
|
||||
items.pop();
|
||||
items.shift();
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
function tableParse(input: string) {
|
||||
let start = 0;
|
||||
let isHead = true;
|
||||
|
||||
const end = input.length;
|
||||
const table: TableContent = {
|
||||
head: [],
|
||||
body: [],
|
||||
};
|
||||
|
||||
while (start < end) {
|
||||
const target = input.substring(start);
|
||||
const line = readLine(target);
|
||||
|
||||
if (!/^\|/.test(target)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (TABLE_SPLIT_LINE_REG.test(target)) {
|
||||
isHead = false;
|
||||
} else if (!isHead && line.includes('|')) {
|
||||
const matched = line.trim().match(TD_REG);
|
||||
|
||||
if (matched) {
|
||||
table.body.push(splitTableLine(line));
|
||||
}
|
||||
}
|
||||
|
||||
start += line.length + 1;
|
||||
}
|
||||
|
||||
return {
|
||||
table,
|
||||
usedLength: start,
|
||||
};
|
||||
}
|
||||
|
||||
export function mdParser(input: string): Articals {
|
||||
const artical = [];
|
||||
let start = 0;
|
||||
const end = input.length;
|
||||
|
||||
while (start < end) {
|
||||
const target = input.substring(start);
|
||||
|
||||
let match;
|
||||
if ((match = TITLE_REG.exec(target))) {
|
||||
artical.push({
|
||||
type: 'title',
|
||||
content: match[2].replace('\r', ''),
|
||||
level: match[1].length,
|
||||
});
|
||||
|
||||
start += match.index + match[0].length;
|
||||
} else if ((match = TABLE_REG.exec(target))) {
|
||||
const { table, usedLength } = tableParse(target.substring(match.index));
|
||||
artical.push({
|
||||
type: 'table',
|
||||
table,
|
||||
});
|
||||
|
||||
start += match.index + usedLength;
|
||||
} else {
|
||||
start += readLine(target).length + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return artical;
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
import type { PathLike } from 'fs';
|
||||
|
||||
export type VueSlot = {
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
export type VueEventArgument = {
|
||||
name: string;
|
||||
type: string;
|
||||
};
|
||||
|
||||
export type VueEvent = {
|
||||
name: string;
|
||||
description?: string;
|
||||
arguments?: VueEventArgument[];
|
||||
};
|
||||
|
||||
export type VueAttribute = {
|
||||
name: string;
|
||||
default: string;
|
||||
description: string;
|
||||
value: {
|
||||
kind: 'expression';
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type VueTag = {
|
||||
name: string;
|
||||
slots: VueSlot[];
|
||||
events: VueEvent[];
|
||||
attributes: VueAttribute[];
|
||||
description?: string;
|
||||
};
|
||||
|
||||
export type Options = {
|
||||
name: string;
|
||||
path: PathLike;
|
||||
typingsPath: PathLike;
|
||||
test: RegExp;
|
||||
version: string;
|
||||
outputDir?: string;
|
||||
tagPrefix?: string;
|
||||
};
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
// myName -> my-name
|
||||
export function toKebabCase(camel: string): string {
|
||||
return camel.replace(/((?<=[a-z\d])[A-Z]|(?<=[A-Z\d])[A-Z](?=[a-z]))/g, '-$1').toLowerCase();
|
||||
}
|
||||
|
||||
// name `v2.0.0` -> name
|
||||
export function removeVersion(str: string) {
|
||||
return str.replace(/`(\w|\.)+`/g, '').trim();
|
||||
}
|
||||
|
||||
// *boolean* -> boolean
|
||||
// _boolean_ -> boolean
|
||||
export function formatType(type: string) {
|
||||
return type
|
||||
.replace(/(^(\*|_))|((\*|_)$)/g, '')
|
||||
.replace('\\', '')
|
||||
.replace('\\', '');
|
||||
}
|
||||
|
||||
export function getComponentName(name: string) {
|
||||
const title = name
|
||||
.split('-')
|
||||
.map(it => it.substring(0, 1) + it.substring(1))
|
||||
.join('');
|
||||
return title.substring(0, 1).toUpperCase() + title.substring(1);
|
||||
}
|
||||
|
||||
export function normalizePath(path: string): string {
|
||||
return path.replace(/\\/g, '/');
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
import type { VueTag, Options } from './type';
|
||||
|
||||
// create web-types.json to provide autocomplete in JetBrains IDEs
|
||||
export function genWebTypes(tags: VueTag[], options: Options) {
|
||||
return {
|
||||
$schema: 'https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json',
|
||||
framework: 'vue',
|
||||
name: options.name,
|
||||
version: options.version,
|
||||
contributions: {
|
||||
html: {
|
||||
tags,
|
||||
attributes: [],
|
||||
'types-syntax': 'typescript',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"outDir": "./lib",
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"declaration": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext"]
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
|
|
@ -1,56 +1,44 @@
|
|||
const { resolve, isThereHaveBrowserslistConfig } = require('./utils/projectHelper');
|
||||
'use strict';
|
||||
|
||||
module.exports = function (modules) {
|
||||
module.exports = function(modules) {
|
||||
const plugins = [
|
||||
[
|
||||
resolve('@babel/plugin-transform-typescript'),
|
||||
{
|
||||
isTSX: true,
|
||||
},
|
||||
],
|
||||
[resolve('@vue/babel-plugin-jsx'), { mergeProps: false, enableObjectSlots: false }],
|
||||
resolve('@babel/plugin-proposal-optional-chaining'),
|
||||
resolve('@babel/plugin-transform-object-assign'),
|
||||
resolve('@babel/plugin-proposal-object-rest-spread'),
|
||||
resolve('@babel/plugin-proposal-export-default-from'),
|
||||
resolve('@babel/plugin-proposal-export-namespace-from'),
|
||||
resolve('@babel/plugin-proposal-class-properties'),
|
||||
resolve('@babel/plugin-syntax-dynamic-import'),
|
||||
[
|
||||
resolve('@babel/plugin-transform-runtime'),
|
||||
{
|
||||
useESModules: modules === false,
|
||||
version:
|
||||
require(`${process.cwd()}/package.json`).dependencies['@babel/runtime'] || '^7.10.4',
|
||||
},
|
||||
],
|
||||
// resolve('babel-plugin-inline-import-data-uri'),
|
||||
// resolve('@babel/plugin-transform-member-expression-literals'),
|
||||
// resolve('@babel/plugin-transform-property-literals'),
|
||||
// resolve('@babel/plugin-proposal-export-default-from'),
|
||||
// resolve('@babel/plugin-transform-object-assign'),
|
||||
// resolve('@babel/plugin-transform-template-literals'),
|
||||
// resolve('@babel/plugin-proposal-object-rest-spread'),
|
||||
// resolve('@babel/plugin-proposal-class-properties'),
|
||||
require.resolve('babel-plugin-transform-vue-jsx'),
|
||||
require.resolve('babel-plugin-inline-import-data-uri'),
|
||||
require.resolve('babel-plugin-transform-es3-member-expression-literals'),
|
||||
require.resolve('babel-plugin-transform-es3-property-literals'),
|
||||
require.resolve('babel-plugin-transform-object-assign'),
|
||||
require.resolve('babel-plugin-transform-object-rest-spread'),
|
||||
require.resolve('babel-plugin-transform-class-properties'),
|
||||
];
|
||||
plugins.push([
|
||||
require.resolve('babel-plugin-transform-runtime'),
|
||||
{
|
||||
polyfill: false,
|
||||
},
|
||||
]);
|
||||
return {
|
||||
presets: [
|
||||
[
|
||||
resolve('@babel/preset-env'),
|
||||
require.resolve('babel-preset-env'),
|
||||
{
|
||||
modules,
|
||||
targets: isThereHaveBrowserslistConfig()
|
||||
? undefined
|
||||
: {
|
||||
browsers: ['last 2 versions', 'Firefox ESR', '> 1%', 'ie >= 11'],
|
||||
},
|
||||
targets: {
|
||||
browsers: [
|
||||
'last 2 versions',
|
||||
'Firefox ESR',
|
||||
'> 1%',
|
||||
'ie >= 9',
|
||||
'iOS >= 8',
|
||||
'Android >= 4',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins,
|
||||
env: {
|
||||
test: {
|
||||
plugins: [resolve('babel-plugin-istanbul')],
|
||||
plugins: [require.resolve('babel-plugin-istanbul')],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const runCmd = require('./runCmd');
|
||||
|
||||
module.exports = function (done) {
|
||||
if (process.env.NPM_CLI) {
|
||||
done(process.env.NPM_CLI);
|
||||
return;
|
||||
}
|
||||
runCmd('which', ['tnpm'], code => {
|
||||
let npm = 'npm';
|
||||
if (!code) {
|
||||
npm = 'tnpm';
|
||||
}
|
||||
done(npm);
|
||||
});
|
||||
};
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const { getProjectPath } = require('./utils/projectHelper');
|
||||
|
||||
module.exports = function () {
|
||||
let my = {};
|
||||
if (fs.existsSync(getProjectPath('tsconfig.json'))) {
|
||||
my = require(getProjectPath('tsconfig.json'));
|
||||
}
|
||||
return Object.assign(
|
||||
{
|
||||
noUnusedParameters: true,
|
||||
noUnusedLocals: true,
|
||||
strictNullChecks: true,
|
||||
target: 'es6',
|
||||
jsx: 'preserve',
|
||||
moduleResolution: 'node',
|
||||
declaration: true,
|
||||
allowSyntheticDefaultImports: true,
|
||||
},
|
||||
my.compilerOptions,
|
||||
);
|
||||
};
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
const { getProjectPath, resolve } = require('./utils/projectHelper');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const WebpackBar = require('webpackbar');
|
||||
const { merge } = require('webpack-merge');
|
||||
const webpackMerge = require('webpack-merge');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
|
||||
const postcssConfig = require('./postcssConfig');
|
||||
const CleanUpStatsPlugin = require('./utils/CleanUpStatsPlugin');
|
||||
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
|
||||
const distFileBaseName = 'antd';
|
||||
|
||||
|
|
@ -22,63 +21,55 @@ const imageOptions = {
|
|||
limit: 10000,
|
||||
};
|
||||
|
||||
function getWebpackConfig(modules, esm = false) {
|
||||
const pkg = require(getProjectPath('package.json'));
|
||||
function getWebpackConfig(modules) {
|
||||
const pkg = require(path.join(process.cwd(), 'package.json'));
|
||||
const babelConfig = require('./getBabelCommonConfig')(modules || false);
|
||||
|
||||
const pluginImportOptions = {
|
||||
style: true,
|
||||
libraryName: distFileBaseName,
|
||||
libraryDirectory: 'components',
|
||||
};
|
||||
babelConfig.plugins.push([resolve('babel-plugin-import'), pluginImportOptions]);
|
||||
const pluginImportOptions = [
|
||||
{
|
||||
style: true,
|
||||
libraryName: distFileBaseName,
|
||||
libraryDirectory: 'components',
|
||||
},
|
||||
];
|
||||
babelConfig.plugins.push([require.resolve('babel-plugin-import'), pluginImportOptions]);
|
||||
|
||||
if (modules === false) {
|
||||
babelConfig.plugins.push(require.resolve('./replaceLib'));
|
||||
}
|
||||
|
||||
/** @type {import('webpack').Configuration} */
|
||||
const config = {
|
||||
devtool: 'source-map',
|
||||
|
||||
output: {
|
||||
path: getProjectPath('./dist/'),
|
||||
path: path.join(process.cwd(), './dist/'),
|
||||
filename: '[name].js',
|
||||
},
|
||||
|
||||
resolve: {
|
||||
modules: ['node_modules', path.join(__dirname, '../node_modules')],
|
||||
extensions: [
|
||||
'.web.tsx',
|
||||
'.web.ts',
|
||||
'.web.jsx',
|
||||
'.web.js',
|
||||
'.ts',
|
||||
'.tsx',
|
||||
'.js',
|
||||
'.jsx',
|
||||
'.vue',
|
||||
'.md',
|
||||
'.json',
|
||||
],
|
||||
extensions: ['.js', '.jsx', '.vue', '.md', '.json'],
|
||||
alias: {
|
||||
vue$: 'vue/dist/vue.esm.js',
|
||||
'@': process.cwd(),
|
||||
},
|
||||
fallback: [
|
||||
'child_process',
|
||||
'cluster',
|
||||
'dgram',
|
||||
'dns',
|
||||
'fs',
|
||||
'module',
|
||||
'net',
|
||||
'readline',
|
||||
'repl',
|
||||
'tls',
|
||||
].reduce((acc, name) => Object.assign({}, acc, { [name]: 'empty' }), {}),
|
||||
},
|
||||
|
||||
node: [
|
||||
'child_process',
|
||||
'cluster',
|
||||
'dgram',
|
||||
'dns',
|
||||
'fs',
|
||||
'module',
|
||||
'net',
|
||||
'readline',
|
||||
'repl',
|
||||
'tls',
|
||||
].reduce((acc, name) => Object.assign({}, acc, { [name]: 'empty' }), {}),
|
||||
|
||||
module: {
|
||||
noParse: [/moment.js/],
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
|
|
@ -92,14 +83,8 @@ function getWebpackConfig(modules, esm = false) {
|
|||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: [resolve('@babel/preset-env')],
|
||||
plugins: [
|
||||
[
|
||||
resolve('@vue/babel-plugin-jsx'),
|
||||
{ mergeProps: false, enableObjectSlots: false },
|
||||
],
|
||||
resolve('@babel/plugin-proposal-object-rest-spread'),
|
||||
],
|
||||
presets: ['env'],
|
||||
plugins: ['transform-vue-jsx', 'transform-object-rest-spread'],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
@ -114,21 +99,6 @@ function getWebpackConfig(modules, esm = false) {
|
|||
exclude: /node_modules/,
|
||||
options: babelConfig,
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: babelConfig,
|
||||
},
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
|
|
@ -141,13 +111,33 @@ function getWebpackConfig(modules, esm = false) {
|
|||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: Object.assign({}, postcssConfig, { sourceMap: true }),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: ['autoprefixer'],
|
||||
},
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: Object.assign({}, postcssConfig, { sourceMap: true }),
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
lessOptions: {
|
||||
sourceMap: true,
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Images
|
||||
|
|
@ -165,12 +155,11 @@ function getWebpackConfig(modules, esm = false) {
|
|||
},
|
||||
|
||||
plugins: [
|
||||
// new BundleAnalyzerPlugin(),
|
||||
new CaseSensitivePathsPlugin(),
|
||||
new webpack.BannerPlugin(`
|
||||
${pkg.name} v${pkg.version}
|
||||
|
||||
Copyright 2017-present, Ant Design Vue.
|
||||
Copyright 2017-present, ant-design-vue.
|
||||
All rights reserved.
|
||||
`),
|
||||
new WebpackBar({
|
||||
|
|
@ -179,57 +168,32 @@ All rights reserved.
|
|||
}),
|
||||
new CleanUpStatsPlugin(),
|
||||
],
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
};
|
||||
|
||||
if (process.env.RUN_ENV === 'PRODUCTION') {
|
||||
let entry = ['./index'];
|
||||
config.externals = [
|
||||
{
|
||||
vue: {
|
||||
root: 'Vue',
|
||||
commonjs2: 'vue',
|
||||
commonjs: 'vue',
|
||||
amd: 'vue',
|
||||
module: 'vue',
|
||||
},
|
||||
const entry = ['./index'];
|
||||
config.externals = {
|
||||
vue: {
|
||||
root: 'Vue',
|
||||
commonjs2: 'vue',
|
||||
commonjs: 'vue',
|
||||
amd: 'vue',
|
||||
},
|
||||
];
|
||||
if (esm) {
|
||||
entry = ['./index.esm'];
|
||||
config.experiments = {
|
||||
...config.experiments,
|
||||
outputModule: true,
|
||||
};
|
||||
config.output.chunkFormat = 'module';
|
||||
config.output.library = {
|
||||
type: 'module',
|
||||
};
|
||||
config.target = 'es2019';
|
||||
} else {
|
||||
config.output.libraryTarget = 'umd';
|
||||
config.output.library = distFileBaseName;
|
||||
config.output.globalObject = 'this';
|
||||
}
|
||||
|
||||
const entryName = esm ? `${distFileBaseName}.esm` : distFileBaseName;
|
||||
|
||||
};
|
||||
config.output.library = distFileBaseName;
|
||||
config.output.libraryTarget = 'umd';
|
||||
config.optimization = {
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
parallel: true,
|
||||
terserOptions: {
|
||||
warnings: false,
|
||||
},
|
||||
sourceMap: true,
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
// Development
|
||||
const uncompressedConfig = merge({}, config, {
|
||||
const uncompressedConfig = webpackMerge({}, config, {
|
||||
entry: {
|
||||
[entryName]: entry,
|
||||
[distFileBaseName]: entry,
|
||||
},
|
||||
mode: 'development',
|
||||
plugins: [
|
||||
|
|
@ -240,12 +204,13 @@ All rights reserved.
|
|||
});
|
||||
|
||||
// Production
|
||||
const prodConfig = merge({}, config, {
|
||||
const prodConfig = webpackMerge({}, config, {
|
||||
entry: {
|
||||
[`${entryName}.min`]: entry,
|
||||
[`${distFileBaseName}.min`]: entry,
|
||||
},
|
||||
mode: 'production',
|
||||
plugins: [
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
new webpack.LoaderOptionsPlugin({
|
||||
minimize: true,
|
||||
}),
|
||||
|
|
@ -254,15 +219,14 @@ All rights reserved.
|
|||
}),
|
||||
],
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [new CssMinimizerPlugin({})],
|
||||
minimizer: [new OptimizeCSSAssetsPlugin({})],
|
||||
},
|
||||
});
|
||||
|
||||
return [prodConfig, uncompressedConfig];
|
||||
}
|
||||
|
||||
return [config];
|
||||
return config;
|
||||
}
|
||||
|
||||
getWebpackConfig.webpack = webpack;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
/* eslint-disable no-console */
|
||||
const { getProjectPath, getConfig } = require('./utils/projectHelper');
|
||||
'use strict';
|
||||
|
||||
// const install = require('./install')
|
||||
const runCmd = require('./runCmd');
|
||||
const getBabelCommonConfig = require('./getBabelCommonConfig');
|
||||
const merge2 = require('merge2');
|
||||
const { execSync } = require('child_process');
|
||||
const through2 = require('through2');
|
||||
const transformLess = require('./transformLess');
|
||||
const webpack = require('webpack');
|
||||
const babel = require('gulp-babel');
|
||||
const argv = require('minimist')(process.argv.slice(2));
|
||||
const { Octokit } = require('@octokit/rest');
|
||||
|
||||
const packageJson = require(`${process.cwd()}/package.json`);
|
||||
// const getNpm = require('./getNpm')
|
||||
// const selfPackage = require('../package.json')
|
||||
const chalk = require('chalk');
|
||||
|
|
@ -17,35 +21,21 @@ const getNpmArgs = require('./utils/get-npm-args');
|
|||
const getChangelog = require('./utils/getChangelog');
|
||||
const path = require('path');
|
||||
// const watch = require('gulp-watch')
|
||||
const ts = require('gulp-typescript');
|
||||
const gulp = require('gulp');
|
||||
const fs = require('fs');
|
||||
const rimraf = require('rimraf');
|
||||
const replaceLib = require('./replaceLib');
|
||||
const stripCode = require('gulp-strip-code');
|
||||
const compareVersions = require('compare-versions');
|
||||
const getTSCommonConfig = require('./getTSCommonConfig');
|
||||
const replaceLib = require('./replaceLib');
|
||||
const sortApiTable = require('./sortApiTable');
|
||||
const { glob } = require('glob');
|
||||
|
||||
const packageJson = require(getProjectPath('package.json'));
|
||||
const tsDefaultReporter = ts.reporter.defaultReporter();
|
||||
const cwd = process.cwd();
|
||||
const libDir = getProjectPath('lib');
|
||||
const esDir = getProjectPath('es');
|
||||
const localeDir = getProjectPath('locale');
|
||||
|
||||
const tsConfig = getTSCommonConfig();
|
||||
|
||||
// FIXME: hard code, not find typescript can modify the path resolution
|
||||
const localeDts = `import type { Locale } from '../lib/locale-provider';
|
||||
declare const localeValues: Locale;
|
||||
export default localeValues;`;
|
||||
const libDir = path.join(cwd, 'lib');
|
||||
const esDir = path.join(cwd, 'es');
|
||||
|
||||
function dist(done) {
|
||||
rimraf.sync(path.join(cwd, 'dist'));
|
||||
process.env.RUN_ENV = 'PRODUCTION';
|
||||
const webpackConfig = require(getProjectPath('webpack.build.conf.js'));
|
||||
const webpackConfig = require(path.join(cwd, 'webpack.build.conf.js'));
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
if (err) {
|
||||
console.error(err.stack || err);
|
||||
|
|
@ -56,17 +46,11 @@ function dist(done) {
|
|||
}
|
||||
|
||||
const info = stats.toJson();
|
||||
const { dist: { finalize } = {}, bail } = getConfig();
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
(info.errors || []).forEach(error => {
|
||||
console.error(error);
|
||||
});
|
||||
// https://github.com/ant-design/ant-design/pull/31662
|
||||
if (bail) {
|
||||
process.exit(1);
|
||||
}
|
||||
console.error(info.errors);
|
||||
}
|
||||
|
||||
if (stats.hasWarnings()) {
|
||||
console.warn(info.warnings);
|
||||
}
|
||||
|
|
@ -81,44 +65,10 @@ function dist(done) {
|
|||
version: false,
|
||||
});
|
||||
console.log(buildInfo);
|
||||
// Additional process of dist finalize
|
||||
if (finalize) {
|
||||
console.log('[Dist] Finalization...');
|
||||
finalize();
|
||||
}
|
||||
done(0);
|
||||
});
|
||||
}
|
||||
|
||||
const tsFiles = ['**/*.ts', '**/*.tsx', '!node_modules/**/*.*', 'typings/**/*.d.ts'];
|
||||
|
||||
function compileTs(stream) {
|
||||
return stream
|
||||
.pipe(ts(tsConfig))
|
||||
.js.pipe(
|
||||
through2.obj(function (file, encoding, next) {
|
||||
// console.log(file.path, file.base);
|
||||
file.path = file.path.replace(/\.[jt]sx$/, '.js');
|
||||
this.push(file);
|
||||
next();
|
||||
}),
|
||||
)
|
||||
.pipe(gulp.dest(process.cwd()));
|
||||
}
|
||||
|
||||
gulp.task('tsc', () =>
|
||||
compileTs(
|
||||
gulp.src(tsFiles, {
|
||||
base: cwd,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
gulp.task('clean', () => {
|
||||
rimraf.sync(getProjectPath('_site'));
|
||||
rimraf.sync(getProjectPath('_data'));
|
||||
});
|
||||
|
||||
function babelify(js, modules) {
|
||||
const babelConfig = getBabelCommonConfig(modules);
|
||||
babelConfig.babelrc = false;
|
||||
|
|
@ -126,122 +76,67 @@ function babelify(js, modules) {
|
|||
if (modules === false) {
|
||||
babelConfig.plugins.push(replaceLib);
|
||||
}
|
||||
const stream = js.pipe(babel(babelConfig)).pipe(
|
||||
let stream = js.pipe(babel(babelConfig)).pipe(
|
||||
through2.obj(function z(file, encoding, next) {
|
||||
this.push(file.clone());
|
||||
if (modules !== false) {
|
||||
if (file.path.match(/\/style\/index\.(js|jsx)$/)) {
|
||||
const content = file.contents.toString(encoding);
|
||||
file.contents = Buffer.from(
|
||||
content
|
||||
.replace(/lodash-es/g, 'lodash')
|
||||
.replace(/@ant-design\/icons-vue/g, '@ant-design/icons-vue/lib/icons'),
|
||||
content.replace(/\/style\/?'/g, "/style/css'").replace(/\.less/g, '.css'),
|
||||
);
|
||||
file.path = file.path.replace(/index\.(js|jsx)$/, 'css.js');
|
||||
this.push(file);
|
||||
next();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
next();
|
||||
}),
|
||||
);
|
||||
return stream.pipe(gulp.dest(modules === false ? esDir : libDir));
|
||||
}
|
||||
|
||||
function compile(modules) {
|
||||
const { compile: { transformTSFile, transformFile } = {} } = getConfig();
|
||||
rimraf.sync(modules !== false ? libDir : esDir);
|
||||
|
||||
const assets = gulp
|
||||
.src(['components/**/*.@(png|svg)'])
|
||||
.pipe(gulp.dest(modules === false ? esDir : libDir));
|
||||
let error = 0;
|
||||
|
||||
// =============================== FILE ===============================
|
||||
let transformFileStream;
|
||||
|
||||
if (transformFile) {
|
||||
transformFileStream = gulp
|
||||
.src(['components/**/*.tsx'])
|
||||
.pipe(
|
||||
through2.obj(function (file, encoding, next) {
|
||||
let nextFile = transformFile(file) || file;
|
||||
nextFile = Array.isArray(nextFile) ? nextFile : [nextFile];
|
||||
nextFile.forEach(f => this.push(f));
|
||||
next();
|
||||
}),
|
||||
)
|
||||
.pipe(gulp.dest(modules === false ? esDir : libDir));
|
||||
}
|
||||
|
||||
// ================================ TS ================================
|
||||
const source = [
|
||||
'components/**/*.js',
|
||||
'components/**/*.jsx',
|
||||
'components/**/*.tsx',
|
||||
'components/**/*.ts',
|
||||
'typings/**/*.d.ts',
|
||||
'!components/*/__tests__/*',
|
||||
];
|
||||
|
||||
// Strip content if needed
|
||||
let sourceStream = gulp.src(source);
|
||||
if (modules === false) {
|
||||
sourceStream = sourceStream.pipe(
|
||||
stream = stream.pipe(
|
||||
stripCode({
|
||||
start_comment: '@remove-on-es-build-begin',
|
||||
end_comment: '@remove-on-es-build-end',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (transformTSFile) {
|
||||
sourceStream = sourceStream.pipe(
|
||||
through2.obj(function (file, encoding, next) {
|
||||
let nextFile = transformTSFile(file) || file;
|
||||
nextFile = Array.isArray(nextFile) ? nextFile : [nextFile];
|
||||
nextFile.forEach(f => this.push(f));
|
||||
next();
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const tsResult = sourceStream.pipe(
|
||||
ts(tsConfig, {
|
||||
error(e) {
|
||||
tsDefaultReporter.error(e);
|
||||
error = 1;
|
||||
},
|
||||
finish: tsDefaultReporter.finish,
|
||||
}),
|
||||
);
|
||||
|
||||
function check() {
|
||||
if (error && !argv['ignore-error']) {
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
tsResult.on('finish', check);
|
||||
tsResult.on('end', check);
|
||||
const tsFilesStream = babelify(tsResult.js, modules);
|
||||
const tsd = tsResult.dts.pipe(gulp.dest(modules === false ? esDir : libDir));
|
||||
return merge2([tsFilesStream, tsd, assets, transformFileStream].filter(s => s));
|
||||
return stream.pipe(gulp.dest(modules === false ? esDir : libDir));
|
||||
}
|
||||
|
||||
function generateLocale() {
|
||||
if (!fs.existsSync(localeDir)) {
|
||||
fs.mkdirSync(localeDir);
|
||||
}
|
||||
function compile(modules) {
|
||||
rimraf.sync(modules !== false ? libDir : esDir);
|
||||
const less = gulp
|
||||
.src(['components/**/*.less'])
|
||||
.pipe(
|
||||
through2.obj(function(file, encoding, next) {
|
||||
this.push(file.clone());
|
||||
if (
|
||||
file.path.match(/\/style\/index\.less$/) ||
|
||||
file.path.match(/\/style\/v2-compatible-reset\.less$/)
|
||||
) {
|
||||
transformLess(file.path)
|
||||
.then(css => {
|
||||
file.contents = Buffer.from(css);
|
||||
file.path = file.path.replace(/\.less$/, '.css');
|
||||
this.push(file);
|
||||
next();
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e);
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}),
|
||||
)
|
||||
.pipe(gulp.dest(modules === false ? esDir : libDir));
|
||||
const assets = gulp
|
||||
.src(['components/**/*.@(png|svg)'])
|
||||
.pipe(gulp.dest(modules === false ? esDir : libDir));
|
||||
|
||||
const localeFiles = glob.sync('components/locale/*.ts?(x)');
|
||||
localeFiles.forEach(item => {
|
||||
const match = item.match(/components\/locale\/(.*)\.tsx?/);
|
||||
if (match) {
|
||||
const locale = match[1];
|
||||
fs.writeFileSync(
|
||||
path.join(localeDir, `${locale}.js`),
|
||||
`module.exports = require('../lib/locale/${locale}');`,
|
||||
);
|
||||
fs.writeFileSync(path.join(localeDir, `${locale}.d.ts`), localeDts);
|
||||
}
|
||||
});
|
||||
const source = ['components/**/*.js', 'components/**/*.jsx', '!components/*/__tests__/*'];
|
||||
const jsFilesStream = babelify(gulp.src(source), modules);
|
||||
return merge2([less, jsFilesStream, assets]);
|
||||
}
|
||||
|
||||
function tag() {
|
||||
|
|
@ -347,71 +242,61 @@ function publish(tagString, done) {
|
|||
}
|
||||
|
||||
function pub(done) {
|
||||
const notOk = !packageJson.version.match(/^\d+\.\d+\.\d+$/);
|
||||
let tagString;
|
||||
if (argv['npm-tag']) {
|
||||
tagString = argv['npm-tag'];
|
||||
}
|
||||
if (!tagString && notOk) {
|
||||
tagString = 'next';
|
||||
}
|
||||
if (packageJson.scripts['pre-publish']) {
|
||||
runCmd('npm', ['run', 'pre-publish'], code2 => {
|
||||
if (code2) {
|
||||
done(code2);
|
||||
return;
|
||||
}
|
||||
dist(code => {
|
||||
if (code) {
|
||||
done(code);
|
||||
return;
|
||||
}
|
||||
const notOk = !packageJson.version.match(/^\d+\.\d+\.\d+$/);
|
||||
let tagString;
|
||||
if (argv['npm-tag']) {
|
||||
tagString = argv['npm-tag'];
|
||||
}
|
||||
if (!tagString && notOk) {
|
||||
tagString = 'next';
|
||||
}
|
||||
if (packageJson.scripts['pre-publish']) {
|
||||
runCmd('npm', ['run', 'pre-publish'], code2 => {
|
||||
if (code2) {
|
||||
done(code2);
|
||||
return;
|
||||
}
|
||||
publish(tagString, done);
|
||||
});
|
||||
} else {
|
||||
publish(tagString, done);
|
||||
});
|
||||
} else {
|
||||
publish(tagString, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const startTime = new Date();
|
||||
gulp.task('compile-with-es', done => {
|
||||
console.log('start compile at ', startTime);
|
||||
console.log('[Parallel] Compile to es...');
|
||||
compile(false).on('finish', done);
|
||||
});
|
||||
|
||||
gulp.task('compile-with-lib', done => {
|
||||
console.log('[Parallel] Compile to js...');
|
||||
compile().on('finish', () => {
|
||||
generateLocale();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('compile-finalize', done => {
|
||||
// Additional process of compile finalize
|
||||
const { compile: { finalize } = {} } = getConfig();
|
||||
if (finalize) {
|
||||
console.log('[Compile] Finalization...');
|
||||
finalize();
|
||||
}
|
||||
done();
|
||||
});
|
||||
gulp.task(
|
||||
'compile-with-es',
|
||||
gulp.series(done => {
|
||||
compile(false).on('finish', function() {
|
||||
done();
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
gulp.task(
|
||||
'compile',
|
||||
gulp.series(gulp.parallel('compile-with-es', 'compile-with-lib'), 'compile-finalize', done => {
|
||||
console.log('end compile at ', new Date());
|
||||
console.log('compile time ', (new Date() - startTime) / 1000, 's');
|
||||
done();
|
||||
gulp.series('compile-with-es', done => {
|
||||
compile().on('finish', function() {
|
||||
done();
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
gulp.task(
|
||||
'dist',
|
||||
gulp.series(done => {
|
||||
gulp.series('compile', done => {
|
||||
dist(done);
|
||||
}),
|
||||
);
|
||||
|
||||
gulp.task(
|
||||
'pub',
|
||||
gulp.series('check-git', 'compile', 'dist', done => {
|
||||
gulp.series('check-git', 'compile', done => {
|
||||
// if (!process.env.GITHUB_TOKEN) {
|
||||
// console.log('no GitHub token found, skip');
|
||||
// } else {
|
||||
|
|
@ -452,7 +337,7 @@ gulp.task(
|
|||
newVersion.trim() === version
|
||||
) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
runCmd('npm', ['run', 'pub'], _code => {
|
||||
runCmd('npm', ['run', 'pub'], code => {
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
|
|
@ -475,11 +360,7 @@ gulp.task(
|
|||
const npmArgs = getNpmArgs();
|
||||
if (npmArgs) {
|
||||
for (let arg = npmArgs.shift(); arg; arg = npmArgs.shift()) {
|
||||
if (
|
||||
/^pu(b(l(i(sh?)?)?)?)?$/.test(arg) &&
|
||||
npmArgs.indexOf('--with-antd-tools') < 0 &&
|
||||
!process.env.npm_config_with_antd_tools
|
||||
) {
|
||||
if (/^pu(b(l(i(sh?)?)?)?)?$/.test(arg) && npmArgs.indexOf('--with-antd-tools') < 0) {
|
||||
reportError();
|
||||
done(1);
|
||||
return;
|
||||
|
|
@ -489,11 +370,3 @@ gulp.task(
|
|||
done();
|
||||
}),
|
||||
);
|
||||
|
||||
gulp.task(
|
||||
'sort-api-table',
|
||||
gulp.series(done => {
|
||||
sortApiTable();
|
||||
done();
|
||||
}),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
const rucksack = require('rucksack-css');
|
||||
const autoprefixer = require('autoprefixer');
|
||||
|
||||
module.exports = {
|
||||
plugins: [rucksack(), autoprefixer()],
|
||||
};
|
||||
|
|
@ -1,26 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
const { dirname } = require('path');
|
||||
const { join, dirname } = require('path');
|
||||
const fs = require('fs');
|
||||
const { getProjectPath } = require('./utils/projectHelper');
|
||||
|
||||
const cwd = process.cwd();
|
||||
|
||||
function replacePath(path) {
|
||||
if (path.node.source && /\/lib\//.test(path.node.source.value)) {
|
||||
const esModule = path.node.source.value.replace('/lib/', '/es/');
|
||||
const esPath = dirname(getProjectPath('node_modules', esModule));
|
||||
if (fs.existsSync(esPath)) {
|
||||
path.node.source.value = esModule;
|
||||
}
|
||||
}
|
||||
|
||||
// @ant-design/icons-vue/xxx => @ant-design/icons-vue/es/icons/xxx
|
||||
const antdIconMatcher = /@ant-design\/icons-vue\/([^/]*)$/;
|
||||
if (path.node.source && antdIconMatcher.test(path.node.source.value)) {
|
||||
const esModule = path.node.source.value.replace(
|
||||
antdIconMatcher,
|
||||
(_, iconName) => `@ant-design/icons-vue/es/icons/${iconName}`,
|
||||
);
|
||||
const esPath = dirname(getProjectPath('node_modules', esModule));
|
||||
const esPath = dirname(join(cwd, `node_modules/${esModule}`));
|
||||
if (fs.existsSync(esPath)) {
|
||||
path.node.source.value = esModule;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
const isWindows = require('is-windows');
|
||||
const getRunCmdEnv = require('./utils/getRunCmdEnv');
|
||||
|
||||
function runCmd(cmd, _args, fn) {
|
||||
const args = _args || [];
|
||||
|
||||
if (isWindows()) {
|
||||
args.unshift(cmd);
|
||||
args.unshift('/c');
|
||||
cmd = process.env.ComSpec;
|
||||
}
|
||||
|
||||
const runner = require('child_process').spawn(cmd, args, {
|
||||
// keep color
|
||||
stdio: 'inherit',
|
||||
|
|
|
|||
|
|
@ -1,165 +0,0 @@
|
|||
const program = require('commander');
|
||||
const majo = require('majo');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const chalk = require('chalk');
|
||||
|
||||
const unified = require('unified');
|
||||
const parse = require('remark-parse');
|
||||
const stringify = require('remark-stringify');
|
||||
|
||||
const yamlConfig = require('remark-yaml-config');
|
||||
const frontmatter = require('remark-frontmatter');
|
||||
|
||||
let fileAPIs = {};
|
||||
const remarkWithYaml = unified()
|
||||
.use(parse)
|
||||
.use(stringify, {
|
||||
paddedTable: false,
|
||||
listItemIndent: 1,
|
||||
stringLength: () => 3,
|
||||
})
|
||||
.use(frontmatter)
|
||||
.use(yamlConfig);
|
||||
|
||||
const stream = majo.majo();
|
||||
|
||||
function getCellValue(node) {
|
||||
return node.children[0].children[0].value;
|
||||
}
|
||||
|
||||
// from small to large
|
||||
const sizeBreakPoints = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'];
|
||||
|
||||
const whiteMethodList = ['afterChange', 'beforeChange'];
|
||||
|
||||
const groups = {
|
||||
isDynamic: val => /^on[A-Z]/.test(val) || whiteMethodList.indexOf(val) > -1,
|
||||
isSize: val => sizeBreakPoints.indexOf(val) > -1,
|
||||
};
|
||||
|
||||
function asciiSort(prev, next) {
|
||||
if (prev > next) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (prev < next) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// follow the alphabet order
|
||||
function alphabetSort(nodes) {
|
||||
// use toLowerCase to keep `case insensitive`
|
||||
return nodes.sort((...comparison) =>
|
||||
asciiSort(...comparison.map(val => getCellValue(val).toLowerCase())),
|
||||
);
|
||||
}
|
||||
|
||||
function sizeSort(nodes) {
|
||||
return nodes.sort((...comparison) =>
|
||||
asciiSort(...comparison.map(val => sizeBreakPoints.indexOf(getCellValue(val).toLowerCase()))),
|
||||
);
|
||||
}
|
||||
|
||||
function sort(ast, filename) {
|
||||
const nameMatch = filename.match(/^components\/([^/]*)\//);
|
||||
const componentName = nameMatch[1];
|
||||
fileAPIs[componentName] = fileAPIs[componentName] || {
|
||||
static: new Set(),
|
||||
size: new Set(),
|
||||
dynamic: new Set(),
|
||||
};
|
||||
|
||||
ast.children.forEach(child => {
|
||||
const staticProps = [];
|
||||
// prefix with `on`
|
||||
const dynamicProps = [];
|
||||
// one of ['xs', 'sm', 'md', 'lg', 'xl']
|
||||
const sizeProps = [];
|
||||
|
||||
// find table markdown type
|
||||
if (child.type === 'table') {
|
||||
// slice will create new array, so sort can affect the original array.
|
||||
// slice(1) cut down the thead
|
||||
child.children.slice(1).forEach(node => {
|
||||
const value = getCellValue(node);
|
||||
if (groups.isDynamic(value)) {
|
||||
dynamicProps.push(node);
|
||||
fileAPIs[componentName].dynamic.add(value);
|
||||
} else if (groups.isSize(value)) {
|
||||
sizeProps.push(node);
|
||||
fileAPIs[componentName].size.add(value);
|
||||
} else {
|
||||
staticProps.push(node);
|
||||
fileAPIs[componentName].static.add(value);
|
||||
}
|
||||
});
|
||||
|
||||
// eslint-disable-next-line
|
||||
child.children = [
|
||||
child.children[0],
|
||||
...alphabetSort(staticProps),
|
||||
...sizeSort(sizeProps),
|
||||
...alphabetSort(dynamicProps),
|
||||
];
|
||||
}
|
||||
});
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
function sortAPI(md, filename) {
|
||||
return remarkWithYaml.stringify(sort(remarkWithYaml.parse(md), filename));
|
||||
}
|
||||
|
||||
function sortMiddleware(ctx) {
|
||||
Object.keys(ctx.files).forEach(filename => {
|
||||
const content = ctx.fileContents(filename);
|
||||
ctx.writeContents(filename, sortAPI(content, filename));
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = () => {
|
||||
fileAPIs = {};
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
.option(
|
||||
'-f, --file [file]',
|
||||
'Specify which file to be transformed',
|
||||
// default value
|
||||
'components/**/index.+(zh-CN|en-US).md',
|
||||
)
|
||||
.option('-o, --output [output]', 'Specify component api output path', '~component-api.json')
|
||||
.parse(process.argv);
|
||||
// Get the markdown file all need to be transformed
|
||||
|
||||
/* eslint-disable no-console */
|
||||
stream
|
||||
.source(program.file)
|
||||
.use(sortMiddleware)
|
||||
.dest('.')
|
||||
.then(() => {
|
||||
if (program.output) {
|
||||
const data = {};
|
||||
Object.keys(fileAPIs).forEach(componentName => {
|
||||
data[componentName] = {
|
||||
static: [...fileAPIs[componentName].static],
|
||||
size: [...fileAPIs[componentName].size],
|
||||
dynamic: [...fileAPIs[componentName].dynamic],
|
||||
};
|
||||
});
|
||||
|
||||
const reportPath = path.resolve(program.output);
|
||||
fs.writeFileSync(reportPath, JSON.stringify(data, null, 2), 'utf8');
|
||||
console.log(chalk.cyan(`API list file: ${reportPath}`));
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
console.log(chalk.green(`sort ant-design-vue api successfully!`));
|
||||
});
|
||||
/* eslint-enable no-console */
|
||||
};
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
const less = require('less');
|
||||
const { readFileSync } = require('fs');
|
||||
const path = require('path');
|
||||
const postcss = require('postcss');
|
||||
const NpmImportPlugin = require('less-plugin-npm-import');
|
||||
const postcssConfig = require('./postcssConfig');
|
||||
|
||||
function transformLess(lessFile, config = {}) {
|
||||
const { cwd = process.cwd() } = config;
|
||||
const resolvedLessFile = path.resolve(cwd, lessFile);
|
||||
|
||||
let data = readFileSync(resolvedLessFile, 'utf-8');
|
||||
data = data.replace(/^\uFEFF/, '');
|
||||
|
||||
// Do less compile
|
||||
const lessOpts = {
|
||||
paths: [path.dirname(resolvedLessFile)],
|
||||
filename: resolvedLessFile,
|
||||
plugins: [new NpmImportPlugin({ prefix: '~' })],
|
||||
javascriptEnabled: true,
|
||||
};
|
||||
return less
|
||||
.render(data, lessOpts)
|
||||
.then(result => {
|
||||
const source = result.css;
|
||||
return postcss(postcssConfig.plugins).process(source, { from: undefined });
|
||||
})
|
||||
.then(r => {
|
||||
return r.css;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = transformLess;
|
||||
|
|
@ -24,13 +24,13 @@ class CleanUpStatsPlugin {
|
|||
|
||||
apply(compiler) {
|
||||
compiler.hooks.done.tap('CleanUpStatsPlugin', stats => {
|
||||
const { children, warnings } = stats.compilation;
|
||||
const { children } = stats.compilation;
|
||||
if (Array.isArray(children)) {
|
||||
stats.compilation.children = children.filter(child => this.shouldPickStatChild(child));
|
||||
}
|
||||
if (Array.isArray(warnings)) {
|
||||
stats.compilation.warnings = warnings.filter(message => this.shouldPickWarning(message));
|
||||
}
|
||||
// if (Array.isArray(warnings)) {
|
||||
// stats.compilation.warnings = warnings.filter(message => this.shouldPickWarning(message));
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,6 @@
|
|||
|
||||
// NOTE: the following code was partially adopted from https://github.com/iarna/in-publish
|
||||
module.exports = function getNpmArgs() {
|
||||
// https://github.com/iarna/in-publish/pull/14
|
||||
if (process.env.npm_command) {
|
||||
return [process.env.npm_command];
|
||||
}
|
||||
|
||||
let npmArgv = null;
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
const fs = require('fs');
|
||||
|
||||
module.exports = function getChangelog(file, version) {
|
||||
const lines = fs.readFileSync(file).toString().split('\n');
|
||||
const lines = fs
|
||||
.readFileSync(file)
|
||||
.toString()
|
||||
.split('\n');
|
||||
const changeLog = [];
|
||||
const startPattern = new RegExp(`^## ${version}`);
|
||||
const stopPattern = /^## /; // 前一个版本
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const isWindows = require('is-windows');
|
||||
|
||||
module.exports = function getRunCmdEnv() {
|
||||
const env = {};
|
||||
|
|
@ -12,12 +11,16 @@ module.exports = function getRunCmdEnv() {
|
|||
const nodeModulesBinDir = path.join(__dirname, '../../node_modules/.bin');
|
||||
|
||||
Object.entries(env)
|
||||
.filter(v => v.slice(0, 1).pop().toLowerCase() === 'path')
|
||||
.filter(
|
||||
v =>
|
||||
v
|
||||
.slice(0, 1)
|
||||
.pop()
|
||||
.toLowerCase() === 'path',
|
||||
)
|
||||
.forEach(v => {
|
||||
const key = v.slice(0, 1).pop();
|
||||
env[key] = env[key]
|
||||
? `${nodeModulesBinDir}${isWindows() ? ';' : ':'}${env[key]}`
|
||||
: nodeModulesBinDir;
|
||||
env[key] = env[key] ? `${nodeModulesBinDir}:${env[key]}` : nodeModulesBinDir;
|
||||
});
|
||||
return env;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const cwd = process.cwd();
|
||||
|
||||
function getProjectPath(...filePath) {
|
||||
return path.join(cwd, ...filePath);
|
||||
}
|
||||
|
||||
function resolve(moduleName) {
|
||||
return require.resolve(moduleName);
|
||||
}
|
||||
|
||||
// We need hack the require to ensure use package module first
|
||||
// For example, `typescript` is required by `gulp-typescript` but provided by `antd`
|
||||
// we do not need for ant-design-vue
|
||||
let injected = false;
|
||||
function injectRequire() {
|
||||
if (injected) return;
|
||||
|
||||
const Module = require('module');
|
||||
|
||||
const oriRequire = Module.prototype.require;
|
||||
Module.prototype.require = function (...args) {
|
||||
const moduleName = args[0];
|
||||
try {
|
||||
return oriRequire.apply(this, args);
|
||||
} catch (err) {
|
||||
const newArgs = [...args];
|
||||
if (moduleName[0] !== '/') {
|
||||
newArgs[0] = getProjectPath('node_modules', moduleName);
|
||||
}
|
||||
return oriRequire.apply(this, newArgs);
|
||||
}
|
||||
};
|
||||
|
||||
injected = true;
|
||||
}
|
||||
|
||||
function getConfig() {
|
||||
const configPath = getProjectPath('.antd-tools.config.js');
|
||||
if (fs.existsSync(configPath)) {
|
||||
return require(configPath);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在可用的browserslist config
|
||||
* https://github.com/browserslist/browserslist#queries
|
||||
* @returns
|
||||
*/
|
||||
function isThereHaveBrowserslistConfig() {
|
||||
try {
|
||||
const packageJson = require(getProjectPath('package.json'));
|
||||
if (packageJson.browserslist) {
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
if (fs.existsSync(getProjectPath('.browserslistrc'))) {
|
||||
return true;
|
||||
}
|
||||
if (fs.existsSync(getProjectPath('browserslist'))) {
|
||||
return true;
|
||||
}
|
||||
// parent项目的配置支持,需要再补充
|
||||
// ROWSERSLIST ROWSERSLIST_ENV 变量的形式,需要再补充。
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getProjectPath,
|
||||
resolve,
|
||||
injectRequire,
|
||||
getConfig,
|
||||
isThereHaveBrowserslistConfig,
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"env": {
|
||||
"test": {
|
||||
"presets": [["env", { "targets": { "node": "current" } }]],
|
||||
"plugins": [
|
||||
"transform-vue-jsx",
|
||||
"transform-object-assign",
|
||||
"transform-object-rest-spread",
|
||||
"transform-class-properties",
|
||||
"transform-runtime"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# 🎨 editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
node_modules/
|
||||
**/*.spec.*
|
||||
**/style/
|
||||
*.html
|
||||
/components/test/*
|
||||
_site/
|
||||
dist/
|
||||
package.json
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"jasmine": true,
|
||||
"jest": true,
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"extends": ["plugin:vue/recommended", "prettier"],
|
||||
"plugins": ["markdown"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/demo/*.md"],
|
||||
"processor": "markdown/markdown",
|
||||
"rules": {
|
||||
"no-console": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": {
|
||||
"comma-dangle": [2, "always-multiline"],
|
||||
"no-var": "error",
|
||||
"no-console": [2, { "allow": ["warn", "error"] }],
|
||||
"object-shorthand": 2,
|
||||
"no-unused-vars": [2, { "ignoreRestSiblings": true, "argsIgnorePattern": "^h$" }],
|
||||
"no-undef": 2,
|
||||
"camelcase": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
"semi": ["error", "always"],
|
||||
"vue/require-prop-types": "off",
|
||||
"vue/require-default-prop": "off",
|
||||
"vue/no-reserved-keys": "off",
|
||||
"vue/comment-directive": "off",
|
||||
"vue/prop-name-casing": "off",
|
||||
"vue/max-attributes-per-line": [
|
||||
2,
|
||||
{
|
||||
"singleline": 20,
|
||||
"multiline": {
|
||||
"max": 1,
|
||||
"allowFirstLine": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"globals": {
|
||||
"h": true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and *not* Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
site/dev.js
|
||||
_site/
|
||||
package-lock.json
|
||||
testDemo/
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"hooks": {
|
||||
"pre-commit": "pretty-quick --staged",
|
||||
"pre-publish": "npm run lint",
|
||||
"commit-msg": "commitlint -x @commitlint/config-conventional -e $GIT_PARAMS"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
**/*.svg
|
||||
package.json
|
||||
lib/
|
||||
es/
|
||||
dist/
|
||||
_site/
|
||||
coverage/
|
||||
CNAME
|
||||
LICENSE
|
||||
yarn.lock
|
||||
netlify.toml
|
||||
yarn-error.log
|
||||
*.sh
|
||||
*.snap
|
||||
.gitignore
|
||||
.npmignore
|
||||
.prettierignore
|
||||
.DS_Store
|
||||
.editorconfig
|
||||
.eslintignore
|
||||
**/*.yml
|
||||
components/style/color/*.less
|
||||
**/assets
|
||||
.gitattributes
|
||||
.stylelintrc
|
||||
.vcmrc
|
||||
.png
|
||||
.npmrc.template
|
||||
.huskyrc
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 100,
|
||||
"proseWrap": "never",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ".prettierrc",
|
||||
"options": {
|
||||
"parser": "json"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"extends": ["stylelint-config-standard", "stylelint-config-prettier"],
|
||||
"rules": {
|
||||
"comment-empty-line-before": null,
|
||||
"declaration-empty-line-before": null,
|
||||
"function-comma-newline-after": null,
|
||||
"function-name-case": null,
|
||||
"function-parentheses-newline-inside": null,
|
||||
"function-max-empty-lines": null,
|
||||
"function-whitespace-after": null,
|
||||
"indentation": null,
|
||||
"number-leading-zero": null,
|
||||
"number-no-trailing-zeros": null,
|
||||
"rule-empty-line-before": null,
|
||||
"selector-combinator-space-after": null,
|
||||
"selector-list-comma-newline-after": null,
|
||||
"selector-pseudo-element-colon-notation": null,
|
||||
"unit-no-unknown": null,
|
||||
"value-list-max-empty-lines": null,
|
||||
"font-family-no-missing-generic-family-keyword": null,
|
||||
"no-descending-specificity": null
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
...require('./mock/user'),
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
rm -rf dist
|
||||
mkdir dist
|
||||
./node_modules/.bin/webpack --config webpack.site.config.js
|
||||
cp dist/index.html index.html
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
dev: {
|
||||
componentName: 'form', // dev components
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
process.env.ENTRY_INDEX = 'dev';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const chokidar = require('chokidar');
|
||||
const importFresh = require('import-fresh');
|
||||
const replace = require('json-templater/string');
|
||||
const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
const devWebpack = require('./webpack.dev.conf');
|
||||
|
||||
const configPath = path.join(__dirname, './config.js');
|
||||
|
||||
/**
|
||||
* a-bc-d --> aBcD
|
||||
* @param {string} s
|
||||
*/
|
||||
const camelize = s => s.replace(/-(\w)/g, ($, $1) => $1.toUpperCase());
|
||||
|
||||
/**
|
||||
* radio-group --> radio
|
||||
* @param {string} s
|
||||
*/
|
||||
const getUpper = s => s.replace(/(-[a-z]*)/g, '');
|
||||
|
||||
let { componentName } = require('./config').dev;
|
||||
|
||||
const componentsInPrototype = ['Modal', 'message', 'notification'];
|
||||
|
||||
const MAIN_TEMPLATE = `import 'babel-polyfill';
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import VueI18n from 'vue-i18n';
|
||||
import VueRouter from 'vue-router';
|
||||
import VueClipboard from 'vue-clipboard2';
|
||||
import Md from '../components/md';
|
||||
import Api from '../components/api';
|
||||
import demoBox from '../components/demoBox';
|
||||
import demoSort from '../components/demoSort';
|
||||
import demoContainer from '../components/demoContainer';
|
||||
import { message, notification } from 'ant-design-vue';
|
||||
{{importComponents}}
|
||||
{{importStyles}}
|
||||
import 'ant-design-vue/es/message/style';
|
||||
import 'ant-design-vue/es/notification/style';
|
||||
import Test from '../docs/{{name}}/demo/index.vue';
|
||||
import zhCN from '../theme/zh-CN';
|
||||
import enUS from '../theme/en-US';
|
||||
import './index.less';
|
||||
|
||||
Vue.use(Vuex);
|
||||
Vue.use(VueClipboard);
|
||||
Vue.use(VueRouter);
|
||||
Vue.use(VueI18n);
|
||||
Vue.component(Md.name, Md);
|
||||
Vue.component(Api.name, Api);
|
||||
Vue.component('demo-box', demoBox);
|
||||
Vue.component('demo-sort', demoSort);
|
||||
Vue.component('demo-container', demoContainer);
|
||||
|
||||
Vue.prototype.$message = message;
|
||||
Vue.prototype.$notification = notification;
|
||||
Vue.prototype.$info = Modal.info;
|
||||
Vue.prototype.$success = Modal.success;
|
||||
Vue.prototype.$error = Modal.error;
|
||||
Vue.prototype.$warning = Modal.warning;
|
||||
Vue.prototype.$confirm = Modal.confirm;
|
||||
Vue.prototype.$destroyAll = Modal.destroyAll;
|
||||
Vue.prototype.$form = Form;
|
||||
|
||||
Vue.use(Modal);
|
||||
{{install}}
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: enUS.locale,
|
||||
messages: {
|
||||
[enUS.locale]: { message: enUS.messages },
|
||||
[zhCN.locale]: { message: zhCN.messages },
|
||||
},
|
||||
});
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
routes: [{
|
||||
path: '/test',
|
||||
component: () => import('../testDemo/index.vue'),
|
||||
}, {
|
||||
path: '/*', component: Test
|
||||
}],
|
||||
});
|
||||
|
||||
const store = new Vuex.Store({
|
||||
state: {
|
||||
username: 'zeka',
|
||||
},
|
||||
mutations: {
|
||||
update(state, payload) {
|
||||
state.username = payload.username;
|
||||
},
|
||||
},
|
||||
});
|
||||
new Vue({
|
||||
el: '#app',
|
||||
i18n,
|
||||
router,
|
||||
store,
|
||||
});
|
||||
`;
|
||||
|
||||
const OUTPUT_PATH = path.join(__dirname, '../site/dev.js');
|
||||
|
||||
const generateEntry = components =>
|
||||
Object.keys(components)
|
||||
.map(component => `import ${component} from 'ant-design-vue/es/${components[component]}';`)
|
||||
.join('\n');
|
||||
|
||||
const generateStyles = components =>
|
||||
Object.keys(components)
|
||||
.map(component => `import 'ant-design-vue/es/${components[component]}/style';`)
|
||||
.join('\n');
|
||||
|
||||
const generateInstall = components =>
|
||||
Object.keys(components)
|
||||
.map(component => `Vue.use(${component});`)
|
||||
.join('\n');
|
||||
|
||||
const renderTemplate = name => {
|
||||
const components = {
|
||||
Tooltip: 'tooltip', // for DemoBox
|
||||
Icon: 'icon', // Basic
|
||||
Form: 'form',
|
||||
Modal: 'modal',
|
||||
};
|
||||
|
||||
const demoPaths = fs
|
||||
.readdirSync(path.join(__dirname, `../docs/${name}/demo`))
|
||||
.map(p => `../docs/${name}/demo/${p}`);
|
||||
const testPaths = fs
|
||||
.readdirSync(path.join(__dirname, `../testDemo`))
|
||||
.map(p => `../testDemo/${p}`);
|
||||
[...demoPaths, ...testPaths].forEach(demoPath => {
|
||||
const demo = fs.readFileSync(path.join(__dirname, demoPath)).toString();
|
||||
|
||||
const componentsInDemo = demo.match(/a-(\w+(-\w+)*)/g) || [];
|
||||
componentsInDemo.forEach(name => {
|
||||
const dirName = name.replace(/^a-/, '');
|
||||
const componentName = camelize(name).replace(/^a/, '');
|
||||
const upperComponentDir = getUpper(dirName);
|
||||
const upperComponentName = upperComponentDir.replace(/^[a-z]/, $ => $.toUpperCase());
|
||||
|
||||
const componentPath = path.join(__dirname, `../../components/${dirName}`);
|
||||
if (fs.existsSync(componentPath)) {
|
||||
if (componentsInPrototype.includes(componentName)) {
|
||||
return;
|
||||
}
|
||||
components[componentName] = dirName;
|
||||
} else if (fs.existsSync(path.join(__dirname, `../../components/${upperComponentDir}`))) {
|
||||
components[upperComponentName] = upperComponentDir;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const importComponents = generateEntry(components);
|
||||
const importStyles = generateStyles(components);
|
||||
const install = generateInstall(components);
|
||||
const template = replace(MAIN_TEMPLATE, {
|
||||
importComponents,
|
||||
importStyles,
|
||||
install,
|
||||
name,
|
||||
});
|
||||
fs.writeFileSync(OUTPUT_PATH, template);
|
||||
};
|
||||
|
||||
function fsExistsSync(path) {
|
||||
try {
|
||||
fs.accessSync(path, fs.F_OK);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!fsExistsSync(path.join(__dirname, '../testDemo/index.vue'))) {
|
||||
if (!fsExistsSync(path.join(__dirname, '../testDemo'))) {
|
||||
fs.mkdirSync(path.join(__dirname, '../testDemo'));
|
||||
}
|
||||
fs.writeFileSync(path.join(__dirname, '../testDemo/index.vue'), `<template></template>`);
|
||||
}
|
||||
|
||||
let demoWatcher;
|
||||
|
||||
chokidar.watch(configPath, { ignoreInitial: true }).on('change', async () => {
|
||||
({ componentName } = importFresh(configPath).dev);
|
||||
|
||||
demoWatcher && (await demoWatcher.close());
|
||||
|
||||
demoWatcher = chokidar.watch(path.join(__dirname, `../docs/${componentName}/demo`));
|
||||
demoWatcher.on('change', () => {
|
||||
renderTemplate(componentName);
|
||||
});
|
||||
|
||||
renderTemplate(componentName);
|
||||
});
|
||||
|
||||
renderTemplate(componentName);
|
||||
|
||||
const compiler = webpack(devWebpack);
|
||||
|
||||
const configuration = devWebpack.devServer;
|
||||
|
||||
const server = new WebpackDevServer(compiler, configuration);
|
||||
server.listen(configuration.port);
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = function(modules) {
|
||||
const plugins = [
|
||||
require.resolve('babel-plugin-transform-vue-jsx'),
|
||||
require.resolve('babel-plugin-inline-import-data-uri'),
|
||||
require.resolve('babel-plugin-transform-es3-member-expression-literals'),
|
||||
require.resolve('babel-plugin-transform-es3-property-literals'),
|
||||
require.resolve('babel-plugin-transform-object-assign'),
|
||||
require.resolve('babel-plugin-transform-object-rest-spread'),
|
||||
require.resolve('babel-plugin-transform-class-properties'),
|
||||
];
|
||||
plugins.push([
|
||||
require.resolve('babel-plugin-transform-runtime'),
|
||||
{
|
||||
polyfill: false,
|
||||
},
|
||||
]);
|
||||
return {
|
||||
presets: [
|
||||
[
|
||||
require.resolve('babel-preset-env'),
|
||||
{
|
||||
modules,
|
||||
targets: {
|
||||
browsers: [
|
||||
'last 2 versions',
|
||||
'Firefox ESR',
|
||||
'> 1%',
|
||||
'ie >= 9',
|
||||
'iOS >= 8',
|
||||
'Android >= 4',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins,
|
||||
env: {
|
||||
test: {
|
||||
plugins: [require.resolve('babel-plugin-istanbul')],
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
module.exports = function(env) {
|
||||
const isDev = env === 'development';
|
||||
return {
|
||||
test: /\.less$/,
|
||||
oneOf: [
|
||||
/* config.module.rule('less').oneOf('vue-modules') */
|
||||
{
|
||||
resourceQuery: /module/,
|
||||
use: [
|
||||
isDev
|
||||
? {
|
||||
loader: 'vue-style-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
shadowMode: false,
|
||||
},
|
||||
}
|
||||
: MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
importLoaders: 2,
|
||||
modules: {
|
||||
localIdentName: '[name]_[local]_[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
lessOptions: {
|
||||
sourceMap: isDev,
|
||||
modifyVars: {},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
/* config.module.rule('less').oneOf('vue') */
|
||||
{
|
||||
resourceQuery: /\?vue/,
|
||||
use: [
|
||||
isDev
|
||||
? {
|
||||
loader: 'vue-style-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
shadowMode: false,
|
||||
},
|
||||
}
|
||||
: MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
importLoaders: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
lessOptions: {
|
||||
sourceMap: isDev,
|
||||
modifyVars: {},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
/* config.module.rule('less').oneOf('normal-modules') */
|
||||
{
|
||||
test: /\.module\.\w+$/,
|
||||
use: [
|
||||
isDev
|
||||
? {
|
||||
loader: 'vue-style-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
shadowMode: false,
|
||||
},
|
||||
}
|
||||
: MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
importLoaders: 2,
|
||||
modules: {
|
||||
localIdentName: '[name]_[local]_[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
lessOptions: {
|
||||
sourceMap: isDev,
|
||||
modifyVars: {},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
/* config.module.rule('less').oneOf('normal') */
|
||||
{
|
||||
use: [
|
||||
isDev
|
||||
? {
|
||||
loader: 'vue-style-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
shadowMode: false,
|
||||
},
|
||||
}
|
||||
: MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
importLoaders: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
lessOptions: {
|
||||
sourceMap: isDev,
|
||||
modifyVars: {},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const Prism = require('prismjs');
|
||||
require('prismjs/components/prism-jsx.min.js');
|
||||
require('prismjs/components/prism-bash.min.js');
|
||||
require('prismjs/components/prism-json.min.js');
|
||||
require('prismjs/components/prism-diff.min.js');
|
||||
require('prismjs/components/prism-less.min.js');
|
||||
const Token = require('markdown-it/lib/token');
|
||||
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
|
||||
const cheerio = require('cheerio');
|
||||
const WebpackBar = require('webpackbar');
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
const getBabelCommonConfig = require('./getBabelCommonConfig');
|
||||
const babelConfig = getBabelCommonConfig(false);
|
||||
|
||||
babelConfig.plugins.push(require.resolve('babel-plugin-syntax-dynamic-import'));
|
||||
|
||||
const fetch = (str, tag, scoped) => {
|
||||
const $ = cheerio.load(str, {
|
||||
decodeEntities: false,
|
||||
xmlMode: true,
|
||||
});
|
||||
if (!tag) {
|
||||
return str;
|
||||
}
|
||||
if (tag === 'style') {
|
||||
return scoped
|
||||
? $(`${tag}[scoped]`).html()
|
||||
: $(`${tag}`)
|
||||
.not(`${tag}[scoped]`)
|
||||
.html();
|
||||
}
|
||||
return $(tag).html();
|
||||
};
|
||||
|
||||
/**
|
||||
* `{{ }}` => `<span>{{</span> <span>}}</span>`
|
||||
* @param {string} str
|
||||
* @return {string}
|
||||
*/
|
||||
const replaceDelimiters = function(str) {
|
||||
return str.replace(/({{|}})/g, '<span>$1</span>');
|
||||
};
|
||||
|
||||
/**
|
||||
* renderHighlight
|
||||
* @param {string} str
|
||||
* @param {string} lang
|
||||
*/
|
||||
|
||||
const renderHighlight = function(str, lang) {
|
||||
if (!(lang && Prism.languages[lang])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
return replaceDelimiters(Prism.highlight(str, Prism.languages[lang], lang));
|
||||
} catch (err) {}
|
||||
};
|
||||
|
||||
const md = require('markdown-it')('default', {
|
||||
html: true,
|
||||
breaks: true,
|
||||
highlight: renderHighlight,
|
||||
}).use(require('markdown-it-anchor'), {
|
||||
level: 2,
|
||||
slugify: string =>
|
||||
string
|
||||
.trim()
|
||||
.split(' ')
|
||||
.join('-'),
|
||||
permalink: true,
|
||||
// renderPermalink: (slug, opts, state, permalink) => {},
|
||||
permalinkClass: 'anchor',
|
||||
permalinkSymbol: '#',
|
||||
permalinkBefore: false,
|
||||
});
|
||||
// md.renderer.rules.fence = wrap(md.renderer.rules.fence)
|
||||
const cnReg = new RegExp('<(cn)(?:[^<]|<)+</\\1>', 'g');
|
||||
const usReg = new RegExp('<(us)(?:[^<]|<)+</\\1>', 'g');
|
||||
md.core.ruler.push('update_template', function replace({ tokens }) {
|
||||
let cn = '';
|
||||
let us = '';
|
||||
let template = '';
|
||||
let script = '';
|
||||
let style = '';
|
||||
let scopedStyle = '';
|
||||
let code = '';
|
||||
let sourceCode = '';
|
||||
tokens.forEach(token => {
|
||||
if (token.type === 'html_block') {
|
||||
if (token.content.match(cnReg)) {
|
||||
cn = fetch(token.content, 'cn');
|
||||
token.content = '';
|
||||
}
|
||||
if (token.content.match(usReg)) {
|
||||
us = fetch(token.content, 'us');
|
||||
token.content = '';
|
||||
}
|
||||
}
|
||||
if (token.type === 'fence' && token.info === 'vue' && token.markup === '```') {
|
||||
sourceCode = token.content;
|
||||
code = '```html\n' + token.content + '```';
|
||||
template = fetch(token.content, 'template');
|
||||
script = fetch(token.content, 'script');
|
||||
style = fetch(token.content, 'style');
|
||||
scopedStyle = fetch(token.content, 'style', true);
|
||||
token.content = '';
|
||||
token.type = 'html_block';
|
||||
}
|
||||
});
|
||||
if (template) {
|
||||
let jsfiddle = {
|
||||
us,
|
||||
cn,
|
||||
sourceCode: Buffer.from(sourceCode).toString('base64'),
|
||||
};
|
||||
jsfiddle = md.utils.escapeHtml(JSON.stringify(jsfiddle));
|
||||
const codeHtml = code ? md.render(code.replace(/@/g, '__at__')).replace(/__at__/g, '@') : '';
|
||||
const cnHtml = cn ? md.render(cn) : '';
|
||||
let newContent = `
|
||||
<template>
|
||||
<demo-box :jsfiddle="${jsfiddle}">
|
||||
<template slot="component">${template}</template>
|
||||
<template slot="description">${cnHtml}</template>
|
||||
<template slot="us-description">${us ? md.render(us) : ''}</template>
|
||||
<template slot="code">${Buffer.from(codeHtml).toString('base64')}</template>
|
||||
</demo-box>
|
||||
</template>`;
|
||||
newContent += script
|
||||
? `
|
||||
<script>
|
||||
${script || ''}
|
||||
</script>
|
||||
`
|
||||
: '';
|
||||
newContent += style ? `<style>${style || ''}</style>` : '';
|
||||
newContent += scopedStyle ? `<style scoped>${scopedStyle || ''}</style>` : '';
|
||||
const t = new Token('html_block', '', 0);
|
||||
t.content = newContent;
|
||||
tokens.push(t);
|
||||
}
|
||||
});
|
||||
const vueLoaderOptions = {
|
||||
loaders: {
|
||||
js: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['env'],
|
||||
plugins: ['transform-vue-jsx', 'transform-object-rest-spread'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: {
|
||||
index: [`./site/${process.env.ENTRY_INDEX || 'index'}.js`],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.md$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderOptions,
|
||||
},
|
||||
{
|
||||
loader: 'vue-antd-md-loader',
|
||||
options: Object.assign(md, {
|
||||
wrapper: 'div',
|
||||
raw: true,
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderOptions,
|
||||
},
|
||||
{
|
||||
test: /\.(js|jsx)$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/,
|
||||
options: babelConfig,
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|gif|svg)$/,
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]?[hash]',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve:
|
||||
process.env.NODE_ENV === 'development'
|
||||
? {
|
||||
modules: ['node_modules', path.join(__dirname, '../node_modules')],
|
||||
extensions: ['.js', '.jsx', '.vue', '.md'],
|
||||
alias: {
|
||||
vue$: 'vue/dist/vue.esm.js',
|
||||
'ant-design-vue$': path.join(__dirname, '../../components/index.js'),
|
||||
'ant-design-vue/es': path.join(__dirname, '../../components'),
|
||||
'ant-design-vue/lib': path.join(__dirname, '../../components'),
|
||||
},
|
||||
}
|
||||
: {
|
||||
modules: ['node_modules'],
|
||||
extensions: ['.js', '.jsx', '.vue', '.md'],
|
||||
alias: {
|
||||
vue$: 'vue/dist/vue.esm.js',
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
new VueLoaderPlugin(),
|
||||
new WebpackBar(),
|
||||
new HardSourceWebpackPlugin(),
|
||||
],
|
||||
};
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const merge = require('webpack-merge');
|
||||
const baseWebpackConfig = require('./webpack.base.conf');
|
||||
const lessLoaderConfig = require('./lessLoaderConfig');
|
||||
const { createMockMiddleware } = require('umi-mock-middleware');
|
||||
|
||||
module.exports = merge(baseWebpackConfig, {
|
||||
mode: 'development',
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../dist'),
|
||||
publicPath: '/',
|
||||
filename: 'build.js',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['vue-style-loader', 'css-loader'],
|
||||
},
|
||||
lessLoaderConfig('development'),
|
||||
],
|
||||
},
|
||||
devServer: {
|
||||
port: process.env.PORT || 3000,
|
||||
host: '0.0.0.0',
|
||||
historyApiFallback: {
|
||||
rewrites: [{ from: /./, to: '/index.html' }],
|
||||
},
|
||||
disableHostCheck: true,
|
||||
hot: true,
|
||||
open: true,
|
||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||
// 解析body,对接真实服务端环境需要注释掉
|
||||
before(app) {
|
||||
// var bodyParser = require("body-parser");
|
||||
// app.use(bodyParser.json());
|
||||
if (process.env.MOCK !== 'none') {
|
||||
app.use(createMockMiddleware());
|
||||
}
|
||||
},
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:3000',
|
||||
},
|
||||
},
|
||||
},
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
devtool: '#source-map',
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'public/index.html',
|
||||
filename: 'index.html',
|
||||
inject: true,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const TerserJSPlugin = require('terser-webpack-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const merge = require('webpack-merge');
|
||||
const baseWebpackConfig = require('./webpack.base.conf');
|
||||
let lessLoaderConfig = require('./lessLoaderConfig')('production');
|
||||
|
||||
module.exports = merge(baseWebpackConfig, {
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../_site'),
|
||||
publicPath: '/',
|
||||
filename: '[name].[contenthash:8].js',
|
||||
chunkFilename: '[contenthash:8].async.js',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
lessLoaderConfig,
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
name: `chunk-vendors`,
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: -10,
|
||||
chunks: 'initial',
|
||||
},
|
||||
common: {
|
||||
name: `chunk-common`,
|
||||
minChunks: 2,
|
||||
priority: -20,
|
||||
chunks: 'initial',
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"',
|
||||
},
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: './public/index.html',
|
||||
inject: true,
|
||||
production: true,
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].[contenthash:8].css',
|
||||
chunkFilename: '[id].[contenthash:8].css',
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
|
@ -1,6 +1,3 @@
|
|||
<template>
|
||||
<div id="carbon-ads" :class="isMobile ? 'carbon-mobile' : ''" />
|
||||
</template>
|
||||
<script>
|
||||
const carbonUrls = {
|
||||
'www.antdv.com': '//cdn.carbonads.com/carbon.js?serve=CK7DL2JW&placement=antdvcom',
|
||||
|
|
@ -19,7 +16,7 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
$route(e, t) {
|
||||
const adId = '#carbonads';
|
||||
let adId = '#carbonads';
|
||||
// if(isGitee) {
|
||||
// adId = '#cf';
|
||||
// }
|
||||
|
|
@ -55,6 +52,9 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return <div id="carbon-ads" class={this.isMobile ? 'carbon-mobile' : ''} />;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="less">
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div class="google-ads" id="API">
|
||||
<ins
|
||||
ref="ins"
|
||||
class="adsbygoogle"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="7647023136"
|
||||
style="display: inline-block; width: 728px; height: 90px"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div class="google-ads" id="api">
|
||||
<ins
|
||||
ref="ins"
|
||||
style="display:block"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="3952358732"
|
||||
data-ad-format="auto"
|
||||
data-full-width-responsive="true"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div class="google-ads">
|
||||
<ins
|
||||
ref="ins"
|
||||
style="display:block"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="9507921838"
|
||||
data-ad-format="auto"
|
||||
data-full-width-responsive="true"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div style="width: 300px;float: right;margin-top: 75px;position: relative;right: 0;bottom: 0;padding: 0;z-index: 9;">
|
||||
<ins
|
||||
ref="ins"
|
||||
class="adsbygoogle"
|
||||
style="display:inline-block;width:300px;height:100px"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="2774992529"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div class="google-ads">
|
||||
<ins
|
||||
ref="ins"
|
||||
class="adsbygoogle"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="2425414214"
|
||||
style="display: inline-block; width: 728px; height: 90px"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -1,14 +1,12 @@
|
|||
<template>
|
||||
<div id="rice">
|
||||
<div class="wwads-cn wwads-horizontal" data-id="62" style="max-width: 350px"></div>
|
||||
<div class="wwads-cn wwads-horizontal" data-id="62" style="max-width: 350px" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
export default {
|
||||
// mounted() {
|
||||
// // this.load();
|
||||
// this.load();
|
||||
// },
|
||||
// methods: {
|
||||
// load() {
|
||||
|
|
@ -23,7 +21,7 @@ export default defineComponent({
|
|||
// this.scriptDom = e;
|
||||
// },
|
||||
// },
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
#rice {
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<template>
|
||||
<div class="markdown api-container">
|
||||
<slot v-if="isZhCN" name="cn" />
|
||||
<slot v-else />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { isZhCN } from '../utils/util';
|
||||
import GoogleAds from './GoogleAds';
|
||||
|
||||
const showAd = false; // location.host.indexOf('antdv.com') > -1;
|
||||
export default {
|
||||
name: 'Api',
|
||||
components: {
|
||||
GoogleAds,
|
||||
},
|
||||
inject: {
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAd,
|
||||
isZhCN: isZhCN(this.demoContext.name),
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
<template>
|
||||
<section :id="id" :class="['code-box', codeExpand ? 'expand' : '']">
|
||||
<section class="code-box-demo">
|
||||
<template v-if="iframeDemo[iframeDemoKey]">
|
||||
<div class="browser-mockup with-url">
|
||||
<iframe :src="iframeDemo[iframeDemoKey]" height="360" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<slot name="component" />
|
||||
</template>
|
||||
</section>
|
||||
<section class="code-box-meta markdown">
|
||||
<slot v-if="isZhCN" name="description" />
|
||||
<slot v-else name="us-description" />
|
||||
<div class="code-box-actions">
|
||||
<a-tooltip
|
||||
:title="copied ? 'Copied!' : 'Copy code'"
|
||||
:visible="copyTooltipVisible"
|
||||
@visibleChange="onCopyTooltipVisibleChange"
|
||||
>
|
||||
<a-icon
|
||||
v-clipboard:copy="sourceCode"
|
||||
v-clipboard:success="handleCodeCopied"
|
||||
:type="copied && copyTooltipVisible ? 'check' : 'copy'"
|
||||
class="code-box-code-copy"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="codeExpand ? 'Hide Code' : 'Show Code'">
|
||||
<span class="code-expand-icon">
|
||||
<img
|
||||
width="16"
|
||||
alt="expand code"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg"
|
||||
:class="codeExpand ? 'code-expand-icon-hide' : 'code-expand-icon-show'"
|
||||
@click="handleCodeExpand"
|
||||
/>
|
||||
<img
|
||||
width="16"
|
||||
alt="expand code"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/OpROPHYqWmrMDBFMZtKF.svg"
|
||||
:class="codeExpand ? 'code-expand-icon-show' : 'code-expand-icon-hide'"
|
||||
@click="handleCodeExpand"
|
||||
/>
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</section>
|
||||
<transition appear :css="false" @enter="enter" @leave="leave">
|
||||
<section
|
||||
v-show="codeExpand"
|
||||
class="highlight-wrapper"
|
||||
style="position: relative;"
|
||||
v-html="getCode()"
|
||||
/>
|
||||
</transition>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import animate from 'ant-design-vue/es/_util/openAnimation';
|
||||
import BaseMixin from 'ant-design-vue/es/_util/BaseMixin';
|
||||
import { isZhCN } from '../utils/util';
|
||||
import { dev } from '../build/config';
|
||||
export default {
|
||||
name: 'DemoBox',
|
||||
mixins: [BaseMixin],
|
||||
inject: {
|
||||
iframeDemo: { default: {} },
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
props: {
|
||||
jsfiddle: Object,
|
||||
isIframe: Boolean,
|
||||
},
|
||||
data() {
|
||||
window.test = this;
|
||||
const { name = '' } = this.demoContext;
|
||||
const { us, cn, sourceCode } = this.jsfiddle;
|
||||
const usTitle = (us.split('#### ')[1] || '').split('\n')[0] || '';
|
||||
const cnTitle = (cn.split('#### ')[1] || '').split('\n')[0] || '';
|
||||
if (process.env.NODE_ENV !== 'production' && usTitle === '') {
|
||||
throw new Error(`not have usTitle`);
|
||||
}
|
||||
const iframeDemoKey = usTitle
|
||||
.split(' ')
|
||||
.join('-')
|
||||
.toLowerCase();
|
||||
const id = [
|
||||
'components',
|
||||
name.replace(/-cn\/?$/, '') || dev.componentName,
|
||||
'demo',
|
||||
...usTitle.split(' '),
|
||||
]
|
||||
.join('-')
|
||||
.toLowerCase();
|
||||
|
||||
if (this.demoContext.store) {
|
||||
const { currentSubMenu } = this.demoContext.store.getState();
|
||||
this.demoContext.store.setState({
|
||||
currentSubMenu: [...currentSubMenu, { cnTitle, usTitle, id }],
|
||||
});
|
||||
}
|
||||
return {
|
||||
codeExpand: false,
|
||||
isZhCN: isZhCN(name),
|
||||
copied: false,
|
||||
copyTooltipVisible: false,
|
||||
sourceCode: decodeURIComponent(escape(window.atob(sourceCode))),
|
||||
id,
|
||||
iframeDemoKey,
|
||||
isDemo: true,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getCode() {
|
||||
const { $slots } = this;
|
||||
return decodeURIComponent(
|
||||
escape(window.atob(($slots.code && $slots.code[0] && $slots.code[0].text) || '')),
|
||||
);
|
||||
},
|
||||
handleCodeExpand() {
|
||||
this.codeExpand = !this.codeExpand;
|
||||
},
|
||||
enter: animate.enter,
|
||||
leave: animate.leave,
|
||||
handleCodeCopied() {
|
||||
this.setState({ copied: true });
|
||||
},
|
||||
|
||||
onCopyTooltipVisibleChange(visible) {
|
||||
if (visible) {
|
||||
this.setState({
|
||||
copyTooltipVisible: visible,
|
||||
copied: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
copyTooltipVisible: visible,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.box-demo {
|
||||
padding: 0;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.box-demo-show {
|
||||
padding: 20px 25px 30px;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
}
|
||||
.box-demo-description {
|
||||
position: relative;
|
||||
padding: 17px 16px 15px 20px;
|
||||
border-radius: 0 0 6px 6px;
|
||||
-webkit-transition: background-color 0.4s ease;
|
||||
transition: background-color 0.4s ease;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
&.bordered {
|
||||
border-bottom: 1px dashed #e9e9e9;
|
||||
}
|
||||
h3,
|
||||
h4 {
|
||||
position: absolute;
|
||||
top: -14px;
|
||||
padding: 1px 8px;
|
||||
margin-left: -8px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
color: #777;
|
||||
border-radius: 4px;
|
||||
border-top-left-radius: 0;
|
||||
background: #fff;
|
||||
-webkit-transition: background-color 0.4s ease;
|
||||
transition: background-color 0.4s ease;
|
||||
.header-anchor {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
li {
|
||||
line-height: 21px;
|
||||
}
|
||||
}
|
||||
.box-demo-code {
|
||||
-webkit-transition: height 0.2s ease-in-out;
|
||||
transition: height 0.2s ease-in-out;
|
||||
overflow: auto;
|
||||
border-top: 1px dashed #e9e9e9;
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
code {
|
||||
margin: 0;
|
||||
background: #f7f7f7;
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 3px;
|
||||
font-size: 0.9em;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
.btn-toggle {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
bottom: 17px;
|
||||
cursor: pointer;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
color: #999;
|
||||
i {
|
||||
-webkit-transition: all 0.3s;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
&.open {
|
||||
i {
|
||||
-webkit-transform: rotate(-180deg);
|
||||
-ms-transform: rotate(-180deg);
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
<template>
|
||||
<div>
|
||||
<demo-box :jsfiddle="jsfiddle">
|
||||
<template #component>
|
||||
<template slot="component">
|
||||
<slot />
|
||||
</template>
|
||||
<template #description>
|
||||
<template slot="description">
|
||||
<div class="demo-description" v-html="cnHtml" />
|
||||
</template>
|
||||
<template #us-description>
|
||||
<template slot="us-description">
|
||||
<div class="demo-description" v-html="usHtml" />
|
||||
</template>
|
||||
<template #code>
|
||||
<template slot="code">
|
||||
{{ codeStr }}
|
||||
</template>
|
||||
</demo-box>
|
||||
|
|
@ -20,12 +20,12 @@
|
|||
<script>
|
||||
import marked from 'marked';
|
||||
import Prism from 'prismjs';
|
||||
// import 'prismjs/components/prism-jsx.min.js';
|
||||
// import 'prismjs/components/prism-bash.min.js';
|
||||
const replaceDelimiters = function (str) {
|
||||
import 'prismjs/components/prism-jsx.min.js';
|
||||
import 'prismjs/components/prism-bash.min.js';
|
||||
const replaceDelimiters = function(str) {
|
||||
return str.replace(/({{|}})/g, '<span>$1</span>');
|
||||
};
|
||||
const renderHighlight = function (str, lang) {
|
||||
const renderHighlight = function(str, lang) {
|
||||
if (!(lang && Prism.languages[lang])) {
|
||||
return '';
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ const renderHighlight = function (str, lang) {
|
|||
} catch (err) {}
|
||||
};
|
||||
const renderer = new marked.Renderer();
|
||||
renderer.heading = function (text, level) {
|
||||
renderer.heading = function(text, level) {
|
||||
return (
|
||||
'<h' + level + ' id="' + text.replace(/[^\w]+/g, '-') + '">' + text + '</h' + level + '>\n'
|
||||
);
|
||||
|
|
@ -62,7 +62,10 @@ export default {
|
|||
const us = this.code.match(usReg) || [];
|
||||
const cnHtml = marked(cn[1].trim());
|
||||
const usHtml = marked(us[1].trim());
|
||||
const sourceCode = this.code.replace(cn[0], '').replace(us[0], '').trim();
|
||||
const sourceCode = this.code
|
||||
.replace(cn[0], '')
|
||||
.replace(us[0], '')
|
||||
.trim();
|
||||
const codeHtml = marked('```html\n' + sourceCode + '```');
|
||||
return {
|
||||
codeStr: window.btoa(unescape(encodeURIComponent(codeHtml))),
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import { Col, Row } from '../../components/grid';
|
||||
import '../../components/grid/style';
|
||||
function isEmptyElement(c) {
|
||||
return !(c.tag || (c.text && c.text.trim() !== ''));
|
||||
}
|
||||
|
||||
function filterEmpty(children = []) {
|
||||
return children.filter(c => !isEmptyElement(c));
|
||||
}
|
||||
export default {
|
||||
props: {
|
||||
cols: {
|
||||
type: [Number, String],
|
||||
default: 2,
|
||||
},
|
||||
},
|
||||
inject: {
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
render() {
|
||||
const { cols, $slots } = this;
|
||||
const isSingleCol = cols === 1;
|
||||
const leftChildren = [];
|
||||
const rightChildren = [];
|
||||
const children = filterEmpty($slots.default);
|
||||
children.forEach((demo, index) => {
|
||||
if (index % 2 === 0 || isSingleCol) {
|
||||
leftChildren.push(demo);
|
||||
} else {
|
||||
rightChildren.push(demo);
|
||||
}
|
||||
});
|
||||
return (
|
||||
<Row gutter={16}>
|
||||
<Col
|
||||
span={isSingleCol ? 24 : 12}
|
||||
class={isSingleCol ? 'code-boxes-col-1-1' : 'code-boxes-col-2-1'}
|
||||
>
|
||||
{leftChildren}
|
||||
</Col>
|
||||
{isSingleCol ? null : (
|
||||
<Col class="code-boxes-col-2-1" span={12}>
|
||||
{rightChildren}
|
||||
</Col>
|
||||
)}
|
||||
</Row>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
<script>
|
||||
import moment from 'moment';
|
||||
export default {
|
||||
props: {
|
||||
isCN: Boolean,
|
||||
},
|
||||
render() {
|
||||
const isCN = this.isCN;
|
||||
const showJeecg = moment().isBefore(moment('2023-09-10'));
|
||||
return (
|
||||
<footer id="footer">
|
||||
<div class="footer-wrap">
|
||||
<a-row>
|
||||
<a-col md={6} sm={24} xs={24}>
|
||||
<div class="footer-center">
|
||||
<h2>Ant Design</h2>
|
||||
<div>
|
||||
<a href="https://github.com/vueComponent/ant-design-vue" target="_blank ">
|
||||
<span>GitHub</span>
|
||||
</a>
|
||||
<span></span>
|
||||
<span>
|
||||
<i class="anticon anticon-github"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://ant.design/docs/react/introduce-cn" target="_blank">
|
||||
Ant Design
|
||||
</a>
|
||||
<span> - </span>
|
||||
<span>React</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://github.com/NG-ZORRO/ng-zorro-antd" target="_blank">
|
||||
Ant Design
|
||||
</a>
|
||||
<span> - </span>
|
||||
<span>Angular</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://github.com/websemantics/awesome-ant-design" target="_blank ">
|
||||
<span>Awesome Ant Design</span>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://library.ant.design/" rel="noopener noreferrer" target="_blank">
|
||||
AntD Library
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col md={6} sm={24} xs={24}>
|
||||
<div class="footer-center">
|
||||
<h2>{isCN ? '社区' : 'Community'}</h2>
|
||||
{isCN ? (
|
||||
<div>
|
||||
<a href="https://zhuanlan.zhihu.com/ant-design-vue" target="_blank">
|
||||
<span>知乎专栏</span>
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<div>
|
||||
<a href="https://github.com/vueComponent/ant-design-vue/releases" target="_blank">
|
||||
<span>{isCN ? '更新记录' : 'Change Log'}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href={`https://vuecomponent.github.io/issue-helper/${isCN ? '?lang=zh' : ''}`}
|
||||
>
|
||||
<span>{isCN ? '报告 Bug' : 'Bug Report'}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col md={6} sm={24} xs={24}>
|
||||
<div class="footer-center">
|
||||
<h2>{isCN ? '友情链接' : 'Links'}</h2>
|
||||
{showJeecg && (
|
||||
<div>
|
||||
<a href="http://www.jeecg.com/" target="_blank">
|
||||
Jeecg
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<a href="https://cn.vuejs.org/" target="_blank">
|
||||
Vue
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://cli.vuejs.org/" target="_blank">
|
||||
Vue CLI
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://antdv.formilyjs.org/" target="_blank">
|
||||
@formily/antdv
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col md={6} sm={24} xs={24}>
|
||||
<div class="footer-center">
|
||||
<h2>
|
||||
<img
|
||||
alt=""
|
||||
class="title-icon"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/nBVXkrFdWHxbZlmMbsaH.svg"
|
||||
/>
|
||||
<span>{isCN ? '更多产品' : 'More Products'}</span>
|
||||
</h2>
|
||||
<div>
|
||||
<a href="https://antv.alipay.com/" rel="noopener noreferrer" target="_blank">
|
||||
AntV
|
||||
</a>
|
||||
<span> - </span>
|
||||
<span>{isCN ? '数据可视化' : 'Data Visualization'}</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://eggjs.org/" rel="noopener noreferrer" target="_blank">
|
||||
Egg
|
||||
</a>
|
||||
<span> - </span>
|
||||
<span>{isCN ? '企业级 Node 开发框架' : 'Enterprise Node Framework'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div style="padding: 10px 144px;">
|
||||
备案号:
|
||||
<a href="http://beian.miit.gov.cn/" target="_blank">
|
||||
浙ICP备19034671号
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<div v-show="visible" id="geektime">
|
||||
<a
|
||||
href="https://time.geekbang.org/course/intro/100024601?code=KHKYcoBU6vZa8nMglg7AWfDxxi3BWrz9INAzAY3umPk%3D"
|
||||
target="_blank"
|
||||
>
|
||||
<img width="150" alt="Vue 实战教程" src="https://qn.antdv.com/geektime-vue.jpeg" />
|
||||
</a>
|
||||
<div class="close" @click="visible = false">
|
||||
<a-icon type="close" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['isMobile'],
|
||||
data() {
|
||||
return {
|
||||
visible: true,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#geektime {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
.close {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
font-size: 16px;
|
||||
padding: 15px;
|
||||
color: #6e3041;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="isEffective(effectiveTime)"
|
||||
id="geektime-ads"
|
||||
:class="isMobile ? 'geektime-ads-mobile' : ''"
|
||||
>
|
||||
<a
|
||||
href="https://time.geekbang.org/column/intro/154?utm_term=zeusGZFFE&utm_source=app&utm_medium=tangjinzhou"
|
||||
target="_blank"
|
||||
>
|
||||
<img height="100" alt="重学前端" src="https://qn.antdv.com/chongxueqianduan.jpg" />
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
export default {
|
||||
props: ['isMobile'],
|
||||
data() {
|
||||
return {
|
||||
visible: true,
|
||||
effectiveTime: {
|
||||
start: '2019-08-05 17:00:00',
|
||||
end: '2019-09-05 17:00:00',
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isEffective({ start, end }) {
|
||||
return moment().isBetween(start, end);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#geektime-ads {
|
||||
width: 266px;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
z-index: 9;
|
||||
background-color: #fff;
|
||||
border-radius: 3px;
|
||||
font-size: 13px;
|
||||
background: #f5f5f5;
|
||||
font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
#geektime-ads.geektime-ads-mobile {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
<script>
|
||||
import { isZhCN } from '../utils/util';
|
||||
import docsearch from 'docsearch.js';
|
||||
import packageInfo from '../../package.json';
|
||||
import logo from '../public/logo.svg';
|
||||
import antDesignVue from '../public/ant-design-vue.svg';
|
||||
|
||||
export default {
|
||||
inject: {
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
props: {
|
||||
name: String,
|
||||
searchData: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visibleAdblockBanner: !!this.demoContext.blocked,
|
||||
value: null,
|
||||
showTopBanner: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'demoContex.blocked': function blocked(val) {
|
||||
this.visibleAdblockBanner = !!val;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.initDocSearch(this.$i18n.locale);
|
||||
},
|
||||
methods: {
|
||||
handleClose(key) {
|
||||
localStorage.removeItem(`notification-key-${key}`);
|
||||
localStorage.setItem(`notification-key-${key}`, true);
|
||||
this.showTopBanner = false;
|
||||
},
|
||||
initDocSearch(locale) {
|
||||
docsearch({
|
||||
apiKey: '92003c1d1d07beef165b08446f4224a3',
|
||||
indexName: 'antdv',
|
||||
inputSelector: '#search-box input',
|
||||
algoliaOptions: { facetFilters: [isZhCN(locale) ? 'cn' : 'en'] },
|
||||
transformData(hits) {
|
||||
hits.forEach(hit => {
|
||||
hit.url = hit.url.replace('www.antdv.com', window.location.host);
|
||||
hit.url = hit.url.replace('https:', window.location.protocol);
|
||||
});
|
||||
return hits;
|
||||
},
|
||||
debug: false, // Set debug to true if you want to inspect the dropdown
|
||||
});
|
||||
},
|
||||
handleClick() {
|
||||
const name = this.name;
|
||||
const path = this.$route.path;
|
||||
const newName = isZhCN(name) ? name.replace(/-cn\/?$/, '') : `${name}-cn`;
|
||||
this.$router.push({
|
||||
path: path.replace(name, newName),
|
||||
});
|
||||
this.$i18n.locale = isZhCN(name) ? 'en-US' : 'zh-CN';
|
||||
},
|
||||
onSelect(val) {
|
||||
this.$router.push(val);
|
||||
this.value = val;
|
||||
},
|
||||
closeTopBanner() {},
|
||||
changeVersion(v) {
|
||||
location.href = `https://${v}.antdv.com${this.$route.fullPath}`;
|
||||
},
|
||||
},
|
||||
render() {
|
||||
const name = this.name;
|
||||
const visibleAdblockBanner = false; // this.visibleAdblockBanner;
|
||||
const isCN = isZhCN(name);
|
||||
const path = this.$route.path;
|
||||
const selectedKeys = path === '/jobs/list-cn' ? ['jobs'] : ['components'];
|
||||
return (
|
||||
<header id="header">
|
||||
{visibleAdblockBanner && (
|
||||
<div class="adblock-banner">
|
||||
{isZhCN
|
||||
? '我们检测到你可能使用了 AdBlock 或 Adblock Plus,它会影响到正常功能的使用(如复制、展开代码等)。'
|
||||
: 'We have detected that you may use AdBlock or Adblock Plus, which will affect the use of normal functions (such as copying, expanding code, etc.)'}
|
||||
<br />
|
||||
{isZhCN
|
||||
? '你可以将 Ant Design Vue 加入白名单,以便我们更好地提供服务。'
|
||||
: 'You can add Ant Design Vue to the whitelist so that we can provide better services.'}
|
||||
|
||||
<CloseOutlined class="close-icon" onClick={() => (this.visibleAdblockBanner = false)} />
|
||||
</div>
|
||||
)}
|
||||
{/* {!isCN && this.showTopBanner && (
|
||||
<div class="global-notification">
|
||||
<span>
|
||||
v3 beta is out! Discover more about it on
|
||||
<a href="https://next.antdv.com/" target="_blank">
|
||||
next.antdv.com
|
||||
</a>
|
||||
|
||||
</span>
|
||||
<a-icon
|
||||
type="close"
|
||||
style="position: absolute;top: 8px;right: 15px;"
|
||||
onClick={() => this.handleClose('next')}
|
||||
/>
|
||||
</div>
|
||||
)} */}
|
||||
<a-row>
|
||||
<a-col class="header-left" xxl={4} xl={5} lg={5} md={6} sm={24} xs={24}>
|
||||
<router-link to={{ path: '/' }} id="logo">
|
||||
<img alt="logo" height="32" src={logo} />
|
||||
<img alt="logo" height="16" src={antDesignVue} />
|
||||
</router-link>
|
||||
<a-button
|
||||
ghost
|
||||
size="small"
|
||||
onClick={this.handleClick}
|
||||
class="header-lang-button"
|
||||
key="lang-button"
|
||||
>
|
||||
{isCN ? 'English' : '中文'}
|
||||
</a-button>
|
||||
</a-col>
|
||||
<a-col xxl={20} xl={19} lg={19} md={18} sm={0} xs={0}>
|
||||
<div id="search-box">
|
||||
<a-icon type="search" />
|
||||
<a-input
|
||||
placeholder={isCN ? '搜索组件...' : 'input search text'}
|
||||
style="width: 200px"
|
||||
/>
|
||||
</div>
|
||||
<span id="github-btn" class="github-btn">
|
||||
<a class="gh-btn" href="//github.com/vueComponent/ant-design-vue/" target="_blank">
|
||||
<span class="gh-ico" aria-hidden="true"></span>
|
||||
<span class="gh-text">Star</span>
|
||||
</a>
|
||||
</span>
|
||||
<a-button
|
||||
ghost
|
||||
size="small"
|
||||
onClick={this.handleClick}
|
||||
class="header-lang-button"
|
||||
key="lang-button"
|
||||
>
|
||||
{isCN ? 'English' : '中文'}
|
||||
</a-button>
|
||||
<a-select size="small" defaultValue={packageInfo.version} class="version">
|
||||
<a-select-option value={packageInfo.version}>{packageInfo.version}</a-select-option>
|
||||
<a-select-option value="2.x" onClick={() => this.changeVersion('2x')}>
|
||||
v2 LST
|
||||
</a-select-option>
|
||||
<a-select-option value="www" onClick={() => this.changeVersion('www')}>
|
||||
v3 Current (Latest Features)
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-menu selectedKeys={selectedKeys} mode="horizontal" class="menu-site" id="nav">
|
||||
<a-menu-item key="components">
|
||||
<router-link to="/docs/vue/introduce">{isCN ? '组件' : 'Components'}</router-link>
|
||||
</a-menu-item>
|
||||
<a-sub-menu
|
||||
v-if="isZhCN"
|
||||
key="advanced"
|
||||
title={
|
||||
<span style="position: relative">
|
||||
高级组件
|
||||
<a-badge color="red" style="position: absolute; top: -35px; right: -15px" />
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<a-menu-item key="surely-table">
|
||||
<a
|
||||
href="https://www.surely.cool"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style="position: relative;"
|
||||
>
|
||||
Surely Table
|
||||
</a>
|
||||
</a-menu-item>
|
||||
</a-sub-menu>
|
||||
{isCN ? (
|
||||
<a-menu-item key="store">
|
||||
<a
|
||||
href="https://store.antdv.com/pro/"
|
||||
target="_blank"
|
||||
style="position: relative;"
|
||||
>
|
||||
商店
|
||||
</a>
|
||||
</a-menu-item>
|
||||
) : (
|
||||
<a-menu-item key="store">
|
||||
<a
|
||||
href="https://store.antdv.com/pro/?lang=en"
|
||||
target="_blank"
|
||||
style="position: relative;"
|
||||
>
|
||||
Store{' '}
|
||||
</a>
|
||||
</a-menu-item>
|
||||
)}
|
||||
{isCN ? (
|
||||
<a-menu-item key="geektime">
|
||||
<a
|
||||
href="https://time.geekbang.org/course/intro/100024601?code=KHKYcoBU6vZa8nMglg7AWfDxxi3BWrz9INAzAY3umPk%3D"
|
||||
target="_blank"
|
||||
style="position: relative;"
|
||||
>
|
||||
Vue 实战教程
|
||||
</a>
|
||||
</a-menu-item>
|
||||
) : null}
|
||||
<a-menu-item key="sponsor">
|
||||
<router-link to={{ path: isCN ? '/docs/vue/sponsor-cn/' : '/docs/vue/sponsor/' }}>
|
||||
{isCN ? '支持我们' : 'Support us'}
|
||||
</router-link>
|
||||
</a-menu-item>
|
||||
<a-sub-menu key="Ecosystem" title={isCN ? '更多' : 'More'}>
|
||||
<a-menu-item key="pro">
|
||||
<a target="_blank" href="https://pro.antdv.com">
|
||||
Pro (Admin)
|
||||
</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="vip">
|
||||
<a target="_blank" href="https://store.antdv.com/pro/">
|
||||
Pro For VIP
|
||||
</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="design">
|
||||
<router-link
|
||||
to={{ path: isCN ? '/docs/vue/download-cn/' : '/docs/vue/download/' }}
|
||||
>
|
||||
{isCN ? '设计资源' : 'Design Resources'}
|
||||
</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="vscode">
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper"
|
||||
>
|
||||
VS Code Extension
|
||||
</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="awesome">
|
||||
<a target="_blank" href="https://github.com/vueComponent/ant-design-vue-awesome">
|
||||
Awesome
|
||||
</a>
|
||||
</a-menu-item>
|
||||
|
||||
<a-menu-item key="qq1">
|
||||
<a>QQ 1群(217490093) 已满</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="qq2">
|
||||
<a>QQ 2群(809774695) 已满</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="qq3">
|
||||
<a>QQ 3群(927828249)</a>
|
||||
</a-menu-item>
|
||||
</a-sub-menu>
|
||||
</a-menu>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</header>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scope>
|
||||
.adblock-banner {
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
min-width: 1000px;
|
||||
padding: 16px;
|
||||
line-height: 28px;
|
||||
color: #8590a6;
|
||||
text-align: center;
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
.global-notification {
|
||||
text-align: center;
|
||||
background: #001529;
|
||||
padding: 20px 0;
|
||||
font-size: 16px;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
z-index: 99;
|
||||
}
|
||||
.global-notification a {
|
||||
color: #177ddc;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<script>
|
||||
// import * as AllDemo from '../demo'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
name: String,
|
||||
hash: String,
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
demoContext: this,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
// const name = this.name
|
||||
// const titleMap = {}
|
||||
// for (const [title] of Object.entries(AllDemo)) {
|
||||
// const key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`
|
||||
// titleMap[key] = title
|
||||
// }
|
||||
// const Demo = AllDemo[titleMap[name.replace(/-cn\/?$/, '')]]
|
||||
// const hash = this.$route.hash.replace('#', '')
|
||||
return (
|
||||
<div id="iframe-page">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
<script>
|
||||
import { enquireScreen } from 'enquire-js';
|
||||
import AllDemo from '../site/demo';
|
||||
import Header from './header';
|
||||
import Footer from './footer';
|
||||
// import Geektime from './geektime';
|
||||
import GeektimeAds from './geektime_ads';
|
||||
import RightBottomAd from './right_bottom_ad';
|
||||
// import Sponsors from './sponsors';
|
||||
import zhCN from 'ant-design-vue/es/locale-provider/zh_CN';
|
||||
import enUS from 'ant-design-vue/es/locale-provider/default';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import { isZhCN } from '../utils/util';
|
||||
import { Provider, create } from '../../components/_util/store';
|
||||
import NProgress from 'nprogress';
|
||||
import MobileMenu from '../../components/vc-drawer/src';
|
||||
import WWAds from './WWAds.vue';
|
||||
import GoogleAds from './GoogleAds';
|
||||
import SurelyVue from './surelyVue';
|
||||
|
||||
const docsList = [
|
||||
{ key: 'introduce', enTitle: 'Ant Design of Vue', title: 'Ant Design of Vue' },
|
||||
{ key: 'getting-started', enTitle: 'Getting Started', title: '快速上手' },
|
||||
{ key: 'use-with-vue-cli', enTitle: 'Use in vue-cli', title: '在 vue-cli 中使用' },
|
||||
{ key: 'customize-theme', enTitle: 'Customize Theme', title: '定制主题' },
|
||||
{ key: 'changelog', enTitle: 'Change Log', title: '更新日志' },
|
||||
{ key: 'i18n', enTitle: 'Internationalization', title: '国际化' },
|
||||
{ key: 'faq', enTitle: 'FAQ', title: '常见问题' },
|
||||
{ key: 'sponsor', enTitle: 'Sponsor', title: '支持我们' },
|
||||
{ key: 'download', enTitle: 'Download Design Resources', title: '下载设计资源' },
|
||||
];
|
||||
|
||||
const isGitee = window.location.host.indexOf('gitee.io') > -1;
|
||||
const showAd = false; // location.host.indexOf('antdv.com') > -1;
|
||||
|
||||
export default {
|
||||
provide() {
|
||||
return {
|
||||
demoContext: this,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
name: String,
|
||||
showDemo: Boolean,
|
||||
showApi: Boolean,
|
||||
},
|
||||
data() {
|
||||
this.store = create({
|
||||
currentSubMenu: [],
|
||||
});
|
||||
this.subscribe();
|
||||
let blocked = false;
|
||||
setTimeout(() => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'adsbox';
|
||||
document.body.appendChild(div);
|
||||
blocked = 'none' === getComputedStyle(div).display;
|
||||
}, 300);
|
||||
return {
|
||||
showSideBars: true,
|
||||
currentSubMenu: [],
|
||||
sidebarHeight: document.documentElement.offsetHeight,
|
||||
isMobile: false,
|
||||
blocked,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'$route.path'() {
|
||||
this.store.setState({ currentSubMenu: [] });
|
||||
this.addSubMenu();
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.unsubscribe) {
|
||||
this.unsubscribe();
|
||||
}
|
||||
clearTimeout(this.timer);
|
||||
if (this.resizeEvent) {
|
||||
this.resizeEvent.remove();
|
||||
}
|
||||
if (this.debouncedResize && this.debouncedResize.cancel) {
|
||||
this.debouncedResize.cancel();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (isGitee) {
|
||||
this.$info({
|
||||
title: '提示',
|
||||
content: '访问国内镜像站点的用户请访问 antdv.com 站点',
|
||||
okText: '立即跳转',
|
||||
onOk() {
|
||||
location.href = 'https://www.antdv.com';
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.addSubMenu();
|
||||
const nprogressHiddenStyle = document.getElementById('nprogress-style');
|
||||
if (nprogressHiddenStyle) {
|
||||
this.timer = setTimeout(() => {
|
||||
nprogressHiddenStyle.parentNode.removeChild(nprogressHiddenStyle);
|
||||
}, 0);
|
||||
}
|
||||
enquireScreen(b => {
|
||||
this.isMobile = !!b;
|
||||
});
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
addSubMenu() {
|
||||
if (this.$route.path.indexOf('/docs/vue/') !== -1) {
|
||||
this.$nextTick(() => {
|
||||
const menus = [];
|
||||
const doms = [...this.$refs.doc.querySelectorAll(['h2', 'h3'])];
|
||||
doms.forEach(dom => {
|
||||
const id = dom.id;
|
||||
if (id) {
|
||||
const title = dom.textContent.split('#')[0].trim();
|
||||
menus.push({ cnTitle: title, usTitle: title, id });
|
||||
}
|
||||
});
|
||||
this.currentSubMenu = menus;
|
||||
});
|
||||
}
|
||||
},
|
||||
subscribe() {
|
||||
const { store } = this;
|
||||
this.unsubscribe = store.subscribe(() => {
|
||||
this.currentSubMenu = this.store.getState().currentSubMenu;
|
||||
});
|
||||
},
|
||||
getSubMenu(isCN) {
|
||||
const currentSubMenu = this.currentSubMenu;
|
||||
const lis = [];
|
||||
currentSubMenu.forEach(({ cnTitle, usTitle, id }, index) => {
|
||||
const title = isCN ? cnTitle : usTitle;
|
||||
lis.push(<a-anchor-link key={id + index} href={`#${id}`} title={title} />);
|
||||
});
|
||||
const showApi = this.$route.path.indexOf('/components/') !== -1;
|
||||
return (
|
||||
<a-anchor offsetTop={100} class="demo-anchor">
|
||||
{lis}
|
||||
{showApi ? <a-anchor-link key="API" title="API" href="#API" /> : ''}
|
||||
</a-anchor>
|
||||
);
|
||||
},
|
||||
getDocsMenu(isCN, pagesKey) {
|
||||
const docsMenu = [];
|
||||
docsList.forEach(({ key, enTitle, title }) => {
|
||||
const k = isCN ? `${key}-cn` : key;
|
||||
pagesKey.push({ name: k, url: `/docs/vue/${k}/`, title: isCN ? title : enTitle });
|
||||
docsMenu.push(
|
||||
<a-menu-item key={k}>
|
||||
<router-link to={`/docs/vue/${k}/`}>{isCN ? title : enTitle}</router-link>
|
||||
</a-menu-item>,
|
||||
);
|
||||
});
|
||||
return docsMenu;
|
||||
},
|
||||
resetDocumentTitle(component, name, isCN) {
|
||||
let titleStr = 'Ant Design Vue';
|
||||
if (component) {
|
||||
const { subtitle, title } = component;
|
||||
const componentName = isCN ? subtitle + ' ' + title : title;
|
||||
titleStr = componentName + ' - ' + titleStr;
|
||||
} else {
|
||||
const currentKey = docsList.filter(item => {
|
||||
return item.key === name;
|
||||
});
|
||||
if (currentKey.length) {
|
||||
titleStr = (isCN ? currentKey[0]['title'] : currentKey[0]['enTitle']) + ' - ' + titleStr;
|
||||
}
|
||||
}
|
||||
document.title = titleStr;
|
||||
},
|
||||
mountedCallback() {
|
||||
NProgress.done();
|
||||
document.documentElement.scrollTop = 0;
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const name = this.name;
|
||||
const isCN = isZhCN(name);
|
||||
const titleMap = {};
|
||||
const menuConfig = {
|
||||
General: [],
|
||||
Layout: [],
|
||||
Navigation: [],
|
||||
'Data Entry': [],
|
||||
'Data Display': [],
|
||||
Feedback: [],
|
||||
Other: [],
|
||||
};
|
||||
const pagesKey = [];
|
||||
let prevPage = null;
|
||||
let nextPage = null;
|
||||
const searchData = [];
|
||||
for (const [title, d] of Object.entries(AllDemo)) {
|
||||
const type = d.type || 'Other';
|
||||
const key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`;
|
||||
titleMap[key] = title;
|
||||
AllDemo[title].key = key;
|
||||
menuConfig[type] = menuConfig[type] || [];
|
||||
menuConfig[type].push(d);
|
||||
}
|
||||
const docsMenu = this.getDocsMenu(isCN, pagesKey);
|
||||
const reName = name.replace(/-cn\/?$/, '');
|
||||
const MenuGroup = [];
|
||||
for (const [type, menus] of Object.entries(menuConfig)) {
|
||||
const MenuItems = [];
|
||||
sortBy(menus, ['title']).forEach(({ title, subtitle, key }) => {
|
||||
const linkValue = isCN
|
||||
? [<span>{title}</span>, <span class="chinese">{subtitle}</span>]
|
||||
: [<span>{title}</span>];
|
||||
if (isCN) {
|
||||
key = `${key}-cn`;
|
||||
}
|
||||
pagesKey.push({
|
||||
name: key,
|
||||
url: `/components/${key}/`,
|
||||
title: isCN ? `${title} ${subtitle}` : title,
|
||||
});
|
||||
searchData.push({
|
||||
title,
|
||||
subtitle,
|
||||
url: `/components/${key}/`,
|
||||
});
|
||||
MenuItems.push(
|
||||
<a-menu-item key={key}>
|
||||
<router-link to={`/components/${key}/`}>{linkValue}</router-link>
|
||||
</a-menu-item>,
|
||||
);
|
||||
});
|
||||
MenuGroup.push(<a-menu-item-group title={type}>{MenuItems}</a-menu-item-group>);
|
||||
}
|
||||
pagesKey.forEach((item, index) => {
|
||||
if (item.name === name) {
|
||||
prevPage = pagesKey[index - 1];
|
||||
nextPage = pagesKey[index + 1];
|
||||
}
|
||||
});
|
||||
let locale = zhCN;
|
||||
if (!isCN) {
|
||||
locale = enUS;
|
||||
}
|
||||
const config = AllDemo[titleMap[reName]];
|
||||
this.resetDocumentTitle(config, reName, isCN);
|
||||
const { isMobile, $route } = this;
|
||||
return (
|
||||
<div class="page-wrapper">
|
||||
<Header searchData={searchData} name={name} />
|
||||
<a-config-provider locale={locale}>
|
||||
<div class="main-wrapper">
|
||||
<a-row>
|
||||
{isMobile ? (
|
||||
<MobileMenu ref="sidebar" wrapperClassName="drawer-wrapper">
|
||||
<SurelyVue />
|
||||
<a-menu
|
||||
class="aside-container menu-site"
|
||||
selectedKeys={[name]}
|
||||
defaultOpenKeys={['Components']}
|
||||
inlineIndent={40}
|
||||
mode="inline"
|
||||
>
|
||||
{docsMenu}
|
||||
<a-sub-menu title={`Components(${searchData.length})`} key="Components">
|
||||
{MenuGroup}
|
||||
</a-sub-menu>
|
||||
</a-menu>
|
||||
</MobileMenu>
|
||||
) : (
|
||||
<a-col
|
||||
ref="sidebar"
|
||||
class="site-sidebar main-menu"
|
||||
xxl={4}
|
||||
xl={5}
|
||||
lg={5}
|
||||
md={6}
|
||||
sm={8}
|
||||
xs={12}
|
||||
>
|
||||
<a-affix>
|
||||
<section class="main-menu-inner">
|
||||
<SurelyVue />
|
||||
<a-menu
|
||||
class="aside-container menu-site"
|
||||
selectedKeys={[name]}
|
||||
defaultOpenKeys={['Components']}
|
||||
inlineIndent={40}
|
||||
mode="inline"
|
||||
>
|
||||
{docsMenu}
|
||||
<a-sub-menu title={`Components(${searchData.length})`} key="Components">
|
||||
{MenuGroup}
|
||||
</a-sub-menu>
|
||||
</a-menu>
|
||||
</section>
|
||||
</a-affix>
|
||||
</a-col>
|
||||
)}
|
||||
<a-col xxl={20} xl={19} lg={19} md={18} sm={24} xs={24}>
|
||||
<section class="main-container main-container-component">
|
||||
{showAd ? <GeektimeAds isMobile={isMobile} /> : null}
|
||||
<WWAds />
|
||||
{!isMobile ? (
|
||||
<div class={['toc-affix', isCN ? 'toc-affix-cn' : '']} style="width: 150px;">
|
||||
{this.getSubMenu(isCN)}
|
||||
</div>
|
||||
) : null}
|
||||
{this.showDemo ? (
|
||||
<Provider store={this.store} key={isCN ? 'cn' : 'en'}>
|
||||
<router-view
|
||||
class={`demo-cols-${config.cols || 2}`}
|
||||
{...{
|
||||
directives: [
|
||||
{
|
||||
name: 'mountedCallback',
|
||||
value: this.mountedCallback,
|
||||
},
|
||||
],
|
||||
}}
|
||||
></router-view>
|
||||
</Provider>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{this.showApi ? (
|
||||
<div class="markdown api-container" ref="doc">
|
||||
<router-view
|
||||
{...{
|
||||
directives: [
|
||||
{
|
||||
name: 'mountedCallback',
|
||||
value: this.mountedCallback,
|
||||
},
|
||||
],
|
||||
}}
|
||||
></router-view>
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</section>
|
||||
<section class="prev-next-nav">
|
||||
{prevPage ? (
|
||||
<router-link class="prev-page" to={`${prevPage.url}`}>
|
||||
<a-icon type="left" />
|
||||
{prevPage.title}
|
||||
</router-link>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{nextPage ? (
|
||||
<router-link class="next-page" to={`${nextPage.url}`}>
|
||||
{nextPage.title}
|
||||
<a-icon type="right" />
|
||||
</router-link>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</section>
|
||||
<Footer ref="footer" isCN={isCN} />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</a-config-provider>
|
||||
{name.indexOf('back-top') === -1 ? <a-back-top /> : null}
|
||||
<RightBottomAd isCN={isCN} isMobile={isMobile} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<div class="markdown" v-html="marked(text)" />
|
||||
</template>
|
||||
<script>
|
||||
import marked from 'marked';
|
||||
import { isZhCN } from '../utils/util';
|
||||
const renderer = new marked.Renderer();
|
||||
renderer.heading = function(text, level) {
|
||||
return (
|
||||
'<h' + level + ' id="' + text.replace(/[^\w]+/g, '-') + '">' + text + '</h' + level + '>\n'
|
||||
);
|
||||
};
|
||||
marked.setOptions({
|
||||
renderer,
|
||||
gfm: true,
|
||||
tables: true,
|
||||
breaks: true,
|
||||
pedantic: true,
|
||||
sanitize: true,
|
||||
smartLists: true,
|
||||
smartypants: true,
|
||||
});
|
||||
export default {
|
||||
name: 'Md',
|
||||
props: {
|
||||
cn: String,
|
||||
us: String,
|
||||
},
|
||||
inject: {
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
data() {
|
||||
let text = '';
|
||||
const { cn, us } = this;
|
||||
if (this.$slots.default && this.$slots.default[0] && this.$slots.default[0].text) {
|
||||
text = this.$slots.default[0].text;
|
||||
} else {
|
||||
text = isZhCN(this.demoContext.name) ? cn : us;
|
||||
}
|
||||
text = text || '';
|
||||
text = text
|
||||
.split('\n')
|
||||
.map(t => t.trim())
|
||||
.join('\n');
|
||||
return {
|
||||
marked,
|
||||
text,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<template>
|
||||
<div v-if="isCN" id="right-bottom">
|
||||
<img width="150" :src="`https://next.antdv.com/common_rice.png?v=${v}`" />
|
||||
<div v-if="isMobile" class="close" @click="visible = false">
|
||||
<a-icon type="close" />
|
||||
</div>
|
||||
<!-- <span v-if="isCN">广告</span> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
const isEffective = (start, end) => {
|
||||
return moment().isBetween(start, end);
|
||||
};
|
||||
export default {
|
||||
components: {},
|
||||
props: ['isCN', 'isMobile'],
|
||||
data() {
|
||||
return {
|
||||
isEffective,
|
||||
visible: true,
|
||||
v: moment().date(),
|
||||
ads: [
|
||||
{
|
||||
alt: 'geektime',
|
||||
img: 'https://qn.antdv.com/geektime-web-small.jpg',
|
||||
href: 'http://gk.link/a/10l8O',
|
||||
visible: isEffective('2020-09-03 10:00:00', '2020-10-04 10:00:00'),
|
||||
},
|
||||
{
|
||||
alt: 'powerproject',
|
||||
img: 'https://qn.antdv.com/powerproject.jpeg?v=20200327',
|
||||
href: 'http://www.powerproject.com.cn',
|
||||
visible: isEffective('2020-03-27 17:00:00', '2020-09-28 17:00:00'),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#right-bottom {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
width: 150px;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
.close {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
font-size: 16px;
|
||||
padding: 15px;
|
||||
color: #6e3041;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<div class="snd-ad">
|
||||
<div class="sponsorsWrap">
|
||||
<span v-if="!isCN" class="sponsorsTitle">
|
||||
{{ isCN ? '赞助商' : 'Sponsors' }}
|
||||
</span>
|
||||
<ul>
|
||||
<!-- <li class="sponsorsItem">
|
||||
<a href="https://tipe.io/?ref=ant-design-vue" target="_blank">
|
||||
<img height="51" src="https://cdn.tipe.io/tipe/tipe-cat-no-text.svg" alt="tipe" />
|
||||
</a>
|
||||
</li> -->
|
||||
<li v-if="isCN && isEffective(effectiveTime.kkb)" class="sponsorsItem">
|
||||
<a href="https://datayi.cn/w/Y9J3M2vR" target="_blank">
|
||||
<img height="66" src="https://qn.antdv.com/kaikeba_ssr.jpeg" alt="kaikeba">
|
||||
</a>
|
||||
<span style="position: absolute; top: 0px;right: 10px">广告</span>
|
||||
</li>
|
||||
<!-- <li class="sponsorsItem">
|
||||
<a-button type="primary" ghost style="font-size: 12px" @click="handleClick">
|
||||
{{ isCN ? '成为赞助商' : 'Become a Sponsor' }}
|
||||
</a-button>
|
||||
</li> -->
|
||||
</ul>
|
||||
</div>
|
||||
<a-modal v-model="visible" title="成为赞助商" @ok="visible = false">
|
||||
如果您有品牌推广、活动推广、招聘推广、社区合作等需求,欢迎联系我们,成为赞助商。<br>
|
||||
您的广告将出现在 And Design Vue 文档所有子页面及 GitHub Readme 等页面。<br>
|
||||
咨询邮箱:<a href="mailto:antdv@foxmail.com">antdv@foxmail.com</a><br>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
export default {
|
||||
props: ['isCN'],
|
||||
data() {
|
||||
return {
|
||||
top: 50,
|
||||
effectiveTime: {
|
||||
bmatch: {
|
||||
start: '2019-03-11',
|
||||
end: '2019-06-11',
|
||||
},
|
||||
kkb: {
|
||||
start: '2020-11-16 22:00:00',
|
||||
end: '2021-05-17 22:00:00',
|
||||
},
|
||||
},
|
||||
visible: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isEffective({ start, end }) {
|
||||
return moment().isBetween(start, end);
|
||||
},
|
||||
handleClick() {
|
||||
if (this.isCN) {
|
||||
this.visible = true;
|
||||
} else {
|
||||
window.open('https://opencollective.com/ant-design-vue#sponsor');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue