Compare commits
17 Commits
feat/vapor
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
2cda7bde09 | |
|
|
6255f1632c | |
|
|
ef51f7f1cc | |
|
|
252a0e2563 | |
|
|
bbb7670df1 | |
|
|
fcdda4a0be | |
|
|
79b63b41c6 | |
|
|
56d9b358f2 | |
|
|
b58e73d51a | |
|
|
e8ec520d9a | |
|
|
ce56f0c8f6 | |
|
|
723bb47a42 | |
|
|
57ea8a65d4 | |
|
|
7e5008080d | |
|
|
74b3018945 | |
|
|
28b1c4f62d | |
|
|
04f6ba33c7 |
|
|
@ -0,0 +1,36 @@
|
||||||
|
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,2 @@
|
||||||
|
codecov:
|
||||||
|
branch: master
|
||||||
|
|
@ -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,13 @@
|
||||||
|
node_modules/
|
||||||
|
**/*.spec.*
|
||||||
|
**/style/
|
||||||
|
*.html
|
||||||
|
/components/test/*
|
||||||
|
es/
|
||||||
|
lib/
|
||||||
|
_site/
|
||||||
|
dist/
|
||||||
|
site/dist/
|
||||||
|
components/version/version.ts
|
||||||
|
site/src/router/demoRoutes.js
|
||||||
|
locale/
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -12,6 +12,3 @@ contact_links:
|
||||||
- name: Paypal
|
- name: Paypal
|
||||||
url: https://www.paypal.me/tangjinzhou
|
url: https://www.paypal.me/tangjinzhou
|
||||||
about: Love Ant Design Vue? Please consider supporting us via Paypal.
|
about: Love Ant Design Vue? Please consider supporting us via Paypal.
|
||||||
- name: 支付宝/微信 赞助
|
|
||||||
url: https://aliyuncdn.antdv.com/alipay-and-wechat.png
|
|
||||||
about: Ant Design Vue 的健康持续发展需要您的支持,🙏
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
name: Build and Deploy to Cloudflare
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Build Application
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install --force
|
||||||
|
|
||||||
|
- name: Build application
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-files
|
||||||
|
path: site/dist/
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Deploy to Cloudflare
|
||||||
|
needs: build
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
deployments: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout (for config files)
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
with:
|
||||||
|
sparse-checkout: |
|
||||||
|
wrangler.jsonc
|
||||||
|
sparse-checkout-cone-mode: false
|
||||||
|
|
||||||
|
- name: Download build artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-files
|
||||||
|
path: site/dist/
|
||||||
|
|
||||||
|
- name: Deploy (Workers + Static Assets)
|
||||||
|
uses: cloudflare/wrangler-action@v3.14.1
|
||||||
|
with:
|
||||||
|
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
|
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
|
command: deploy --config wrangler.jsonc
|
||||||
|
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
@ -10,7 +10,7 @@ jobs:
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: cache package-lock.json
|
- name: cache package-lock.json
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: package-temp-dir
|
path: package-temp-dir
|
||||||
key: lock-${{ github.sha }}
|
key: lock-${{ github.sha }}
|
||||||
|
|
@ -27,7 +27,7 @@ jobs:
|
||||||
|
|
||||||
- name: cache node_modules
|
- name: cache node_modules
|
||||||
id: node_modules_cache_id
|
id: node_modules_cache_id
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: node_modules
|
path: node_modules
|
||||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||||
|
|
@ -52,13 +52,13 @@ jobs:
|
||||||
# submodules: true
|
# submodules: true
|
||||||
|
|
||||||
- name: restore cache from package-lock.json
|
- name: restore cache from package-lock.json
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: package-temp-dir
|
path: package-temp-dir
|
||||||
key: lock-${{ github.sha }}
|
key: lock-${{ github.sha }}
|
||||||
|
|
||||||
- name: restore cache from node_modules
|
- name: restore cache from node_modules
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: node_modules
|
path: node_modules
|
||||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ jobs:
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: cache package-lock.json
|
- name: cache package-lock.json
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: package-temp-dir
|
path: package-temp-dir
|
||||||
key: lock-${{ github.sha }}
|
key: lock-${{ github.sha }}
|
||||||
|
|
@ -27,7 +27,7 @@ jobs:
|
||||||
|
|
||||||
- name: cache node_modules
|
- name: cache node_modules
|
||||||
id: node_modules_cache_id
|
id: node_modules_cache_id
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: node_modules
|
path: node_modules
|
||||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||||
|
|
@ -43,25 +43,25 @@ jobs:
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: restore cache from package-lock.json
|
- name: restore cache from package-lock.json
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: package-temp-dir
|
path: package-temp-dir
|
||||||
key: lock-${{ github.sha }}
|
key: lock-${{ github.sha }}
|
||||||
|
|
||||||
- name: restore cache from node_modules
|
- name: restore cache from node_modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: node_modules
|
path: node_modules
|
||||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||||
|
|
||||||
- name: cache lib
|
- name: cache lib
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: lib
|
path: lib
|
||||||
key: lib-${{ github.sha }}
|
key: lib-${{ github.sha }}
|
||||||
|
|
||||||
- name: cache es
|
- name: cache es
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: es
|
path: es
|
||||||
key: es-${{ github.sha }}
|
key: es-${{ github.sha }}
|
||||||
|
|
@ -77,13 +77,13 @@ jobs:
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: restore cache from package-lock.json
|
- name: restore cache from package-lock.json
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: package-temp-dir
|
path: package-temp-dir
|
||||||
key: lock-${{ github.sha }}
|
key: lock-${{ github.sha }}
|
||||||
|
|
||||||
- name: restore cache from node_modules
|
- name: restore cache from node_modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: node_modules
|
path: node_modules
|
||||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||||
|
|
@ -99,13 +99,13 @@ jobs:
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: restore cache from package-lock.json
|
- name: restore cache from package-lock.json
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: package-temp-dir
|
path: package-temp-dir
|
||||||
key: lock-${{ github.sha }}
|
key: lock-${{ github.sha }}
|
||||||
|
|
||||||
- name: restore cache from node_modules
|
- name: restore cache from node_modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: node_modules
|
path: node_modules
|
||||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,9 @@ package-lock.json
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
/coverage
|
/coverage
|
||||||
|
|
||||||
|
# 备份文件
|
||||||
|
/components/test/*
|
||||||
|
list.txt
|
||||||
|
|
||||||
site/dev.js
|
site/dev.js
|
||||||
|
|
||||||
|
|
@ -74,39 +77,10 @@ vetur/
|
||||||
|
|
||||||
report.html
|
report.html
|
||||||
|
|
||||||
|
site/src/router/demoRoutes.js
|
||||||
|
|
||||||
|
components/version/version.ts
|
||||||
# Local env files
|
components/version/version.tsx
|
||||||
.env
|
components/version/token.json
|
||||||
.env.*
|
components/version/token-meta.json
|
||||||
!.env.template
|
~component-api.json
|
||||||
|
|
||||||
# Testing
|
|
||||||
coverage
|
|
||||||
|
|
||||||
# Turbo
|
|
||||||
.turbo
|
|
||||||
|
|
||||||
# Vercel
|
|
||||||
.vercel
|
|
||||||
|
|
||||||
# Build Outputs
|
|
||||||
.next/
|
|
||||||
out/
|
|
||||||
build/
|
|
||||||
dist/
|
|
||||||
storybook-static/
|
|
||||||
|
|
||||||
|
|
||||||
# Debug
|
|
||||||
npm-debug.log*
|
|
||||||
|
|
||||||
# Misc
|
|
||||||
.DS_Store
|
|
||||||
*.pem
|
|
||||||
vite.config.*.timestamp*
|
|
||||||
*.tsbuildinfo
|
|
||||||
*.log
|
|
||||||
|
|
||||||
.npmrc
|
|
||||||
.tsup/
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
npx --no-install pretty-quick --staged
|
||||||
|
|
@ -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,60 @@
|
||||||
|
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)/',
|
||||||
|
];
|
||||||
|
const testPathIgnorePatterns = ['/node_modules/', 'node'];
|
||||||
|
|
||||||
|
function getTestRegex(libDir) {
|
||||||
|
if (libDir === 'dist') {
|
||||||
|
return 'demo\\.test\\.js$';
|
||||||
|
}
|
||||||
|
return '.*\\.test\\.(j|t)sx?$';
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
verbose: true,
|
||||||
|
setupFiles: ['./tests/setup.js'],
|
||||||
|
setupFilesAfterEnv: ['./tests/setupAfterEnv.ts'],
|
||||||
|
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json', 'vue', 'md', 'jpg'],
|
||||||
|
modulePathIgnorePatterns: ['/_site/'],
|
||||||
|
testPathIgnorePatterns: testPathIgnorePatterns,
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
testRegex: getTestRegex(libDir),
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^@/(.*)$/': '<rootDir>/$1',
|
||||||
|
'^ant-design-vue$': '<rootDir>/components/index',
|
||||||
|
'^ant-design-vue/es/(.*)$': '<rootDir>/components/$1',
|
||||||
|
},
|
||||||
|
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
|
||||||
|
collectCoverage: process.env.COVERAGE === 'true',
|
||||||
|
collectCoverageFrom: [
|
||||||
|
'components/**/*.{js,jsx,vue}',
|
||||||
|
'!components/*/__tests__/**/type.{js,jsx}',
|
||||||
|
'!components/vc-*/**/*',
|
||||||
|
'!components/*/demo/**/*',
|
||||||
|
'!components/_util/**/*',
|
||||||
|
'!components/align/**/*',
|
||||||
|
'!components/trigger/**/*',
|
||||||
|
'!**/node_modules/**',
|
||||||
|
],
|
||||||
|
testEnvironment: 'jsdom',
|
||||||
|
testEnvironmentOptions: {
|
||||||
|
url: 'http://localhost',
|
||||||
|
customExportConditions: ['node', 'node-addons'],
|
||||||
|
},
|
||||||
|
transformIgnorePatterns,
|
||||||
|
globals: {
|
||||||
|
'ts-jest': {
|
||||||
|
babelConfig: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
**/*.svg
|
||||||
|
lib/
|
||||||
|
es/
|
||||||
|
dist/
|
||||||
|
_site/
|
||||||
|
coverage/
|
||||||
|
CNAME
|
||||||
|
LICENSE
|
||||||
|
yarn.lock
|
||||||
|
netlify.toml
|
||||||
|
yarn-error.log
|
||||||
|
*.sh
|
||||||
|
*.snap
|
||||||
|
.gitignore
|
||||||
|
.npmignore
|
||||||
|
.prettierignore
|
||||||
|
.DS_Store
|
||||||
|
.editorconfig
|
||||||
|
.eslintignore
|
||||||
|
**/*.yml
|
||||||
|
**/assets
|
||||||
|
.gitattributes
|
||||||
|
.stylelintrc
|
||||||
|
.vcmrc
|
||||||
|
.png
|
||||||
|
.npmrc.template
|
||||||
|
.huskyrc
|
||||||
|
.gitmodules
|
||||||
|
*.png
|
||||||
|
v2-doc/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"endOfLine": "lf",
|
||||||
|
"printWidth": 100,
|
||||||
|
"proseWrap": "never",
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"htmlWhitespaceSensitivity": "ignore",
|
||||||
|
"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,43 @@
|
||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"helpMessage": "\nPlease fix your commit message (and consider using https://www.npmjs.com/package/commitizen)\n",
|
||||||
|
"types": [
|
||||||
|
"feat",
|
||||||
|
"fix",
|
||||||
|
"docs",
|
||||||
|
"style",
|
||||||
|
"refactor",
|
||||||
|
"perf",
|
||||||
|
"test",
|
||||||
|
"chore",
|
||||||
|
"revert",
|
||||||
|
"ci"
|
||||||
|
],
|
||||||
|
"warnOnFail": false,
|
||||||
|
"autoFix": false
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,3 @@
|
||||||
<p align="center">
|
|
||||||
<a href="https://www.antdv.com/">
|
|
||||||
<img width="200" src="https://aliyuncdn.antdv.com/logo.png">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
<a href="https://www.antdv.com/" target="_blank">Ant Design Vue</a>
|
<a href="https://www.antdv.com/" target="_blank">Ant Design Vue</a>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
@ -18,6 +12,14 @@
|
||||||
|
|
||||||
[](https://www.antdv.com/)
|
[](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) | 简体中文
|
[English](./README.md) | 简体中文
|
||||||
|
|
||||||
## 特性
|
## 特性
|
||||||
|
|
@ -88,14 +90,13 @@ ant-design-vue 是 MIT 协议的开源项目。为了项目能够更好的持续
|
||||||
- [Patreon](https://www.patreon.com/tangjinzhou)
|
- [Patreon](https://www.patreon.com/tangjinzhou)
|
||||||
- [opencollective](https://opencollective.com/ant-design-vue)
|
- [opencollective](https://opencollective.com/ant-design-vue)
|
||||||
- [paypal](https://www.paypal.me/tangjinzhou)
|
- [paypal](https://www.paypal.me/tangjinzhou)
|
||||||
- [支付宝或微信](https://aliyuncdn.antdv.com/alipay-and-wechat.png)
|
|
||||||
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
|
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
|
||||||
|
|
||||||
## 赞助商
|
## 赞助商
|
||||||
|
|
||||||
成为赞助商,并在 Github 上的自述文件上获得您的徽标,并链接到您的网站。 [[成为赞助商](https://opencollective.com/ant-design-vue#sponsor)]
|
成为赞助商,并在 Github 上的自述文件上获得您的徽标,并链接到您的网站。 [[成为赞助商](https://opencollective.com/ant-design-vue#sponsor)]
|
||||||
|
|
||||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://aliyuncdn.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="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>
|
||||||
|
|
||||||
## 支持者
|
## 支持者
|
||||||
|
|
||||||
|
|
|
||||||
13
README.md
13
README.md
|
|
@ -1,6 +1,6 @@
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://www.antdv.com/">
|
<a href="https://www.antdv.com/">
|
||||||
<img width="200" src="https://aliyuncdn.antdv.com/logo.png">
|
<img width="200" src="https://www.antdv.com/logo.png">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -18,6 +18,14 @@ An enterprise-class UI components based on Ant Design and Vue.
|
||||||
|
|
||||||
[](https://www.antdv.com/)
|
[](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)
|
English | [简体中文](./README-zh_CN.md)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
@ -82,14 +90,13 @@ ant-design-vue is an MIT-licensed open source project. In order to achieve bette
|
||||||
- [Patreon](https://www.patreon.com/tangjinzhou)
|
- [Patreon](https://www.patreon.com/tangjinzhou)
|
||||||
- [opencollective](https://opencollective.com/ant-design-vue)
|
- [opencollective](https://opencollective.com/ant-design-vue)
|
||||||
- [paypal](https://www.paypal.me/tangjinzhou)
|
- [paypal](https://www.paypal.me/tangjinzhou)
|
||||||
- [支付宝或微信](https://aliyuncdn.antdv.com/alipay-and-wechat.png)
|
|
||||||
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
|
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
|
||||||
|
|
||||||
## Sponsors
|
## 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)]
|
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://aliyuncdn.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="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>
|
||||||
|
|
||||||
## [More Sponsor (From Patreon、alipay、wechat、paypal...)](https://github.com/vueComponent/ant-design-vue/blob/master/BACKERS.md)
|
## [More Sponsor (From Patreon、alipay、wechat、paypal...)](https://github.com/vueComponent/ant-design-vue/blob/master/BACKERS.md)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
@import '@ant-design-vue/tailwind-config';
|
|
||||||
@source '../index.html';
|
|
||||||
@source '../src/**/*.{vue,ts}';
|
|
||||||
* {
|
|
||||||
scrollbar-width: thin;
|
|
||||||
scrollbar-color: var(--color-base-300) transparent;
|
|
||||||
}
|
|
||||||
*:focus-visible {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shiki.github-dark,
|
|
||||||
.dark-scrollbar {
|
|
||||||
scrollbar-color: rgba(121, 121, 121, 0.4) transparent;
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
export { default } from '@ant-design-vue/eslint-config/vue'
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Playground</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
{
|
|
||||||
"name": "playground",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"private": true,
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"build": "vite build",
|
|
||||||
"dev": "vite",
|
|
||||||
"lint": "eslint . --fix",
|
|
||||||
"preview": "vite preview",
|
|
||||||
"tsc": "vue-tsc --noEmit"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@floating-ui/vue": "^1.1.5",
|
|
||||||
"@heroicons/vue": "^2.1.5",
|
|
||||||
"@ant-design-vue/ui": "*",
|
|
||||||
"@simonwep/pickr": "^1.9.1",
|
|
||||||
"@trpc/client": "^11.0.0",
|
|
||||||
"@trpc/server": "^11.0.0",
|
|
||||||
"@wdns/vue-code-block": "^2.3.3",
|
|
||||||
"clsx": "^2.1.1",
|
|
||||||
"cookies": "^0.9.1",
|
|
||||||
"uuid": "^10.0.0",
|
|
||||||
"vue": "^3.4.34",
|
|
||||||
"vue-router": "^4.4.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@ant-design-vue/eslint-config": "*",
|
|
||||||
"@ant-design-vue/prettier-config": "*",
|
|
||||||
"@ant-design-vue/typescript-config": "*",
|
|
||||||
"@ant-design-vue/vite-config": "*",
|
|
||||||
"@ant-design-vue/tailwind-config": "*",
|
|
||||||
"@tailwindcss/vite": "^4.1.3",
|
|
||||||
"@types/cookies": "^0.9.0",
|
|
||||||
"@types/node": "^20.0.0",
|
|
||||||
"@vitejs/plugin-vue": "^5.1.3",
|
|
||||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
|
||||||
"tailwindcss": "^4.1.3",
|
|
||||||
"typescript": "^5.8.2",
|
|
||||||
"vite": "^5.3.5",
|
|
||||||
"vite-plugin-dts": "^3.9.1",
|
|
||||||
"vite-svg-loader": "^5.1.0",
|
|
||||||
"vue-tsc": "^3.0.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
export { default } from "@ant-design-vue/prettier-config/tailwind";
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
<template>
|
|
||||||
<button @click="toggleTheme" class="fixed top-2 right-2">toggle {{ appearance }}</button>
|
|
||||||
<a-theme :appearance="appearance">
|
|
||||||
<RouterView />
|
|
||||||
</a-theme>
|
|
||||||
</template>
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
const appearance = ref('light')
|
|
||||||
|
|
||||||
const toggleTheme = () => {
|
|
||||||
appearance.value = appearance.value === 'light' ? 'dark' : 'light'
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="flex h-screen" :class="pageClass">
|
|
||||||
<TheNavbar v-if="!hideNavbar" :items="navs"></TheNavbar>
|
|
||||||
<div class="flex-1 justify-center px-4 py-16" :class="contentClass">
|
|
||||||
<RouterView></RouterView>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { provideLayoutOptions } from '@/composables/layout'
|
|
||||||
import { computed, ref } from 'vue'
|
|
||||||
import TheNavbar from './TheNavbar.vue'
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
navs: { name: string; path: string }[]
|
|
||||||
hideNavbar?: boolean
|
|
||||||
hideBreadcrumbs?: boolean
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const pageClass = ref<string>()
|
|
||||||
const contentClass = ref<string>()
|
|
||||||
|
|
||||||
provideLayoutOptions({
|
|
||||||
pageClass,
|
|
||||||
contentClass,
|
|
||||||
hideNavbar: computed(() => props.hideNavbar),
|
|
||||||
hideBreadcrumbs: computed(() => props.hideBreadcrumbs),
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="flex flex-wrap gap-8 px-8">
|
|
||||||
<RouterLink v-for="item in items" :key="item.path" :to="item.path">
|
|
||||||
<div
|
|
||||||
class="shadow-xs relative flex w-72 flex-col rounded-lg bg-primary capitalize text-primary-content transition-all hover:scale-105 hover:shadow-xl"
|
|
||||||
>
|
|
||||||
<div className="flex-col gap-2 flex flex-auto p-4 text-sm items-center text-center">
|
|
||||||
<h2 className="font-semibold flex items-center gap-2 text-xl mb-1">
|
|
||||||
{{ item.name }}
|
|
||||||
</h2>
|
|
||||||
<div className="flex flex-wrap items-start gap-2 justify-end">
|
|
||||||
<ArrowRightIcon class="size-5" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</RouterLink>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ArrowRightIcon } from '@heroicons/vue/20/solid'
|
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
items: { name: string; path: string }[]
|
|
||||||
}>()
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="max-w-full select-none overflow-x-auto px-4 py-2 text-sm">
|
|
||||||
<ul class="flex min-h-min items-center whitespace-nowrap capitalize">
|
|
||||||
<template v-for="(item, i) in items" :key="item.path">
|
|
||||||
<li class="flex items-center">
|
|
||||||
<template v-if="i > 0">
|
|
||||||
<span
|
|
||||||
class="ml-2 mr-3 block size-1.5 rotate-45 transform border-r-[1px] border-t-[1px] border-base-content/70 bg-transparent"
|
|
||||||
></span>
|
|
||||||
</template>
|
|
||||||
<template v-if="item.path !== route.path">
|
|
||||||
<RouterLink class="flex items-center hover:underline" :to="item.path">
|
|
||||||
{{ item.name }}
|
|
||||||
</RouterLink>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<span class="text-base-content/70">{{ item.name }}</span>
|
|
||||||
</template>
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
|
|
||||||
defineProps<{ items: { name: string; path: string }[] }>()
|
|
||||||
const route = useRoute()
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="bg-base-100/90 text-base-content border-base-content/10 border-r">
|
|
||||||
<div class="flex min-h-16 w-full items-center p-2">
|
|
||||||
<div class="justify-start">
|
|
||||||
<div class="group relative inline-block">
|
|
||||||
<ul
|
|
||||||
tabindex="0"
|
|
||||||
class="bg-base-100 z-[1] mt-3 flex w-52 origin-top scale-95 flex-col flex-wrap rounded-lg p-2 text-sm capitalize"
|
|
||||||
>
|
|
||||||
<li v-for="item in items" :key="item.name">
|
|
||||||
<RouterLink
|
|
||||||
:aria-disabled="item.path === route.path"
|
|
||||||
:to="item.path"
|
|
||||||
@click.stop="$event.currentTarget.blur()"
|
|
||||||
class="hover:bg-base-content/10 flex cursor-pointer flex-col rounded-lg px-3 py-2 transition duration-200"
|
|
||||||
>
|
|
||||||
{{ item.name }}
|
|
||||||
</RouterLink>
|
|
||||||
<ul v-if="item.children">
|
|
||||||
<li v-for="child in item.children" :key="child.name">
|
|
||||||
<RouterLink
|
|
||||||
:to="child.path"
|
|
||||||
@click.stop="$event.currentTarget.blur()"
|
|
||||||
class="hover:bg-base-content/10 flex cursor-pointer flex-col rounded-lg px-3 py-2 text-xs opacity-80 transition duration-200"
|
|
||||||
>
|
|
||||||
{{ child.name }}
|
|
||||||
</RouterLink>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
items: { name: string; path: string; children?: { name: string; path: string }[] }[]
|
|
||||||
}>()
|
|
||||||
const route = useRoute()
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import { inject, InjectionKey, provide, Ref } from 'vue'
|
|
||||||
|
|
||||||
export interface LayoutOptions {
|
|
||||||
pageClass: Ref<string | undefined>
|
|
||||||
contentClass: Ref<string | undefined>
|
|
||||||
hideNavbar: Ref<boolean>
|
|
||||||
hideBreadcrumbs: Ref<boolean>
|
|
||||||
}
|
|
||||||
|
|
||||||
const LayoutOptionsToken: InjectionKey<LayoutOptions> = Symbol()
|
|
||||||
|
|
||||||
export function provideLayoutOptions(options: LayoutOptions) {
|
|
||||||
provide(LayoutOptionsToken, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function injectLayoutOptions() {
|
|
||||||
const options = inject(LayoutOptionsToken)
|
|
||||||
if (!options) {
|
|
||||||
throw new Error('"injectLayoutOptions" must be called inside pages')
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import '~/tailwind.css'
|
|
||||||
import { createApp } from 'vue'
|
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
|
||||||
import App from './App.vue'
|
|
||||||
import routes from './routes'
|
|
||||||
import antd from '@ant-design-vue/ui'
|
|
||||||
import '@ant-design-vue/ui/tailwind.css'
|
|
||||||
import '@ant-design-vue/ui/style.css'
|
|
||||||
|
|
||||||
const router = createRouter({
|
|
||||||
history: createWebHistory(),
|
|
||||||
routes,
|
|
||||||
})
|
|
||||||
|
|
||||||
createApp(App).use(router).use(antd).mount('#app')
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="flex h-[200vh] flex-col gap-2">
|
|
||||||
<a-affix :offset-top="top" @change="onChange">
|
|
||||||
<a-button type="primary" @click="top += 10">Affix top</a-button>
|
|
||||||
</a-affix>
|
|
||||||
<br />
|
|
||||||
<a-affix :offset-bottom="bottom">
|
|
||||||
<a-button type="primary" @click="bottom += 10">Affix bottom</a-button>
|
|
||||||
</a-affix>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
const top = ref<number>(10)
|
|
||||||
const bottom = ref<number>(10)
|
|
||||||
const onChange = (lastAffix: boolean) => {
|
|
||||||
console.log('onChange', lastAffix)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="flex flex-wrap gap-2">
|
|
||||||
<a-button variant="solid" size="lg">Solid Button</a-button>
|
|
||||||
<a-button variant="solid" size="lg" disabled>Solid Button</a-button>
|
|
||||||
<a-button variant="solid" size="lg" loading>Solid Button</a-button>
|
|
||||||
<a-button variant="solid" size="lg" danger>Danger Solid Button</a-button>
|
|
||||||
<a-button variant="solid" size="lg" danger disabled>Disabled Danger Solid Button</a-button>
|
|
||||||
<br />
|
|
||||||
<a-button variant="outlined" size="sm">Outlined Button</a-button>
|
|
||||||
<a-button variant="outlined" size="md">Outlined Button</a-button>
|
|
||||||
<a-button variant="outlined" size="lg">Outlined Button</a-button>
|
|
||||||
<a-button variant="outlined" size="lg" disabled>Disabled Outlined Button</a-button>
|
|
||||||
<a-button variant="outlined" size="lg" loading>Loading Outlined Button</a-button>
|
|
||||||
<a-button variant="outlined" size="lg" danger>Danger Outlined Button</a-button>
|
|
||||||
<a-button variant="outlined" size="lg" danger disabled>
|
|
||||||
Disabled Danger Outlined Button
|
|
||||||
</a-button>
|
|
||||||
<br />
|
|
||||||
<a-button variant="text" size="sm">Text Button</a-button>
|
|
||||||
<a-button variant="text" size="md">Text Button</a-button>
|
|
||||||
<a-button variant="text" size="lg">Text Button</a-button>
|
|
||||||
<a-button variant="text" size="lg" disabled>Disabled Text Button</a-button>
|
|
||||||
<a-button variant="text" size="lg" loading>Loading Text Button</a-button>
|
|
||||||
<a-button variant="text" size="lg" danger>Danger Text Button</a-button>
|
|
||||||
<a-button variant="text" size="lg" danger disabled>Disabled Danger Text Button</a-button>
|
|
||||||
<br />
|
|
||||||
<a-button variant="link" size="sm">Link Button</a-button>
|
|
||||||
<a-button variant="link" size="md">Link Button</a-button>
|
|
||||||
<a-button variant="link" size="lg">Link Button</a-button>
|
|
||||||
<a-button variant="link" size="lg" disabled>Disabled Link Button</a-button>
|
|
||||||
<a-button variant="link" size="lg" loading>Loading Link Button</a-button>
|
|
||||||
<a-button variant="link" size="lg" danger>Danger Link Button</a-button>
|
|
||||||
<a-button variant="link" size="lg" danger disabled>Disabled Danger Link Button</a-button>
|
|
||||||
<br />
|
|
||||||
<a-button variant="dashed" size="sm">Dashed Button</a-button>
|
|
||||||
<a-button variant="dashed" size="md">Dashed Button</a-button>
|
|
||||||
<a-button variant="dashed" size="lg">Dashed Button</a-button>
|
|
||||||
<a-button variant="dashed" size="lg" disabled>Disabled Dashed Button</a-button>
|
|
||||||
<a-button variant="dashed" size="lg" loading>Loading Dashed Button</a-button>
|
|
||||||
<a-button variant="dashed" size="lg" danger>Danger Dashed Button</a-button>
|
|
||||||
<a-button variant="dashed" size="lg" danger disabled>Disabled Danger Dashed Button</a-button>
|
|
||||||
<br />
|
|
||||||
<a-button variant="filled" size="sm">Filled Button</a-button>
|
|
||||||
<a-button variant="filled" size="md">Filled Button</a-button>
|
|
||||||
<a-button variant="filled" size="lg">Filled Button</a-button>
|
|
||||||
<a-button variant="filled" size="lg" disabled>Disabled Filled Button</a-button>
|
|
||||||
<a-button variant="filled" size="lg" loading>Loading Filled Button</a-button>
|
|
||||||
<a-button variant="filled" size="lg" danger>Danger Filled Button</a-button>
|
|
||||||
<a-button variant="filled" size="lg" danger disabled>Disabled Danger Filled Button</a-button>
|
|
||||||
|
|
||||||
<a-button color="purple">Purple Button</a-button>
|
|
||||||
<a-button color="blue">Blue Button</a-button>
|
|
||||||
<a-button color="green">Green Button</a-button>
|
|
||||||
<a-button color="red">Red Button</a-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="flex flex-col gap-2">
|
|
||||||
<button class="btn btn-primary">Primary</button>
|
|
||||||
<button class="btn btn-secondary">Default</button>
|
|
||||||
<button class="btn btn-error">Danger</button>
|
|
||||||
<button class="btn btn-link">Link</button>
|
|
||||||
<button class="btn btn-ghost">Ghost</button>
|
|
||||||
<button class="btn btn-link">Link</button>
|
|
||||||
<button class="btn btn-link">Link</button>
|
|
||||||
<button class="btn btn-link">Link</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
<template>
|
|
||||||
<a-flex gap="middle" vertical>
|
|
||||||
<label>
|
|
||||||
Select axis:
|
|
||||||
<select v-model="axis">
|
|
||||||
<option v-for="item in axisOptions" :key="item">{{ item }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<a-flex :vertical="axis === 'vertical'">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in new Array(4)"
|
|
||||||
:key="item"
|
|
||||||
:style="{ ...baseStyle, background: `${index % 2 ? '#1677ff' : '#1677ffbf'}` }"
|
|
||||||
/>
|
|
||||||
</a-flex>
|
|
||||||
<hr/>
|
|
||||||
<label>
|
|
||||||
Select justify:
|
|
||||||
<select v-model="justify">
|
|
||||||
<option v-for="item in justifyOptions" :key="item">{{ item }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Select align:
|
|
||||||
<select v-model="align">
|
|
||||||
<option v-for="item in alignOptions" :key="item">{{ item }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<a-flex :style="{ ...boxStyle }" :justify="justify" :align="align">
|
|
||||||
<a-button variant="solid">Primary</a-button>
|
|
||||||
<a-button variant="solid">Primary</a-button>
|
|
||||||
<a-button variant="solid">Primary</a-button>
|
|
||||||
<a-button variant="solid">Primary</a-button>
|
|
||||||
</a-flex>
|
|
||||||
<hr/>
|
|
||||||
<a-flex gap="middle" vertical>
|
|
||||||
<label>
|
|
||||||
Select gap size:
|
|
||||||
<select v-model="gapSize">
|
|
||||||
<option v-for="item in gapSizeOptions" :key="item">{{ item }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<a-flex :gap="gapSize">
|
|
||||||
<a-button variant="solid">Primary</a-button>
|
|
||||||
<a-button>Default</a-button>
|
|
||||||
<a-button variant="dashed">Dashed</a-button>
|
|
||||||
<a-button variant="link">Link</a-button>
|
|
||||||
</a-flex>
|
|
||||||
</a-flex>
|
|
||||||
<hr/>
|
|
||||||
<label>
|
|
||||||
Auto wrap:
|
|
||||||
</label>
|
|
||||||
<a-flex wrap="wrap" gap="small">
|
|
||||||
<a-button v-for="item in new Array(24)" :key="item" variant="solid">Button</a-button>
|
|
||||||
</a-flex>
|
|
||||||
</a-flex>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import type { CSSProperties } from 'vue';
|
|
||||||
import { ref, reactive } from 'vue';
|
|
||||||
|
|
||||||
const baseStyle: CSSProperties = {
|
|
||||||
width: '25%',
|
|
||||||
height: '54px',
|
|
||||||
};
|
|
||||||
const boxStyle: CSSProperties = {
|
|
||||||
width: '100%',
|
|
||||||
height: '120px',
|
|
||||||
borderRadius: '6px',
|
|
||||||
border: '1px solid #40a9ff',
|
|
||||||
};
|
|
||||||
|
|
||||||
const axisOptions = reactive(['horizontal', 'vertical']);
|
|
||||||
const axis = ref(axisOptions[0]);
|
|
||||||
|
|
||||||
const justifyOptions = reactive([
|
|
||||||
'flex-start',
|
|
||||||
'center',
|
|
||||||
'flex-end',
|
|
||||||
'space-between',
|
|
||||||
'space-around',
|
|
||||||
'space-evenly',
|
|
||||||
]);
|
|
||||||
const justify = ref(justifyOptions[0]);
|
|
||||||
|
|
||||||
const alignOptions = reactive(['flex-start', 'center', 'flex-end']);
|
|
||||||
const align = ref(alignOptions[0]);
|
|
||||||
|
|
||||||
const gapSizeOptions = reactive(['small', 'middle', 'large']);
|
|
||||||
const gapSize = ref(gapSizeOptions[0]);
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
import { RouteRecordRaw, RouterView } from 'vue-router'
|
|
||||||
import BasicLayout from './components/BasicLayout.vue'
|
|
||||||
import { Fragment, h } from 'vue'
|
|
||||||
|
|
||||||
// /pages/button/basic.vue
|
|
||||||
const items = import.meta.glob('./pages/*/*.vue', { import: 'default', eager: true })
|
|
||||||
|
|
||||||
const categoryRoutes: Record<string, RouteRecordRaw[]> = {}
|
|
||||||
|
|
||||||
Object.keys(items).forEach(path => {
|
|
||||||
const route = path.replace('./pages/', '').replace('.vue', '')
|
|
||||||
const [category, demo] = route.split('/')
|
|
||||||
|
|
||||||
if (!categoryRoutes[category]) {
|
|
||||||
categoryRoutes[category] = []
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryRoutes[category].push({
|
|
||||||
path: demo,
|
|
||||||
component: items[path],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const routes: RouteRecordRaw[] = Object.entries(categoryRoutes).map(([category, children]) => {
|
|
||||||
const renderComponents = () =>
|
|
||||||
h(
|
|
||||||
'div',
|
|
||||||
children.map(child => h(child.component)),
|
|
||||||
)
|
|
||||||
renderComponents.displayName = 'renderComponents'
|
|
||||||
return {
|
|
||||||
path: `/${category}`,
|
|
||||||
component: RouterView,
|
|
||||||
children: [
|
|
||||||
...children,
|
|
||||||
{
|
|
||||||
path: ':demo*',
|
|
||||||
component: renderComponents,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const navs = Object.keys(categoryRoutes).map(category => ({
|
|
||||||
name: category,
|
|
||||||
path: `/${category}`,
|
|
||||||
children: categoryRoutes[category].map(child => ({
|
|
||||||
name: child.path,
|
|
||||||
path: `/${category}/${child.path}`,
|
|
||||||
})),
|
|
||||||
}))
|
|
||||||
routes.push({
|
|
||||||
path: '/:pathMatch(.*)*',
|
|
||||||
component: h('div', 'demo not found'),
|
|
||||||
})
|
|
||||||
export default [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
component: BasicLayout,
|
|
||||||
children: routes,
|
|
||||||
props: {
|
|
||||||
navs,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
declare module '*.vue' {
|
|
||||||
import type { DefineComponent } from 'vue'
|
|
||||||
const component: DefineComponent<Record<string, never>, Record<string, never>, any>
|
|
||||||
export default component
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/* eslint-disable @typescript-eslint/consistent-type-imports */
|
|
||||||
declare module 'vue' {
|
|
||||||
export interface GlobalComponents {
|
|
||||||
AButton: typeof import('@ant-design-vue/ui').Button
|
|
||||||
AAffix: typeof import('@ant-design-vue/ui').Affix
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export {}
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
import { RouteRecordRaw } from 'vue-router'
|
|
||||||
|
|
||||||
export function globRoutes(
|
|
||||||
baseName: string,
|
|
||||||
globs: Record<string, () => Promise<unknown>>,
|
|
||||||
): RouteRecordRaw {
|
|
||||||
const items = Object.entries(globs).map(([path, component]) => {
|
|
||||||
const match = path.match(/^\.\/pages\/(.+)\/index\.ts$/)
|
|
||||||
if (!match) {
|
|
||||||
throw new Error('invalid glob')
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
name: match[1],
|
|
||||||
component,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const home: RouteRecordRaw = {
|
|
||||||
path: '',
|
|
||||||
components: {
|
|
||||||
default: () => import('@/components/HomePage.vue'),
|
|
||||||
breadcrumbs: () => import('@/components/TheBreadcrumbs.vue'),
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
default: {
|
|
||||||
items: items.map(item => {
|
|
||||||
return {
|
|
||||||
name: item.name,
|
|
||||||
path: `/${baseName}/${item.name}`,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
breadcrumbs: {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
name: 'home',
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: baseName,
|
|
||||||
path: `/${baseName}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
name: baseName,
|
|
||||||
title: baseName,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const pages: RouteRecordRaw[] = items.map(item => {
|
|
||||||
return {
|
|
||||||
path: item.name,
|
|
||||||
components: {
|
|
||||||
default: item.component,
|
|
||||||
breadcrumbs: () => import('@/components/TheBreadcrumbs.vue'),
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
breadcrumbs: {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
name: 'home',
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: baseName,
|
|
||||||
path: `/${baseName}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: item.name,
|
|
||||||
path: `/${baseName}/${item.name}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
name: item.name,
|
|
||||||
title: `${baseName} - ${item.name}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
path: `/${baseName}`,
|
|
||||||
component: () => import('@/components/BasicLayout.vue'),
|
|
||||||
props: {
|
|
||||||
navs: [
|
|
||||||
{
|
|
||||||
name: 'home',
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
hideNavbar: true,
|
|
||||||
hideBreadcrumbs: true,
|
|
||||||
},
|
|
||||||
children: [home, ...pages],
|
|
||||||
} as RouteRecordRaw
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "@ant-design-vue/typescript-config/tsconfig.vue.json",
|
|
||||||
"include": ["src/**/*.ts", "src/**/*.vue"],
|
|
||||||
"references": [{ "path": "./tsconfig.node.json" }],
|
|
||||||
"compilerOptions": {
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"],
|
|
||||||
"~/*": ["./assets/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "@ant-design-vue/typescript-config/tsconfig.node.json",
|
|
||||||
"include": ["vite.config.*"]
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
import tailwindcss from '@tailwindcss/vite'
|
|
||||||
import vue from '@vitejs/plugin-vue'
|
|
||||||
import { resolve } from 'node:path'
|
|
||||||
import { defineConfig, Plugin } from 'vite'
|
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [vue(), tailwindcss()],
|
|
||||||
server: {
|
|
||||||
watch: {
|
|
||||||
ignored: ['!**/node_modules/@ant-design-vue/**'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': resolve(__dirname, './src'),
|
|
||||||
'~': resolve(__dirname, './assets'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
test: {
|
||||||
|
presets: [['@babel/preset-env']],
|
||||||
|
plugins: [
|
||||||
|
['@vue/babel-plugin-jsx', { mergeProps: false, enableObjectSlots: false }],
|
||||||
|
'@babel/plugin-proposal-optional-chaining',
|
||||||
|
'@babel/plugin-transform-object-assign',
|
||||||
|
'@babel/plugin-proposal-object-rest-spread',
|
||||||
|
'@babel/plugin-proposal-export-default-from',
|
||||||
|
'@babel/plugin-proposal-export-namespace-from',
|
||||||
|
'@babel/plugin-proposal-class-properties',
|
||||||
|
'@babel/plugin-syntax-dynamic-import',
|
||||||
|
'@babel/plugin-transform-runtime',
|
||||||
|
'transform-require-context',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
export type KeyType = string | number;
|
export type KeyType = string | number;
|
||||||
type ValueType = [number, any]; // [times, realValue]
|
type ValueType = [number, any]; // [times, realValue]
|
||||||
|
|
||||||
const SPLIT = '%';
|
const SPLIT = '%';
|
||||||
|
|
||||||
class Entity {
|
class Entity {
|
||||||
instanceId: string;
|
instanceId: string;
|
||||||
constructor(instanceId: string) {
|
constructor(instanceId: string) {
|
||||||
this.instanceId = instanceId;
|
this.instanceId = instanceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @private Internal cache map. Do not access this directly */
|
/** @private Internal cache map. Do not access this directly */
|
||||||
cache = new Map<string, ValueType>();
|
cache = new Map<string, ValueType>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ export function createCache() {
|
||||||
Array.from(styles).forEach(style => {
|
Array.from(styles).forEach(style => {
|
||||||
(style as any)[CSS_IN_JS_INSTANCE] = (style as any)[CSS_IN_JS_INSTANCE] || cssinjsInstanceId;
|
(style as any)[CSS_IN_JS_INSTANCE] = (style as any)[CSS_IN_JS_INSTANCE] || cssinjsInstanceId;
|
||||||
|
|
||||||
|
// Not force move if no head
|
||||||
// Not force move if no head
|
// Not force move if no head
|
||||||
if ((style as any)[CSS_IN_JS_INSTANCE] === cssinjsInstanceId) {
|
if ((style as any)[CSS_IN_JS_INSTANCE] === cssinjsInstanceId) {
|
||||||
document.head.insertBefore(style, firstChild);
|
document.head.insertBefore(style, firstChild);
|
||||||
|
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
import type Cache from './Cache';
|
|
||||||
import { extract as tokenExtractStyle, TOKEN_PREFIX } from './hooks/useCacheToken';
|
|
||||||
import { CSS_VAR_PREFIX, extract as cssVarExtractStyle } from './hooks/useCSSVarRegister';
|
|
||||||
import { extract as styleExtractStyle, STYLE_PREFIX } from './hooks/useStyleRegister';
|
|
||||||
import { toStyleStr } from './util';
|
|
||||||
import { ATTR_CACHE_MAP, serialize as serializeCacheMap } from './util/cacheMapUtil';
|
|
||||||
|
|
||||||
const ExtractStyleFns = {
|
|
||||||
[STYLE_PREFIX]: styleExtractStyle,
|
|
||||||
[TOKEN_PREFIX]: tokenExtractStyle,
|
|
||||||
[CSS_VAR_PREFIX]: cssVarExtractStyle,
|
|
||||||
};
|
|
||||||
|
|
||||||
type ExtractStyleType = keyof typeof ExtractStyleFns;
|
|
||||||
|
|
||||||
function isNotNull<T>(value: T | null): value is T {
|
|
||||||
return value !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function extractStyle(
|
|
||||||
cache: Cache,
|
|
||||||
options?:
|
|
||||||
| boolean
|
|
||||||
| {
|
|
||||||
plain?: boolean;
|
|
||||||
types?: ExtractStyleType | ExtractStyleType[];
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
const { plain = false, types = ['style', 'token', 'cssVar'] } =
|
|
||||||
typeof options === 'boolean' ? { plain: options } : options || {};
|
|
||||||
|
|
||||||
const matchPrefixRegexp = new RegExp(
|
|
||||||
`^(${(typeof types === 'string' ? [types] : types).join('|')})%`,
|
|
||||||
);
|
|
||||||
|
|
||||||
// prefix with `style` is used for `useStyleRegister` to cache style context
|
|
||||||
const styleKeys = Array.from(cache.cache.keys()).filter(key => matchPrefixRegexp.test(key));
|
|
||||||
|
|
||||||
// Common effect styles like animation
|
|
||||||
const effectStyles: Record<string, boolean> = {};
|
|
||||||
|
|
||||||
// Mapping of cachePath to style hash
|
|
||||||
const cachePathMap: Record<string, string> = {};
|
|
||||||
|
|
||||||
let styleText = '';
|
|
||||||
|
|
||||||
styleKeys
|
|
||||||
.map<[number, string] | null>(key => {
|
|
||||||
const cachePath = key.replace(matchPrefixRegexp, '').replace(/%/g, '|');
|
|
||||||
const [prefix] = key.split('%');
|
|
||||||
const extractFn = ExtractStyleFns[prefix as keyof typeof ExtractStyleFns];
|
|
||||||
const extractedStyle = extractFn(cache.cache.get(key)![1], effectStyles, {
|
|
||||||
plain,
|
|
||||||
});
|
|
||||||
if (!extractedStyle) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const [order, styleId, styleStr] = extractedStyle;
|
|
||||||
if (key.startsWith('style')) {
|
|
||||||
cachePathMap[cachePath] = styleId;
|
|
||||||
}
|
|
||||||
return [order, styleStr];
|
|
||||||
})
|
|
||||||
.filter(isNotNull)
|
|
||||||
.sort(([o1], [o2]) => o1 - o2)
|
|
||||||
.forEach(([, style]) => {
|
|
||||||
styleText += style;
|
|
||||||
});
|
|
||||||
|
|
||||||
// ==================== Fill Cache Path ====================
|
|
||||||
styleText += toStyleStr(
|
|
||||||
`.${ATTR_CACHE_MAP}{content:"${serializeCacheMap(cachePathMap)}";}`,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
{
|
|
||||||
[ATTR_CACHE_MAP]: ATTR_CACHE_MAP,
|
|
||||||
},
|
|
||||||
plain,
|
|
||||||
);
|
|
||||||
|
|
||||||
return styleText;
|
|
||||||
}
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
import { removeCSS, updateCSS } from '../../../vc-util/Dom/dynamicCSS';
|
|
||||||
import { ATTR_MARK, ATTR_TOKEN, CSS_IN_JS_INSTANCE, useStyleInject } from '../StyleContext';
|
|
||||||
import { isClientSide, toStyleStr } from '../util';
|
|
||||||
import type { TokenWithCSSVar } from '../util/css-variables';
|
|
||||||
import { transformToken } from '../util/css-variables';
|
|
||||||
import type { ExtractStyle } from './useGlobalCache';
|
|
||||||
import useGlobalCache from './useGlobalCache';
|
|
||||||
import { uniqueHash } from './useStyleRegister';
|
|
||||||
import type { ComputedRef } from 'vue';
|
|
||||||
import { computed } from 'vue';
|
|
||||||
|
|
||||||
export const CSS_VAR_PREFIX = 'cssVar';
|
|
||||||
|
|
||||||
type CSSVarCacheValue<V, T extends Record<string, V> = Record<string, V>> = [
|
|
||||||
cssVarToken: TokenWithCSSVar<V, T>,
|
|
||||||
cssVarStr: string,
|
|
||||||
styleId: string,
|
|
||||||
cssVarKey: string,
|
|
||||||
];
|
|
||||||
|
|
||||||
const useCSSVarRegister = <V, T extends Record<string, V>>(
|
|
||||||
config: ComputedRef<{
|
|
||||||
path: string[];
|
|
||||||
key: string;
|
|
||||||
prefix?: string;
|
|
||||||
unitless?: Record<string, boolean>;
|
|
||||||
ignore?: Record<string, boolean>;
|
|
||||||
scope?: string;
|
|
||||||
token: any;
|
|
||||||
}>,
|
|
||||||
fn: () => T,
|
|
||||||
) => {
|
|
||||||
const styleContext = useStyleInject();
|
|
||||||
|
|
||||||
const stylePath = computed(() => {
|
|
||||||
return [
|
|
||||||
...config.value.path,
|
|
||||||
config.value.key,
|
|
||||||
config.value.scope || '',
|
|
||||||
config.value.token?._tokenKey,
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
const cache = useGlobalCache<CSSVarCacheValue<V, T>>(
|
|
||||||
CSS_VAR_PREFIX,
|
|
||||||
stylePath,
|
|
||||||
() => {
|
|
||||||
const originToken = fn();
|
|
||||||
const [mergedToken, cssVarsStr] = transformToken<V, T>(originToken, config.value.key, {
|
|
||||||
prefix: config.value.prefix,
|
|
||||||
unitless: config.value.unitless,
|
|
||||||
ignore: config.value.ignore,
|
|
||||||
scope: config.value.scope || '',
|
|
||||||
});
|
|
||||||
|
|
||||||
const styleId = uniqueHash(stylePath.value, cssVarsStr);
|
|
||||||
return [mergedToken, cssVarsStr, styleId, config.value.key];
|
|
||||||
},
|
|
||||||
([, , styleId]) => {
|
|
||||||
if (isClientSide) {
|
|
||||||
removeCSS(styleId, { mark: ATTR_MARK });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
([, cssVarsStr, styleId]) => {
|
|
||||||
if (!cssVarsStr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const style = updateCSS(cssVarsStr, styleId, {
|
|
||||||
mark: ATTR_MARK,
|
|
||||||
prepend: 'queue',
|
|
||||||
attachTo: styleContext.value.container,
|
|
||||||
priority: -999,
|
|
||||||
});
|
|
||||||
|
|
||||||
(style as any)[CSS_IN_JS_INSTANCE] = styleContext.value.cache?.instanceId;
|
|
||||||
|
|
||||||
// Used for `useCacheToken` to remove on batch when token removed
|
|
||||||
style.setAttribute(ATTR_TOKEN, config.value.key);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return cache;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const extract: ExtractStyle<CSSVarCacheValue<any>> = (cache, _effectStyles, options) => {
|
|
||||||
const [, styleStr, styleId, cssVarKey] = cache;
|
|
||||||
const { plain } = options || {};
|
|
||||||
|
|
||||||
if (!styleStr) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const order = -999;
|
|
||||||
|
|
||||||
// ====================== Style ======================
|
|
||||||
// Used for rc-util
|
|
||||||
const sharedAttrs = {
|
|
||||||
'data-vc-order': 'prependQueue',
|
|
||||||
'data-vc-priority': `${order}`,
|
|
||||||
};
|
|
||||||
|
|
||||||
const styleText = toStyleStr(styleStr, cssVarKey, styleId, sharedAttrs, plain);
|
|
||||||
|
|
||||||
return [order, styleId, styleText];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useCSSVarRegister;
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
import hash from '@emotion/hash';
|
import hash from '@emotion/hash';
|
||||||
import { updateCSS } from '../../../vc-util/Dom/dynamicCSS';
|
import { ATTR_TOKEN, CSS_IN_JS_INSTANCE, useStyleInject } from '../StyleContext';
|
||||||
import { ATTR_MARK, ATTR_TOKEN, CSS_IN_JS_INSTANCE, useStyleInject } from '../StyleContext';
|
|
||||||
import type Theme from '../theme/Theme';
|
import type Theme from '../theme/Theme';
|
||||||
import { flattenToken, memoResult, token2key, toStyleStr } from '../util';
|
|
||||||
import { transformToken } from '../util/css-variables';
|
|
||||||
import type { ExtractStyle } from './useGlobalCache';
|
|
||||||
import useGlobalCache from './useGlobalCache';
|
import useGlobalCache from './useGlobalCache';
|
||||||
|
import { flattenToken, token2key } from '../util';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
|
|
||||||
const EMPTY_OVERRIDE = {};
|
const EMPTY_OVERRIDE = {};
|
||||||
|
|
||||||
|
const isProduction = process.env.NODE_ENV === 'production';
|
||||||
|
// nuxt generate when NODE_ENV is prerender
|
||||||
|
const isPrerender = process.env.NODE_ENV === 'prerender';
|
||||||
|
|
||||||
// Generate different prefix to make user selector break in production env.
|
// Generate different prefix to make user selector break in production env.
|
||||||
// This helps developer not to do style override directly on the hash id.
|
// This helps developer not to do style override directly on the hash id.
|
||||||
const hashPrefix = process.env.NODE_ENV !== 'production' ? 'css-dev-only-do-not-override' : 'css';
|
const hashPrefix = !isProduction && !isPrerender ? 'css-dev-only-do-not-override' : 'css';
|
||||||
|
|
||||||
export interface Option<DerivativeToken, DesignToken> {
|
export interface Option<DerivativeToken, DesignToken> {
|
||||||
/**
|
/**
|
||||||
|
|
@ -45,22 +46,6 @@ export interface Option<DerivativeToken, DesignToken> {
|
||||||
override: object,
|
override: object,
|
||||||
theme: Theme<any, any>,
|
theme: Theme<any, any>,
|
||||||
) => DerivativeToken;
|
) => DerivativeToken;
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform token to css variables.
|
|
||||||
*/
|
|
||||||
cssVar?: {
|
|
||||||
/** Prefix for css variables */
|
|
||||||
prefix?: string;
|
|
||||||
/** Tokens that should not be appended with unit */
|
|
||||||
unitless?: Record<string, boolean>;
|
|
||||||
/** Tokens that should not be transformed to css variables */
|
|
||||||
ignore?: Record<string, boolean>;
|
|
||||||
/** Tokens that preserves origin value */
|
|
||||||
preserve?: Record<string, boolean>;
|
|
||||||
/** Key for current theme. Useful for customizing and should be unique */
|
|
||||||
key?: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenKeys = new Map<string, number>();
|
const tokenKeys = new Map<string, number>();
|
||||||
|
|
@ -109,7 +94,6 @@ export const getComputedToken = <DerivativeToken = object, DesignToken = Derivat
|
||||||
format?: (token: DesignToken) => DerivativeToken,
|
format?: (token: DesignToken) => DerivativeToken,
|
||||||
) => {
|
) => {
|
||||||
const derivativeToken = theme.getDerivativeToken(originToken);
|
const derivativeToken = theme.getDerivativeToken(originToken);
|
||||||
|
|
||||||
// Merge with override
|
// Merge with override
|
||||||
let mergedDerivativeToken = {
|
let mergedDerivativeToken = {
|
||||||
...derivativeToken,
|
...derivativeToken,
|
||||||
|
|
@ -124,16 +108,6 @@ export const getComputedToken = <DerivativeToken = object, DesignToken = Derivat
|
||||||
return mergedDerivativeToken;
|
return mergedDerivativeToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TOKEN_PREFIX = 'token';
|
|
||||||
|
|
||||||
type TokenCacheValue<DerivativeToken> = [
|
|
||||||
token: DerivativeToken & { _tokenKey: string; _themeKey: string },
|
|
||||||
hashId: string,
|
|
||||||
realToken: DerivativeToken & { _tokenKey: string },
|
|
||||||
cssVarStr: string,
|
|
||||||
cssVarKey: string,
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache theme derivative token as global shared one
|
* Cache theme derivative token as global shared one
|
||||||
* @param theme Theme entity
|
* @param theme Theme entity
|
||||||
|
|
@ -145,27 +119,21 @@ export default function useCacheToken<DerivativeToken = object, DesignToken = De
|
||||||
theme: Ref<Theme<any, any>>,
|
theme: Ref<Theme<any, any>>,
|
||||||
tokens: Ref<Partial<DesignToken>[]>,
|
tokens: Ref<Partial<DesignToken>[]>,
|
||||||
option: Ref<Option<DerivativeToken, DesignToken>> = ref({}),
|
option: Ref<Option<DerivativeToken, DesignToken>> = ref({}),
|
||||||
): Ref<TokenCacheValue<DerivativeToken>> {
|
) {
|
||||||
const styleContext = useStyleInject();
|
const style = useStyleInject();
|
||||||
|
|
||||||
// Basic - We do basic cache here
|
// Basic - We do basic cache here
|
||||||
const mergedToken = computed(() =>
|
const mergedToken = computed(() => Object.assign({}, ...tokens.value));
|
||||||
memoResult(() => Object.assign({}, ...tokens.value), tokens.value),
|
|
||||||
);
|
|
||||||
|
|
||||||
const tokenStr = computed(() => flattenToken(mergedToken.value));
|
const tokenStr = computed(() => flattenToken(mergedToken.value));
|
||||||
const overrideTokenStr = computed(() => flattenToken(option.value.override ?? EMPTY_OVERRIDE));
|
const overrideTokenStr = computed(() => flattenToken(option.value.override || EMPTY_OVERRIDE));
|
||||||
|
|
||||||
const cssVarStr = computed(() => (option.value.cssVar ? flattenToken(option.value.cssVar) : ''));
|
const cachedToken = useGlobalCache<[DerivativeToken & { _tokenKey: string }, string]>(
|
||||||
|
'token',
|
||||||
const cachedToken = useGlobalCache<TokenCacheValue<DerivativeToken>>(
|
|
||||||
TOKEN_PREFIX,
|
|
||||||
computed(() => [
|
computed(() => [
|
||||||
option.value.salt ?? '',
|
option.value.salt || '',
|
||||||
theme.value?.id,
|
theme.value.id,
|
||||||
tokenStr.value,
|
tokenStr.value,
|
||||||
overrideTokenStr.value,
|
overrideTokenStr.value,
|
||||||
cssVarStr.value,
|
|
||||||
]),
|
]),
|
||||||
() => {
|
() => {
|
||||||
const {
|
const {
|
||||||
|
|
@ -173,82 +141,25 @@ export default function useCacheToken<DerivativeToken = object, DesignToken = De
|
||||||
override = EMPTY_OVERRIDE,
|
override = EMPTY_OVERRIDE,
|
||||||
formatToken,
|
formatToken,
|
||||||
getComputedToken: compute,
|
getComputedToken: compute,
|
||||||
cssVar,
|
|
||||||
} = option.value;
|
} = option.value;
|
||||||
let mergedDerivativeToken = compute
|
const mergedDerivativeToken = compute
|
||||||
? compute(mergedToken.value, override, theme.value)
|
? compute(mergedToken.value, override, theme.value)
|
||||||
: getComputedToken(mergedToken.value, override, theme.value, formatToken);
|
: getComputedToken(mergedToken.value, override, theme.value, formatToken);
|
||||||
|
|
||||||
// Replace token value with css variables
|
|
||||||
const actualToken = { ...mergedDerivativeToken };
|
|
||||||
let cssVarsStr = '';
|
|
||||||
if (!!cssVar) {
|
|
||||||
[mergedDerivativeToken, cssVarsStr] = transformToken(mergedDerivativeToken, cssVar.key!, {
|
|
||||||
prefix: cssVar.prefix,
|
|
||||||
ignore: cssVar.ignore,
|
|
||||||
unitless: cssVar.unitless,
|
|
||||||
preserve: cssVar.preserve,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimize for `useStyleRegister` performance
|
// Optimize for `useStyleRegister` performance
|
||||||
const tokenKey = token2key(mergedDerivativeToken, salt);
|
const tokenKey = token2key(mergedDerivativeToken, salt);
|
||||||
mergedDerivativeToken._tokenKey = tokenKey;
|
mergedDerivativeToken._tokenKey = tokenKey;
|
||||||
actualToken._tokenKey = token2key(actualToken, salt);
|
recordCleanToken(tokenKey);
|
||||||
|
|
||||||
const themeKey = cssVar?.key ?? tokenKey;
|
|
||||||
mergedDerivativeToken._themeKey = themeKey;
|
|
||||||
recordCleanToken(themeKey);
|
|
||||||
|
|
||||||
const hashId = `${hashPrefix}-${hash(tokenKey)}`;
|
const hashId = `${hashPrefix}-${hash(tokenKey)}`;
|
||||||
mergedDerivativeToken._hashId = hashId; // Not used
|
mergedDerivativeToken._hashId = hashId; // Not used
|
||||||
|
return [mergedDerivativeToken, hashId];
|
||||||
return [mergedDerivativeToken, hashId, actualToken, cssVarsStr, cssVar?.key || ''];
|
|
||||||
},
|
},
|
||||||
cache => {
|
cache => {
|
||||||
// Remove token will remove all related style
|
// Remove token will remove all related style
|
||||||
cleanTokenStyle(cache[0]._themeKey, styleContext.value?.cache?.instanceId);
|
cleanTokenStyle(cache[0]._tokenKey, style.value?.cache.instanceId);
|
||||||
},
|
|
||||||
([token, , , cssVarsStr]) => {
|
|
||||||
const { cssVar } = option.value;
|
|
||||||
if (cssVar && cssVarsStr) {
|
|
||||||
const style = updateCSS(cssVarsStr, hash(`css-variables-${token._themeKey}`), {
|
|
||||||
mark: ATTR_MARK,
|
|
||||||
prepend: 'queue',
|
|
||||||
attachTo: styleContext.value?.container,
|
|
||||||
priority: -999,
|
|
||||||
});
|
|
||||||
|
|
||||||
(style as any)[CSS_IN_JS_INSTANCE] = styleContext.value?.cache?.instanceId;
|
|
||||||
|
|
||||||
// Used for `useCacheToken` to remove on batch when token removed
|
|
||||||
style.setAttribute(ATTR_TOKEN, token._themeKey);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return cachedToken;
|
return cachedToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const extract: ExtractStyle<TokenCacheValue<any>> = (cache, _effectStyles, options) => {
|
|
||||||
const [, , realToken, styleStr, cssVarKey] = cache;
|
|
||||||
const { plain } = options || {};
|
|
||||||
|
|
||||||
if (!styleStr) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const styleId = realToken._tokenKey;
|
|
||||||
const order = -999;
|
|
||||||
|
|
||||||
// ====================== Style ======================
|
|
||||||
// Used for rc-util
|
|
||||||
const sharedAttrs = {
|
|
||||||
'data-vc-order': 'prependQueue',
|
|
||||||
'data-vc-priority': `${order}`,
|
|
||||||
};
|
|
||||||
|
|
||||||
const styleText = toStyleStr(styleStr, cssVarKey, styleId, sharedAttrs, plain);
|
|
||||||
|
|
||||||
return [order, styleId, styleText];
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
// import canUseDom from 'rc-util/lib/Dom/canUseDom';
|
|
||||||
import useLayoutEffect from '../../../_util/hooks/useLayoutEffect';
|
|
||||||
import type { ShallowRef, WatchCallback } from 'vue';
|
|
||||||
import { watch } from 'vue';
|
|
||||||
|
|
||||||
type UseCompatibleInsertionEffect = (
|
|
||||||
renderEffect: WatchCallback,
|
|
||||||
effect: (polyfill?: boolean) => ReturnType<WatchCallback>,
|
|
||||||
deps: ShallowRef,
|
|
||||||
) => void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Polyfill `useInsertionEffect` for React < 18
|
|
||||||
* @param renderEffect will be executed in `useMemo`, and do not have callback
|
|
||||||
* @param effect will be executed in `useLayoutEffect`
|
|
||||||
* @param deps
|
|
||||||
*/
|
|
||||||
const useInsertionEffectPolyfill: UseCompatibleInsertionEffect = (renderEffect, effect, deps) => {
|
|
||||||
watch(deps, renderEffect, { immediate: true });
|
|
||||||
useLayoutEffect(() => effect(true), deps);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compatible `useInsertionEffect`
|
|
||||||
* will use `useInsertionEffect` if React version >= 18,
|
|
||||||
* otherwise use `useInsertionEffectPolyfill`.
|
|
||||||
*/
|
|
||||||
const useCompatibleInsertionEffect: UseCompatibleInsertionEffect = useInsertionEffectPolyfill;
|
|
||||||
|
|
||||||
export default useCompatibleInsertionEffect;
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
const useRun = () => {
|
|
||||||
return function (fn: () => void) {
|
|
||||||
fn();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const useEffectCleanupRegister = useRun;
|
|
||||||
|
|
||||||
export default useEffectCleanupRegister;
|
|
||||||
|
|
@ -1,37 +1,41 @@
|
||||||
import { useStyleInject } from '../StyleContext';
|
import { useStyleInject } from '../StyleContext';
|
||||||
import type { KeyType } from '../Cache';
|
import type { KeyType } from '../Cache';
|
||||||
import useCompatibleInsertionEffect from './useCompatibleInsertionEffect';
|
|
||||||
import useHMR from './useHMR';
|
import useHMR from './useHMR';
|
||||||
import type { ShallowRef, Ref } from 'vue';
|
import type { ShallowRef, Ref } from 'vue';
|
||||||
import { onBeforeUnmount, watch, computed } from 'vue';
|
import { onBeforeUnmount, watch, watchEffect, shallowRef } from 'vue';
|
||||||
|
export default function useClientCache<CacheType>(
|
||||||
export type ExtractStyle<CacheValue> = (
|
|
||||||
cache: CacheValue,
|
|
||||||
effectStyles: Record<string, boolean>,
|
|
||||||
options?: {
|
|
||||||
plain?: boolean;
|
|
||||||
},
|
|
||||||
) => [order: number, styleId: string, style: string] | null;
|
|
||||||
|
|
||||||
export default function useGlobalCache<CacheType>(
|
|
||||||
prefix: string,
|
prefix: string,
|
||||||
keyPath: Ref<KeyType[]>,
|
keyPath: Ref<KeyType[]>,
|
||||||
cacheFn: () => CacheType,
|
cacheFn: () => CacheType,
|
||||||
onCacheRemove?: (cache: CacheType, fromHMR: boolean) => void,
|
onCacheRemove?: (cache: CacheType, fromHMR: boolean) => void,
|
||||||
// Add additional effect trigger by `useInsertionEffect`
|
|
||||||
onCacheEffect?: (cachedValue: CacheType) => void,
|
|
||||||
): ShallowRef<CacheType> {
|
): ShallowRef<CacheType> {
|
||||||
const styleContext = useStyleInject();
|
const styleContext = useStyleInject();
|
||||||
const globalCache = computed(() => styleContext.value?.cache);
|
const fullPathStr = shallowRef('');
|
||||||
const deps = computed(() => [prefix, ...keyPath.value].join('%'));
|
const res = shallowRef<CacheType>();
|
||||||
|
watchEffect(() => {
|
||||||
|
fullPathStr.value = [prefix, ...keyPath.value].join('%');
|
||||||
|
});
|
||||||
const HMRUpdate = useHMR();
|
const HMRUpdate = useHMR();
|
||||||
|
const clearCache = (pathStr: string) => {
|
||||||
|
styleContext.value.cache.update(pathStr, prevCache => {
|
||||||
|
const [times = 0, cache] = prevCache || [];
|
||||||
|
const nextCount = times - 1;
|
||||||
|
if (nextCount === 0) {
|
||||||
|
onCacheRemove?.(cache, false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
type UpdaterArgs = [times: number, cache: CacheType];
|
return [times - 1, cache];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const buildCache = (updater?: (data: UpdaterArgs) => UpdaterArgs) => {
|
watch(
|
||||||
globalCache.value.update(deps.value, prevCache => {
|
fullPathStr,
|
||||||
const [times = 0, cache] = prevCache || [undefined, undefined];
|
(newStr, oldStr) => {
|
||||||
|
if (oldStr) clearCache(oldStr);
|
||||||
|
// Create cache
|
||||||
|
styleContext.value.cache.update(newStr, prevCache => {
|
||||||
|
const [times = 0, cache] = prevCache || [];
|
||||||
|
|
||||||
// HMR should always ignore cache since developer may change it
|
// HMR should always ignore cache since developer may change it
|
||||||
let tmpCache = cache;
|
let tmpCache = cache;
|
||||||
|
|
@ -39,77 +43,16 @@ export default function useGlobalCache<CacheType>(
|
||||||
onCacheRemove?.(tmpCache, HMRUpdate);
|
onCacheRemove?.(tmpCache, HMRUpdate);
|
||||||
tmpCache = null;
|
tmpCache = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mergedCache = tmpCache || cacheFn();
|
const mergedCache = tmpCache || cacheFn();
|
||||||
|
|
||||||
const data: UpdaterArgs = [times, mergedCache];
|
return [times + 1, mergedCache];
|
||||||
|
|
||||||
// Call updater if need additional logic
|
|
||||||
return updater ? updater(data) : data;
|
|
||||||
});
|
});
|
||||||
};
|
res.value = styleContext.value.cache.get(fullPathStr.value)![1];
|
||||||
|
|
||||||
watch(
|
|
||||||
deps,
|
|
||||||
() => {
|
|
||||||
buildCache();
|
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
let cacheEntity = globalCache.value.get(deps.value);
|
|
||||||
|
|
||||||
// HMR clean the cache but not trigger `useMemo` again
|
|
||||||
// Let's fallback of this
|
|
||||||
// ref https://github.com/ant-design/cssinjs/issues/127
|
|
||||||
if (process.env.NODE_ENV !== 'production' && !cacheEntity) {
|
|
||||||
buildCache();
|
|
||||||
cacheEntity = globalCache.value.get(deps.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cacheContent = computed(
|
|
||||||
() =>
|
|
||||||
(globalCache.value.get(deps.value) && globalCache.value.get(deps.value)![1]) ||
|
|
||||||
cacheEntity![1],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove if no need anymore
|
|
||||||
useCompatibleInsertionEffect(
|
|
||||||
() => {
|
|
||||||
onCacheEffect?.(cacheContent.value);
|
|
||||||
},
|
|
||||||
polyfill => {
|
|
||||||
// It's bad to call build again in effect.
|
|
||||||
// But we have to do this since StrictMode will call effect twice
|
|
||||||
// which will clear cache on the first time.
|
|
||||||
buildCache(([times, cache]) => {
|
|
||||||
if (polyfill && times === 0) {
|
|
||||||
onCacheEffect?.(cacheContent.value);
|
|
||||||
}
|
|
||||||
return [times + 1, cache];
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
globalCache.value.update(deps.value, prevCache => {
|
|
||||||
const [times = 0, cache] = prevCache || [];
|
|
||||||
const nextCount = times - 1;
|
|
||||||
if (nextCount <= 0) {
|
|
||||||
if (polyfill || !globalCache.value.get(deps.value)) {
|
|
||||||
onCacheRemove?.(cache, false);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [times - 1, cache];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
},
|
|
||||||
deps,
|
|
||||||
);
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
buildCache();
|
clearCache(fullPathStr.value);
|
||||||
});
|
});
|
||||||
|
return res;
|
||||||
return cacheContent;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import canUseDom from '../../canUseDom';
|
import canUseDom from '../../../../_util/canUseDom';
|
||||||
import { ATTR_MARK } from '../StyleContext';
|
import { ATTR_MARK } from '../../StyleContext';
|
||||||
|
|
||||||
export const ATTR_CACHE_MAP = 'data-ant-cssinjs-cache-path';
|
export const ATTR_CACHE_MAP = 'data-ant-cssinjs-cache-path';
|
||||||
|
|
||||||
|
|
@ -3,30 +3,38 @@ import type * as CSS from 'csstype';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import unitless from '@emotion/unitless';
|
import unitless from '@emotion/unitless';
|
||||||
import { compile, serialize, stringify } from 'stylis';
|
import { compile, serialize, stringify } from 'stylis';
|
||||||
import type { Theme, Transformer } from '..';
|
import type { Theme, Transformer } from '../..';
|
||||||
import type Keyframes from '../Keyframes';
|
import type Cache from '../../Cache';
|
||||||
import type { Linter } from '../linters';
|
import type Keyframes from '../../Keyframes';
|
||||||
import { contentQuotesLinter, hashedAnimationLinter } from '../linters';
|
import type { Linter } from '../../linters';
|
||||||
import type { HashPriority } from '../StyleContext';
|
import { contentQuotesLinter, hashedAnimationLinter } from '../../linters';
|
||||||
|
import type { HashPriority } from '../../StyleContext';
|
||||||
import {
|
import {
|
||||||
useStyleInject,
|
useStyleInject,
|
||||||
ATTR_CACHE_PATH,
|
ATTR_CACHE_PATH,
|
||||||
ATTR_MARK,
|
ATTR_MARK,
|
||||||
ATTR_TOKEN,
|
ATTR_TOKEN,
|
||||||
CSS_IN_JS_INSTANCE,
|
CSS_IN_JS_INSTANCE,
|
||||||
} from '../StyleContext';
|
} from '../../StyleContext';
|
||||||
import { isClientSide, supportLayer, toStyleStr } from '../util';
|
import { supportLayer } from '../../util';
|
||||||
import { CSS_FILE_STYLE, existPath, getStyleAndHash } from '../util/cacheMapUtil';
|
import useGlobalCache from '../useGlobalCache';
|
||||||
import type { ExtractStyle } from './useGlobalCache';
|
import { removeCSS, updateCSS } from '../../../../vc-util/Dom/dynamicCSS';
|
||||||
import useGlobalCache from './useGlobalCache';
|
|
||||||
import { removeCSS, updateCSS } from '../../../vc-util/Dom/dynamicCSS';
|
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import type { VueNode } from '../../type';
|
import type { VueNode } from '../../../type';
|
||||||
|
import canUseDom from '../../../../_util/canUseDom';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ATTR_CACHE_MAP,
|
||||||
|
existPath,
|
||||||
|
getStyleAndHash,
|
||||||
|
serialize as serializeCacheMap,
|
||||||
|
} from './cacheMapUtil';
|
||||||
|
|
||||||
|
const isClientSide = canUseDom();
|
||||||
|
|
||||||
const SKIP_CHECK = '_skip_check_';
|
const SKIP_CHECK = '_skip_check_';
|
||||||
const MULTI_VALUE = '_multi_value_';
|
const MULTI_VALUE = '_multi_value_';
|
||||||
|
|
||||||
export type CSSProperties = Omit<CSS.PropertiesFallback<number | string>, 'animationName'> & {
|
export type CSSProperties = Omit<CSS.PropertiesFallback<number | string>, 'animationName'> & {
|
||||||
animationName?: CSS.PropertiesFallback<number | string>['animationName'] | Keyframes;
|
animationName?: CSS.PropertiesFallback<number | string>['animationName'] | Keyframes;
|
||||||
};
|
};
|
||||||
|
|
@ -52,7 +60,6 @@ export type CSSInterpolation = InterpolationPrimitive | ArrayCSSInterpolation |
|
||||||
|
|
||||||
export type CSSOthersObject = Record<string, CSSInterpolation>;
|
export type CSSOthersObject = Record<string, CSSInterpolation>;
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
export interface CSSObject extends CSSPropertiesWithMultiValues, CSSPseudos, CSSOthersObject {}
|
export interface CSSObject extends CSSPropertiesWithMultiValues, CSSPseudos, CSSOthersObject {}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
@ -107,6 +114,16 @@ export interface ParseInfo {
|
||||||
parentSelectors: string[];
|
parentSelectors: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Global effect style will mount once and not removed
|
||||||
|
// The effect will not save in SSR cache (e.g. keyframes)
|
||||||
|
const globalEffectStyleKeys = new Set();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private Test only. Clear the global effect style keys.
|
||||||
|
*/
|
||||||
|
export const _cf =
|
||||||
|
process.env.NODE_ENV !== 'production' ? () => globalEffectStyleKeys.clear() : undefined;
|
||||||
|
|
||||||
// Parse CSSObject to style content
|
// Parse CSSObject to style content
|
||||||
export const parseStyle = (
|
export const parseStyle = (
|
||||||
interpolation: CSSInterpolation,
|
interpolation: CSSInterpolation,
|
||||||
|
|
@ -241,7 +258,6 @@ export const parseStyle = (
|
||||||
|
|
||||||
styleStr += `${styleName}:${formatValue};`;
|
styleStr += `${styleName}:${formatValue};`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const actualValue = (value as any)?.value ?? value;
|
const actualValue = (value as any)?.value ?? value;
|
||||||
if (
|
if (
|
||||||
typeof value === 'object' &&
|
typeof value === 'object' &&
|
||||||
|
|
@ -279,7 +295,7 @@ export const parseStyle = (
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// == Register ==
|
// == Register ==
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
export function uniqueHash(path: (string | number)[], styleStr: string) {
|
function uniqueHash(path: (string | number)[], styleStr: string) {
|
||||||
return hash(`${path.join('%')}${styleStr}`);
|
return hash(`${path.join('%')}${styleStr}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,17 +303,6 @@ export function uniqueHash(path: (string | number)[], styleStr: string) {
|
||||||
// return null;
|
// return null;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export const STYLE_PREFIX = 'style';
|
|
||||||
|
|
||||||
type StyleCacheValue = [
|
|
||||||
styleStr: string,
|
|
||||||
tokenKey: string,
|
|
||||||
styleId: string,
|
|
||||||
effectStyle: Record<string, string>,
|
|
||||||
clientOnly: boolean | undefined,
|
|
||||||
order: number,
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a style to the global style sheet.
|
* Register a style to the global style sheet.
|
||||||
*/
|
*/
|
||||||
|
|
@ -332,14 +337,22 @@ export default function useStyleRegister(
|
||||||
}
|
}
|
||||||
|
|
||||||
// const [cacheStyle[0], cacheStyle[1], cacheStyle[2]]
|
// const [cacheStyle[0], cacheStyle[1], cacheStyle[2]]
|
||||||
useGlobalCache<StyleCacheValue>(
|
useGlobalCache<
|
||||||
STYLE_PREFIX,
|
[
|
||||||
|
styleStr: string,
|
||||||
|
tokenKey: string,
|
||||||
|
styleId: string,
|
||||||
|
effectStyle: Record<string, string>,
|
||||||
|
clientOnly: boolean | undefined,
|
||||||
|
order: number,
|
||||||
|
]
|
||||||
|
>(
|
||||||
|
'style',
|
||||||
fullPath,
|
fullPath,
|
||||||
// Create cache if needed
|
// Create cache if needed
|
||||||
() => {
|
() => {
|
||||||
const { path, hashId, layer, clientOnly, order = 0 } = info.value;
|
const { path, hashId, layer, nonce, clientOnly, order = 0 } = info.value;
|
||||||
const cachePath = fullPath.value.join('|');
|
const cachePath = fullPath.value.join('|');
|
||||||
|
|
||||||
// Get style from SSR inline style directly
|
// Get style from SSR inline style directly
|
||||||
if (existPath(cachePath)) {
|
if (existPath(cachePath)) {
|
||||||
const [inlineCacheStyleStr, styleHash] = getStyleAndHash(cachePath);
|
const [inlineCacheStyleStr, styleHash] = getStyleAndHash(cachePath);
|
||||||
|
|
@ -347,10 +360,8 @@ export default function useStyleRegister(
|
||||||
return [inlineCacheStyleStr, tokenKey.value, styleHash, {}, clientOnly, order];
|
return [inlineCacheStyleStr, tokenKey.value, styleHash, {}, clientOnly, order];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate style
|
|
||||||
const styleObj = styleFn();
|
const styleObj = styleFn();
|
||||||
const { hashPriority, transformers, linters } = styleContext.value;
|
const { hashPriority, container, transformers, linters, cache } = styleContext.value;
|
||||||
|
|
||||||
const [parsedStyle, effectStyle] = parseStyle(styleObj, {
|
const [parsedStyle, effectStyle] = parseStyle(styleObj, {
|
||||||
hashId,
|
hashId,
|
||||||
|
|
@ -360,32 +371,18 @@ export default function useStyleRegister(
|
||||||
transformers,
|
transformers,
|
||||||
linters,
|
linters,
|
||||||
});
|
});
|
||||||
|
|
||||||
const styleStr = normalizeStyle(parsedStyle);
|
const styleStr = normalizeStyle(parsedStyle);
|
||||||
const styleId = uniqueHash(fullPath.value, styleStr);
|
const styleId = uniqueHash(fullPath.value, styleStr);
|
||||||
|
|
||||||
return [styleStr, tokenKey.value, styleId, effectStyle, clientOnly, order];
|
if (isMergedClientSide) {
|
||||||
},
|
|
||||||
|
|
||||||
// Remove cache if no need
|
|
||||||
([, , styleId], fromHMR) => {
|
|
||||||
if ((fromHMR || styleContext.value.autoClear) && isClientSide) {
|
|
||||||
removeCSS(styleId, { mark: ATTR_MARK });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Effect: Inject style here
|
|
||||||
([styleStr, , styleId, effectStyle]) => {
|
|
||||||
if (isMergedClientSide && styleStr !== CSS_FILE_STYLE) {
|
|
||||||
const mergedCSSConfig: Parameters<typeof updateCSS>[2] = {
|
const mergedCSSConfig: Parameters<typeof updateCSS>[2] = {
|
||||||
mark: ATTR_MARK,
|
mark: ATTR_MARK,
|
||||||
prepend: 'queue',
|
prepend: 'queue',
|
||||||
attachTo: styleContext.value.container,
|
attachTo: container,
|
||||||
priority: info.value.order,
|
priority: order,
|
||||||
};
|
};
|
||||||
|
|
||||||
const nonceStr =
|
const nonceStr = typeof nonce === 'function' ? nonce() : nonce;
|
||||||
typeof info.value.nonce === 'function' ? info.value.nonce() : info.value.nonce;
|
|
||||||
|
|
||||||
if (nonceStr) {
|
if (nonceStr) {
|
||||||
mergedCSSConfig.csp = { nonce: nonceStr };
|
mergedCSSConfig.csp = { nonce: nonceStr };
|
||||||
|
|
@ -393,33 +390,45 @@ export default function useStyleRegister(
|
||||||
|
|
||||||
const style = updateCSS(styleStr, styleId, mergedCSSConfig);
|
const style = updateCSS(styleStr, styleId, mergedCSSConfig);
|
||||||
|
|
||||||
(style as any)[CSS_IN_JS_INSTANCE] = styleContext.value.cache.instanceId;
|
(style as any)[CSS_IN_JS_INSTANCE] = cache.instanceId;
|
||||||
|
|
||||||
// Used for `useCacheToken` to remove on batch when token removed
|
// Used for `useCacheToken` to remove on batch when token removed
|
||||||
style.setAttribute(ATTR_TOKEN, tokenKey.value);
|
style.setAttribute(ATTR_TOKEN, tokenKey.value);
|
||||||
|
|
||||||
// Debug usage. Dev only
|
// Dev usage to find which cache path made this easily
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
style.setAttribute(ATTR_CACHE_PATH, fullPath.value.join('|'));
|
style.setAttribute(ATTR_CACHE_PATH, fullPath.value.join('|'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inject client side effect style
|
// Inject client side effect style
|
||||||
Object.keys(effectStyle).forEach(effectKey => {
|
Object.keys(effectStyle).forEach(effectKey => {
|
||||||
updateCSS(
|
if (!globalEffectStyleKeys.has(effectKey)) {
|
||||||
normalizeStyle(effectStyle[effectKey]),
|
globalEffectStyleKeys.add(effectKey);
|
||||||
`_effect-${effectKey}`,
|
|
||||||
mergedCSSConfig,
|
// Inject
|
||||||
);
|
updateCSS(normalizeStyle(effectStyle[effectKey]), `_effect-${effectKey}`, {
|
||||||
|
mark: ATTR_MARK,
|
||||||
|
prepend: 'queue',
|
||||||
|
attachTo: container,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return [styleStr, tokenKey.value, styleId, effectStyle, clientOnly, order];
|
||||||
|
},
|
||||||
|
// Remove cache if no need
|
||||||
|
([, , styleId], fromHMR) => {
|
||||||
|
if ((fromHMR || styleContext.value.autoClear) && isClientSide) {
|
||||||
|
removeCSS(styleId, { mark: ATTR_MARK });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return (node: VueNode) => {
|
return (node: VueNode) => {
|
||||||
return node;
|
return node;
|
||||||
// let styleNode: VueNode;
|
// let styleNode: VueNode;
|
||||||
|
// if (!styleContext.ssrInline || isMergedClientSide || !styleContext.defaultCache) {
|
||||||
// if (!styleContext.value.ssrInline || isMergedClientSide || !styleContext.value.defaultCache) {
|
|
||||||
// styleNode = <Empty />;
|
// styleNode = <Empty />;
|
||||||
// } else {
|
// } else {
|
||||||
// styleNode = (
|
// styleNode = (
|
||||||
|
|
@ -442,25 +451,78 @@ export default function useStyleRegister(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const extract: ExtractStyle<StyleCacheValue> = (cache, effectStyles, options) => {
|
// ============================================================================
|
||||||
const [styleStr, tokenKey, styleId, effectStyle, clientOnly, order]: StyleCacheValue = cache;
|
// == SSR ==
|
||||||
const { plain } = options || {};
|
// ============================================================================
|
||||||
|
export function extractStyle(cache: Cache, plain = false) {
|
||||||
|
const matchPrefix = `style%`;
|
||||||
|
|
||||||
|
// prefix with `style` is used for `useStyleRegister` to cache style context
|
||||||
|
const styleKeys = Array.from(cache.cache.keys()).filter(key => key.startsWith(matchPrefix));
|
||||||
|
|
||||||
|
// Common effect styles like animation
|
||||||
|
const effectStyles: Record<string, boolean> = {};
|
||||||
|
|
||||||
|
// Mapping of cachePath to style hash
|
||||||
|
const cachePathMap: Record<string, string> = {};
|
||||||
|
|
||||||
|
let styleText = '';
|
||||||
|
|
||||||
|
function toStyleStr(
|
||||||
|
style: string,
|
||||||
|
tokenKey?: string,
|
||||||
|
styleId?: string,
|
||||||
|
customizeAttrs: Record<string, string> = {},
|
||||||
|
) {
|
||||||
|
const attrs: Record<string, string | undefined> = {
|
||||||
|
...customizeAttrs,
|
||||||
|
[ATTR_TOKEN]: tokenKey,
|
||||||
|
[ATTR_MARK]: styleId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const attrStr = Object.keys(attrs)
|
||||||
|
.map(attr => {
|
||||||
|
const val = attrs[attr];
|
||||||
|
return val ? `${attr}="${val}"` : null;
|
||||||
|
})
|
||||||
|
.filter(v => v)
|
||||||
|
.join(' ');
|
||||||
|
|
||||||
|
return plain ? style : `<style ${attrStr}>${style}</style>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====================== Fill Style ======================
|
||||||
|
type OrderStyle = [order: number, style: string];
|
||||||
|
|
||||||
|
const orderStyles: OrderStyle[] = styleKeys
|
||||||
|
.map(key => {
|
||||||
|
const cachePath = key.slice(matchPrefix.length).replace(/%/g, '|');
|
||||||
|
|
||||||
|
const [styleStr, tokenKey, styleId, effectStyle, clientOnly, order]: [
|
||||||
|
string,
|
||||||
|
string,
|
||||||
|
string,
|
||||||
|
Record<string, string>,
|
||||||
|
boolean,
|
||||||
|
number,
|
||||||
|
] = cache.cache.get(key)![1];
|
||||||
|
|
||||||
// Skip client only style
|
// Skip client only style
|
||||||
if (clientOnly) {
|
if (clientOnly) {
|
||||||
return null;
|
return null! as OrderStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
let keyStyleText = styleStr;
|
|
||||||
|
|
||||||
// ====================== Style ======================
|
// ====================== Style ======================
|
||||||
// Used for rc-util
|
// Used for vc-util
|
||||||
const sharedAttrs = {
|
const sharedAttrs = {
|
||||||
'data-vc-order': 'prependQueue',
|
'data-vc-order': 'prependQueue',
|
||||||
'data-vc-priority': `${order}`,
|
'data-vc-priority': `${order}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
keyStyleText = toStyleStr(styleStr, tokenKey, styleId, sharedAttrs, plain);
|
let keyStyleText = toStyleStr(styleStr, tokenKey, styleId, sharedAttrs);
|
||||||
|
|
||||||
|
// Save cache path with hash mapping
|
||||||
|
cachePathMap[cachePath] = styleId;
|
||||||
|
|
||||||
// =============== Create effect style ===============
|
// =============== Create effect style ===============
|
||||||
if (effectStyle) {
|
if (effectStyle) {
|
||||||
|
|
@ -468,17 +530,37 @@ export const extract: ExtractStyle<StyleCacheValue> = (cache, effectStyles, opti
|
||||||
// Effect style can be reused
|
// Effect style can be reused
|
||||||
if (!effectStyles[effectKey]) {
|
if (!effectStyles[effectKey]) {
|
||||||
effectStyles[effectKey] = true;
|
effectStyles[effectKey] = true;
|
||||||
const effectStyleStr = normalizeStyle(effectStyle[effectKey]);
|
|
||||||
keyStyleText += toStyleStr(
|
keyStyleText += toStyleStr(
|
||||||
effectStyleStr,
|
normalizeStyle(effectStyle[effectKey]),
|
||||||
tokenKey,
|
tokenKey,
|
||||||
`_effect-${effectKey}`,
|
`_effect-${effectKey}`,
|
||||||
sharedAttrs,
|
sharedAttrs,
|
||||||
plain,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return [order, styleId, keyStyleText];
|
const ret: OrderStyle = [order, keyStyleText];
|
||||||
};
|
|
||||||
|
return ret;
|
||||||
|
})
|
||||||
|
.filter(o => o);
|
||||||
|
|
||||||
|
orderStyles
|
||||||
|
.sort((o1, o2) => o1[0] - o2[0])
|
||||||
|
.forEach(([, style]) => {
|
||||||
|
styleText += style;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ==================== Fill Cache Path ====================
|
||||||
|
styleText += toStyleStr(
|
||||||
|
`.${ATTR_CACHE_MAP}{content:"${serializeCacheMap(cachePathMap)}";}`,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
[ATTR_CACHE_MAP]: ATTR_CACHE_MAP,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return styleText;
|
||||||
|
}
|
||||||
|
|
@ -1,37 +1,28 @@
|
||||||
import extractStyle from './extractStyle';
|
import useCacheToken from './hooks/useCacheToken';
|
||||||
import useCacheToken, { getComputedToken } from './hooks/useCacheToken';
|
|
||||||
import useCSSVarRegister from './hooks/useCSSVarRegister';
|
|
||||||
import type { CSSInterpolation, CSSObject } from './hooks/useStyleRegister';
|
import type { CSSInterpolation, CSSObject } from './hooks/useStyleRegister';
|
||||||
import useStyleRegister from './hooks/useStyleRegister';
|
import useStyleRegister, { extractStyle } from './hooks/useStyleRegister';
|
||||||
import Keyframes from './Keyframes';
|
import Keyframes from './Keyframes';
|
||||||
import type { Linter } from './linters';
|
import type { Linter } from './linters';
|
||||||
import {
|
import { legacyNotSelectorLinter, logicalPropertiesLinter, parentSelectorLinter } from './linters';
|
||||||
legacyNotSelectorLinter,
|
import type { StyleContextProps, StyleProviderProps } from './StyleContext';
|
||||||
logicalPropertiesLinter,
|
import { createCache, useStyleInject, useStyleProvider, StyleProvider } from './StyleContext';
|
||||||
NaNLinter,
|
|
||||||
parentSelectorLinter,
|
|
||||||
} from './linters';
|
|
||||||
import type { StyleProviderProps } from './StyleContext';
|
|
||||||
import { createCache, StyleProvider } from './StyleContext';
|
|
||||||
import type { DerivativeFunc, TokenType } from './theme';
|
import type { DerivativeFunc, TokenType } from './theme';
|
||||||
import { createTheme, Theme } from './theme';
|
import { createTheme, Theme } from './theme';
|
||||||
import type { Transformer } from './transformers/interface';
|
import type { Transformer } from './transformers/interface';
|
||||||
import legacyLogicalPropertiesTransformer from './transformers/legacyLogicalProperties';
|
import legacyLogicalPropertiesTransformer from './transformers/legacyLogicalProperties';
|
||||||
import px2remTransformer from './transformers/px2rem';
|
import px2remTransformer from './transformers/px2rem';
|
||||||
import { supportLogicProps, supportWhere, unit } from './util';
|
import { supportLogicProps, supportWhere } from './util';
|
||||||
import { token2CSSVar } from './util/css-variables';
|
|
||||||
|
|
||||||
export {
|
const cssinjs = {
|
||||||
Theme,
|
Theme,
|
||||||
createTheme,
|
createTheme,
|
||||||
useStyleRegister,
|
useStyleRegister,
|
||||||
useCSSVarRegister,
|
|
||||||
useCacheToken,
|
useCacheToken,
|
||||||
createCache,
|
createCache,
|
||||||
StyleProvider,
|
useStyleInject,
|
||||||
|
useStyleProvider,
|
||||||
Keyframes,
|
Keyframes,
|
||||||
extractStyle,
|
extractStyle,
|
||||||
getComputedToken,
|
|
||||||
|
|
||||||
// Transformer
|
// Transformer
|
||||||
legacyLogicalPropertiesTransformer,
|
legacyLogicalPropertiesTransformer,
|
||||||
|
|
@ -41,11 +32,32 @@ export {
|
||||||
logicalPropertiesLinter,
|
logicalPropertiesLinter,
|
||||||
legacyNotSelectorLinter,
|
legacyNotSelectorLinter,
|
||||||
parentSelectorLinter,
|
parentSelectorLinter,
|
||||||
NaNLinter,
|
|
||||||
|
|
||||||
// util
|
// cssinjs
|
||||||
token2CSSVar,
|
StyleProvider,
|
||||||
unit,
|
};
|
||||||
|
export {
|
||||||
|
Theme,
|
||||||
|
createTheme,
|
||||||
|
useStyleRegister,
|
||||||
|
useCacheToken,
|
||||||
|
createCache,
|
||||||
|
useStyleInject,
|
||||||
|
useStyleProvider,
|
||||||
|
Keyframes,
|
||||||
|
extractStyle,
|
||||||
|
|
||||||
|
// Transformer
|
||||||
|
legacyLogicalPropertiesTransformer,
|
||||||
|
px2remTransformer,
|
||||||
|
|
||||||
|
// Linters
|
||||||
|
logicalPropertiesLinter,
|
||||||
|
legacyNotSelectorLinter,
|
||||||
|
parentSelectorLinter,
|
||||||
|
|
||||||
|
// cssinjs
|
||||||
|
StyleProvider,
|
||||||
};
|
};
|
||||||
export type {
|
export type {
|
||||||
TokenType,
|
TokenType,
|
||||||
|
|
@ -54,9 +66,12 @@ export type {
|
||||||
DerivativeFunc,
|
DerivativeFunc,
|
||||||
Transformer,
|
Transformer,
|
||||||
Linter,
|
Linter,
|
||||||
|
StyleContextProps,
|
||||||
StyleProviderProps,
|
StyleProviderProps,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const _experimental = {
|
export const _experimental = {
|
||||||
supportModernCSS: () => supportWhere() && supportLogicProps(),
|
supportModernCSS: () => supportWhere() && supportLogicProps(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default cssinjs;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import type { Linter } from './interface';
|
|
||||||
import { lintWarning } from './utils';
|
|
||||||
|
|
||||||
const linter: Linter = (key, value, info) => {
|
|
||||||
if ((typeof value === 'string' && /NaN/g.test(value)) || Number.isNaN(value)) {
|
|
||||||
lintWarning(`Unexpected 'NaN' in property '${key}: ${value}'.`, info);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default linter;
|
|
||||||
|
|
@ -3,5 +3,4 @@ export { default as hashedAnimationLinter } from './hashedAnimationLinter';
|
||||||
export type { Linter } from './interface';
|
export type { Linter } from './interface';
|
||||||
export { default as legacyNotSelectorLinter } from './legacyNotSelectorLinter';
|
export { default as legacyNotSelectorLinter } from './legacyNotSelectorLinter';
|
||||||
export { default as logicalPropertiesLinter } from './logicalPropertiesLinter';
|
export { default as logicalPropertiesLinter } from './logicalPropertiesLinter';
|
||||||
export { default as NaNLinter } from './NaNLinter';
|
|
||||||
export { default as parentSelectorLinter } from './parentSelectorLinter';
|
export { default as parentSelectorLinter } from './parentSelectorLinter';
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ export function lintWarning(message: string, info: LinterInfo) {
|
||||||
|
|
||||||
devWarning(
|
devWarning(
|
||||||
false,
|
false,
|
||||||
`[Ant Design Vue CSS-in-JS] ${path ? `Error in ${path}: ` : ''}${message}${
|
`[Ant Design Vue CSS-in-JS] ${path ? `Error in '${path}': ` : ''}${message}${
|
||||||
parentSelectors.length ? ` Selector: ${parentSelectors.join(' | ')}` : ''
|
parentSelectors.length ? ` Selector info: ${parentSelectors.join(' -> ')}` : ''
|
||||||
}`,
|
}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,34 @@
|
||||||
import type { CSSObject } from '..';
|
import type { CSSObject } from '..';
|
||||||
import type { Transformer } from './interface';
|
import type { Transformer } from './interface';
|
||||||
|
|
||||||
function splitValues(value: string | number): [values: (string | number)[], important: boolean] {
|
function splitValues(value: string | number) {
|
||||||
if (typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
return [[value], false];
|
return [value];
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawStyle = String(value).trim();
|
const splitStyle = String(value).split(/\s+/);
|
||||||
const importantCells = rawStyle.match(/(.*)(!important)/);
|
|
||||||
|
|
||||||
const splitStyle = (importantCells ? importantCells[1] : rawStyle).trim().split(/\s+/);
|
|
||||||
|
|
||||||
// Combine styles split in brackets, like `calc(1px + 2px)`
|
// Combine styles split in brackets, like `calc(1px + 2px)`
|
||||||
let temp = '';
|
let temp = '';
|
||||||
let brackets = 0;
|
let brackets = 0;
|
||||||
return [
|
return splitStyle.reduce<string[]>((list, item) => {
|
||||||
splitStyle.reduce<string[]>((list, item) => {
|
if (item.includes('(')) {
|
||||||
if (item.includes('(') || item.includes(')')) {
|
|
||||||
const left = item.split('(').length - 1;
|
|
||||||
const right = item.split(')').length - 1;
|
|
||||||
brackets += left - right;
|
|
||||||
}
|
|
||||||
if (brackets === 0) {
|
|
||||||
list.push(temp + item);
|
|
||||||
temp = '';
|
|
||||||
} else if (brackets > 0) {
|
|
||||||
temp += item;
|
temp += item;
|
||||||
|
brackets += item.split('(').length - 1;
|
||||||
|
} else if (item.includes(')')) {
|
||||||
|
temp += ` ${item}`;
|
||||||
|
brackets -= item.split(')').length - 1;
|
||||||
|
if (brackets === 0) {
|
||||||
|
list.push(temp);
|
||||||
|
temp = '';
|
||||||
|
}
|
||||||
|
} else if (brackets > 0) {
|
||||||
|
temp += ` ${item}`;
|
||||||
|
} else {
|
||||||
|
list.push(item);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}, []),
|
}, []);
|
||||||
!!importantCells,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MatchValue = string[] & {
|
type MatchValue = string[] & {
|
||||||
|
|
@ -107,14 +105,8 @@ const keyMap: Record<string, MatchValue> = {
|
||||||
borderEndEndRadius: ['borderBottomRightRadius'],
|
borderEndEndRadius: ['borderBottomRightRadius'],
|
||||||
};
|
};
|
||||||
|
|
||||||
function wrapImportantAndSkipCheck(value: string | number, important: boolean) {
|
function skipCheck(value: string | number) {
|
||||||
let parsedValue = value;
|
return { _skip_check_: true, value };
|
||||||
|
|
||||||
if (important) {
|
|
||||||
parsedValue = `${parsedValue} !important`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { _skip_check_: true, value: parsedValue };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -135,28 +127,25 @@ const transform: Transformer = {
|
||||||
const matchValue = keyMap[key];
|
const matchValue = keyMap[key];
|
||||||
|
|
||||||
if (matchValue && (typeof value === 'number' || typeof value === 'string')) {
|
if (matchValue && (typeof value === 'number' || typeof value === 'string')) {
|
||||||
const [values, important] = splitValues(value);
|
const values = splitValues(value);
|
||||||
|
|
||||||
if (matchValue.length && matchValue.notSplit) {
|
if (matchValue.length && matchValue.notSplit) {
|
||||||
// not split means always give same value like border
|
// not split means always give same value like border
|
||||||
matchValue.forEach(matchKey => {
|
matchValue.forEach(matchKey => {
|
||||||
clone[matchKey] = wrapImportantAndSkipCheck(value, important);
|
clone[matchKey] = skipCheck(value);
|
||||||
});
|
});
|
||||||
} else if (matchValue.length === 1) {
|
} else if (matchValue.length === 1) {
|
||||||
// Handle like `marginBlockStart` => `marginTop`
|
// Handle like `marginBlockStart` => `marginTop`
|
||||||
clone[matchValue[0]] = wrapImportantAndSkipCheck(value, important);
|
clone[matchValue[0]] = skipCheck(value);
|
||||||
} else if (matchValue.length === 2) {
|
} else if (matchValue.length === 2) {
|
||||||
// Handle like `marginBlock` => `marginTop` & `marginBottom`
|
// Handle like `marginBlock` => `marginTop` & `marginBottom`
|
||||||
matchValue.forEach((matchKey, index) => {
|
matchValue.forEach((matchKey, index) => {
|
||||||
clone[matchKey] = wrapImportantAndSkipCheck(values[index] ?? values[0], important);
|
clone[matchKey] = skipCheck(values[index] ?? values[0]);
|
||||||
});
|
});
|
||||||
} else if (matchValue.length === 4) {
|
} else if (matchValue.length === 4) {
|
||||||
// Handle like `inset` => `top` & `right` & `bottom` & `left`
|
// Handle like `inset` => `top` & `right` & `bottom` & `left`
|
||||||
matchValue.forEach((matchKey, index) => {
|
matchValue.forEach((matchKey, index) => {
|
||||||
clone[matchKey] = wrapImportantAndSkipCheck(
|
clone[matchKey] = skipCheck(values[index] ?? values[index - 2] ?? values[0]);
|
||||||
values[index] ?? values[index - 2] ?? values[0],
|
|
||||||
important,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
clone[key] = value;
|
clone[key] = value;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* respect https://github.com/cuth/postcss-pxtorem
|
* respect https://github.com/cuth/postcss-pxtorem
|
||||||
*/
|
*/
|
||||||
// @ts-ignore
|
|
||||||
import unitless from '@emotion/unitless';
|
import unitless from '@emotion/unitless';
|
||||||
import type { CSSObject } from '..';
|
import type { CSSObject } from '..';
|
||||||
import type { Transformer } from './interface';
|
import type { Transformer } from './interface';
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,12 @@
|
||||||
import hash from '@emotion/hash';
|
import hash from '@emotion/hash';
|
||||||
import canUseDom from '../../canUseDom';
|
import { removeCSS, updateCSS } from '../../vc-util/Dom/dynamicCSS';
|
||||||
import { removeCSS, updateCSS } from '../../../vc-util/Dom/dynamicCSS';
|
import canUseDom from '../canUseDom';
|
||||||
import { ATTR_MARK, ATTR_TOKEN } from '../StyleContext';
|
|
||||||
import { Theme } from '../theme';
|
|
||||||
|
|
||||||
// Create a cache for memo concat
|
import { Theme } from './theme';
|
||||||
type NestWeakMap<T> = WeakMap<object, NestWeakMap<T> | T>;
|
|
||||||
const resultCache: NestWeakMap<object> = new WeakMap();
|
|
||||||
const RESULT_VALUE = {};
|
|
||||||
|
|
||||||
export function memoResult<T extends object, R>(callback: () => R, deps: T[]): R {
|
|
||||||
let current: WeakMap<any, any> = resultCache;
|
|
||||||
for (let i = 0; i < deps.length; i += 1) {
|
|
||||||
const dep = deps[i];
|
|
||||||
if (!current.has(dep)) {
|
|
||||||
current.set(dep, new WeakMap());
|
|
||||||
}
|
|
||||||
current = current.get(dep)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!current.has(RESULT_VALUE)) {
|
|
||||||
current.set(RESULT_VALUE, callback());
|
|
||||||
}
|
|
||||||
|
|
||||||
return current.get(RESULT_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a cache here to avoid always loop generate
|
// Create a cache here to avoid always loop generate
|
||||||
const flattenTokenCache = new WeakMap<any, string>();
|
const flattenTokenCache = new WeakMap<any, string>();
|
||||||
|
|
||||||
/**
|
|
||||||
* Flatten token to string, this will auto cache the result when token not change
|
|
||||||
*/
|
|
||||||
export function flattenToken(token: any) {
|
export function flattenToken(token: any) {
|
||||||
let str = flattenTokenCache.get(token) || '';
|
let str = flattenTokenCache.get(token) || '';
|
||||||
|
|
||||||
|
|
@ -141,39 +116,3 @@ export function supportLogicProps(): boolean {
|
||||||
|
|
||||||
return canLogic!;
|
return canLogic!;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isClientSide = canUseDom();
|
|
||||||
|
|
||||||
export function unit(num: string | number) {
|
|
||||||
if (typeof num === 'number') {
|
|
||||||
return `${num}px`;
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toStyleStr(
|
|
||||||
style: string,
|
|
||||||
tokenKey?: string,
|
|
||||||
styleId?: string,
|
|
||||||
customizeAttrs: Record<string, string> = {},
|
|
||||||
plain = false,
|
|
||||||
) {
|
|
||||||
if (plain) {
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
const attrs: Record<string, string | undefined> = {
|
|
||||||
...customizeAttrs,
|
|
||||||
[ATTR_TOKEN]: tokenKey,
|
|
||||||
[ATTR_MARK]: styleId,
|
|
||||||
};
|
|
||||||
|
|
||||||
const attrStr = Object.keys(attrs)
|
|
||||||
.map(attr => {
|
|
||||||
const val = attrs[attr];
|
|
||||||
return val ? `${attr}="${val}"` : null;
|
|
||||||
})
|
|
||||||
.filter(v => v)
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
return `<style ${attrStr}>${style}</style>`;
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
export const token2CSSVar = (token: string, prefix = '') => {
|
|
||||||
return `--${prefix ? `${prefix}-` : ''}${token}`
|
|
||||||
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
||||||
.replace(/([A-Z]+)([A-Z][a-z0-9]+)/g, '$1-$2')
|
|
||||||
.replace(/([a-z])([A-Z0-9])/g, '$1-$2')
|
|
||||||
.toLowerCase();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const serializeCSSVar = <T extends Record<string, any>>(
|
|
||||||
cssVars: T,
|
|
||||||
hashId: string,
|
|
||||||
options?: {
|
|
||||||
scope?: string;
|
|
||||||
},
|
|
||||||
) => {
|
|
||||||
if (!Object.keys(cssVars).length) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return `.${hashId}${options?.scope ? `.${options.scope}` : ''}{${Object.entries(cssVars)
|
|
||||||
.map(([key, value]) => `${key}:${value};`)
|
|
||||||
.join('')}}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TokenWithCSSVar<V, T extends Record<string, V> = Record<string, V>> = {
|
|
||||||
[key in keyof T]?: string | V;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const transformToken = <V, T extends Record<string, V> = Record<string, V>>(
|
|
||||||
token: T,
|
|
||||||
themeKey: string,
|
|
||||||
config?: {
|
|
||||||
prefix?: string;
|
|
||||||
ignore?: {
|
|
||||||
[key in keyof T]?: boolean;
|
|
||||||
};
|
|
||||||
unitless?: {
|
|
||||||
[key in keyof T]?: boolean;
|
|
||||||
};
|
|
||||||
preserve?: {
|
|
||||||
[key in keyof T]?: boolean;
|
|
||||||
};
|
|
||||||
scope?: string;
|
|
||||||
},
|
|
||||||
): [TokenWithCSSVar<V, T>, string] => {
|
|
||||||
const cssVars: Record<string, string> = {};
|
|
||||||
const result: TokenWithCSSVar<V, T> = {};
|
|
||||||
Object.entries(token).forEach(([key, value]) => {
|
|
||||||
if (config?.preserve?.[key]) {
|
|
||||||
result[key as keyof T] = value;
|
|
||||||
} else if ((typeof value === 'string' || typeof value === 'number') && !config?.ignore?.[key]) {
|
|
||||||
const cssVar = token2CSSVar(key, config?.prefix);
|
|
||||||
cssVars[cssVar] =
|
|
||||||
typeof value === 'number' && !config?.unitless?.[key] ? `${value}px` : String(value);
|
|
||||||
result[key as keyof T] = `var(${cssVar})`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return [result, serializeCSSVar(cssVars, themeKey, { scope: config?.scope })];
|
|
||||||
};
|
|
||||||
|
|
@ -2,31 +2,32 @@ export function isWindow(obj: any): obj is Window {
|
||||||
return obj !== null && obj !== undefined && obj === obj.window;
|
return obj !== null && obj !== undefined && obj === obj.window;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getScroll = (target: HTMLElement | Window | Document | null): number => {
|
export default function getScroll(
|
||||||
|
target: HTMLElement | Window | Document | null,
|
||||||
|
top: boolean,
|
||||||
|
): number {
|
||||||
if (typeof window === 'undefined') {
|
if (typeof window === 'undefined') {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
const method = top ? 'scrollTop' : 'scrollLeft';
|
||||||
let result = 0;
|
let result = 0;
|
||||||
if (isWindow(target)) {
|
if (isWindow(target)) {
|
||||||
result = target.pageYOffset;
|
result = target[top ? 'scrollY' : 'scrollX'];
|
||||||
} else if (target instanceof Document) {
|
} else if (target instanceof Document) {
|
||||||
result = target.documentElement.scrollTop;
|
result = target.documentElement[method];
|
||||||
} else if (target instanceof HTMLElement) {
|
} else if (target instanceof HTMLElement) {
|
||||||
result = target.scrollTop;
|
result = target[method];
|
||||||
} else if (target) {
|
} else if (target) {
|
||||||
// According to the type inference, the `target` is `never` type.
|
// According to the type inference, the `target` is `never` type.
|
||||||
// Since we configured the loose mode type checking, and supports mocking the target with such shape below::
|
// Since we configured the loose mode type checking, and supports mocking the target with such shape below::
|
||||||
// `{ documentElement: { scrollLeft: 200, scrollTop: 400 } }`,
|
// `{ documentElement: { scrollLeft: 200, scrollTop: 400 } }`,
|
||||||
// the program may falls into this branch.
|
// the program may falls into this branch.
|
||||||
// Check the corresponding tests for details. Don't sure what is the real scenario this happens.
|
// Check the corresponding tests for details. Don't sure what is the real scenario this happens.
|
||||||
/* biome-ignore lint/complexity/useLiteralKeys: target is a never type */ /* eslint-disable-next-line dot-notation */
|
result = target[method];
|
||||||
result = target['scrollTop'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target && !isWindow(target) && typeof result !== 'number') {
|
if (target && !isWindow(target) && typeof result !== 'number') {
|
||||||
result = (target.ownerDocument ?? (target as Document)).documentElement?.scrollTop;
|
result = ((target.ownerDocument ?? target) as any).documentElement?.[method];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
}
|
||||||
|
|
||||||
export default getScroll;
|
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
import type { Ref, ShallowRef } from 'vue';
|
|
||||||
|
|
||||||
import { shallowRef, ref, watch, nextTick, onMounted, onUnmounted } from 'vue';
|
|
||||||
|
|
||||||
function useLayoutEffect(
|
|
||||||
fn: (mount: boolean) => void | VoidFunction,
|
|
||||||
deps?: Ref<any> | Ref<any>[] | ShallowRef<any> | ShallowRef<any>[],
|
|
||||||
) {
|
|
||||||
const firstMount = shallowRef(true);
|
|
||||||
const cleanupFn = ref(null);
|
|
||||||
let stopWatch = null;
|
|
||||||
|
|
||||||
stopWatch = watch(
|
|
||||||
deps,
|
|
||||||
() => {
|
|
||||||
nextTick(() => {
|
|
||||||
if (cleanupFn.value) {
|
|
||||||
cleanupFn.value();
|
|
||||||
}
|
|
||||||
cleanupFn.value = fn(firstMount.value);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
{ immediate: true, flush: 'post' },
|
|
||||||
);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
firstMount.value = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
if (cleanupFn.value) {
|
|
||||||
cleanupFn.value();
|
|
||||||
}
|
|
||||||
if (stopWatch) {
|
|
||||||
stopWatch();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useLayoutUpdateEffect = (callback, deps) => {
|
|
||||||
useLayoutEffect(firstMount => {
|
|
||||||
if (!firstMount) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
}, deps);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useLayoutEffect;
|
|
||||||
|
|
@ -14,7 +14,7 @@ interface ScrollToOptions {
|
||||||
export default function scrollTo(y: number, options: ScrollToOptions = {}) {
|
export default function scrollTo(y: number, options: ScrollToOptions = {}) {
|
||||||
const { getContainer = () => window, callback, duration = 450 } = options;
|
const { getContainer = () => window, callback, duration = 450 } = options;
|
||||||
const container = getContainer();
|
const container = getContainer();
|
||||||
const scrollTop = getScroll(container);
|
const scrollTop = getScroll(container, true);
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
const frameFunc = () => {
|
const frameFunc = () => {
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,10 @@ import useStyle from './style';
|
||||||
function getDefaultTarget() {
|
function getDefaultTarget() {
|
||||||
return typeof window !== 'undefined' ? window : null;
|
return typeof window !== 'undefined' ? window : null;
|
||||||
}
|
}
|
||||||
const AFFIX_STATUS_NONE = 0;
|
enum AffixStatus {
|
||||||
const AFFIX_STATUS_PREPARE = 1;
|
None,
|
||||||
|
Prepare,
|
||||||
type AffixStatus = typeof AFFIX_STATUS_NONE | typeof AFFIX_STATUS_PREPARE;
|
}
|
||||||
|
|
||||||
export interface AffixState {
|
export interface AffixState {
|
||||||
affixStyle?: CSSProperties;
|
affixStyle?: CSSProperties;
|
||||||
placeholderStyle?: CSSProperties;
|
placeholderStyle?: CSSProperties;
|
||||||
|
|
@ -83,7 +82,7 @@ const Affix = defineComponent({
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
affixStyle: undefined,
|
affixStyle: undefined,
|
||||||
placeholderStyle: undefined,
|
placeholderStyle: undefined,
|
||||||
status: AFFIX_STATUS_NONE,
|
status: AffixStatus.None,
|
||||||
lastAffix: false,
|
lastAffix: false,
|
||||||
prevTarget: null,
|
prevTarget: null,
|
||||||
timeout: null,
|
timeout: null,
|
||||||
|
|
@ -99,12 +98,7 @@ const Affix = defineComponent({
|
||||||
const measure = () => {
|
const measure = () => {
|
||||||
const { status, lastAffix } = state;
|
const { status, lastAffix } = state;
|
||||||
const { target } = props;
|
const { target } = props;
|
||||||
if (
|
if (status !== AffixStatus.Prepare || !fixedNode.value || !placeholderNode.value || !target) {
|
||||||
status !== AFFIX_STATUS_PREPARE ||
|
|
||||||
!fixedNode.value ||
|
|
||||||
!placeholderNode.value ||
|
|
||||||
!target
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +108,7 @@ const Affix = defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
const newState = {
|
const newState = {
|
||||||
status: AFFIX_STATUS_NONE,
|
status: AffixStatus.None,
|
||||||
} as AffixState;
|
} as AffixState;
|
||||||
const placeholderRect = getTargetRect(placeholderNode.value as HTMLElement);
|
const placeholderRect = getTargetRect(placeholderNode.value as HTMLElement);
|
||||||
|
|
||||||
|
|
@ -178,7 +172,7 @@ const Affix = defineComponent({
|
||||||
};
|
};
|
||||||
const prepareMeasure = () => {
|
const prepareMeasure = () => {
|
||||||
Object.assign(state, {
|
Object.assign(state, {
|
||||||
status: AFFIX_STATUS_PREPARE,
|
status: AffixStatus.Prepare,
|
||||||
affixStyle: undefined,
|
affixStyle: undefined,
|
||||||
placeholderStyle: undefined,
|
placeholderStyle: undefined,
|
||||||
});
|
});
|
||||||
|
|
@ -259,13 +253,12 @@ const Affix = defineComponent({
|
||||||
});
|
});
|
||||||
|
|
||||||
const { prefixCls } = useConfigInject('affix', props);
|
const { prefixCls } = useConfigInject('affix', props);
|
||||||
const [wrapSSR, hashId, cssVarCls] = useStyle(prefixCls);
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
return () => {
|
return () => {
|
||||||
const { affixStyle, placeholderStyle, status } = state;
|
const { affixStyle, placeholderStyle, status } = state;
|
||||||
const className = classNames({
|
const className = classNames({
|
||||||
[prefixCls.value]: affixStyle,
|
[prefixCls.value]: affixStyle,
|
||||||
[hashId.value]: true,
|
[hashId.value]: true,
|
||||||
[cssVarCls.value]: true,
|
|
||||||
});
|
});
|
||||||
const restProps = omit(props, [
|
const restProps = omit(props, [
|
||||||
'prefixCls',
|
'prefixCls',
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,15 @@
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
import type { CSSObject } from '../../_util/cssinjs';
|
||||||
import { FullToken, GenerateStyle, genStyleHooks, GetDefaultToken } from '../../theme/internal';
|
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||||
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
export interface ComponentToken {
|
|
||||||
/**
|
|
||||||
* @desc 弹出层的 z-index
|
|
||||||
* @descEN z-index of popup
|
|
||||||
*/
|
|
||||||
zIndexPopup: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AffixToken extends FullToken<'Affix'> {
|
interface AffixToken extends FullToken<'Affix'> {
|
||||||
//
|
zIndexPopup: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================== Shared ==============================
|
// ============================== Shared ==============================
|
||||||
const genSharedAffixStyle: GenerateStyle<AffixToken> = (token): CSSObject => {
|
const genSharedAffixStyle: GenerateStyle<AffixToken> = (token): CSSObject => {
|
||||||
const { componentCls } = token;
|
const { componentCls } = token;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[componentCls]: {
|
[componentCls]: {
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
|
|
@ -24,9 +18,10 @@ const genSharedAffixStyle: GenerateStyle<AffixToken> = (token): CSSObject => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const prepareComponentToken: GetDefaultToken<'Affix'> = token => ({
|
|
||||||
zIndexPopup: token.zIndexBase + 10,
|
|
||||||
});
|
|
||||||
|
|
||||||
// ============================== Export ==============================
|
// ============================== Export ==============================
|
||||||
export default genStyleHooks('Affix', genSharedAffixStyle, prepareComponentToken);
|
export default genComponentStyleHook('Affix', token => {
|
||||||
|
const affixToken = mergeToken<AffixToken>(token, {
|
||||||
|
zIndexPopup: token.zIndexBase + 10,
|
||||||
|
});
|
||||||
|
return [genSharedAffixStyle(affixToken)];
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,8 @@ export function getTargetRect(target: BindElement): DOMRect {
|
||||||
: ({ top: 0, bottom: window.innerHeight } as DOMRect);
|
: ({ top: 0, bottom: window.innerHeight } as DOMRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFixedTop(placeholderRect: DOMRect, targetRect: DOMRect, offsetTop?: number) {
|
export function getFixedTop(placeholderRect: DOMRect, targetRect: DOMRect, offsetTop: number) {
|
||||||
if (
|
if (offsetTop !== undefined && targetRect.top > placeholderRect.top - offsetTop) {
|
||||||
offsetTop !== undefined &&
|
|
||||||
Math.round(targetRect.top) > Math.round(placeholderRect.top) - offsetTop
|
|
||||||
) {
|
|
||||||
return `${offsetTop + targetRect.top}px`;
|
return `${offsetTop + targetRect.top}px`;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -22,12 +19,9 @@ export function getFixedTop(placeholderRect: DOMRect, targetRect: DOMRect, offse
|
||||||
export function getFixedBottom(
|
export function getFixedBottom(
|
||||||
placeholderRect: DOMRect,
|
placeholderRect: DOMRect,
|
||||||
targetRect: DOMRect,
|
targetRect: DOMRect,
|
||||||
offsetBottom?: number,
|
offsetBottom: number,
|
||||||
) {
|
) {
|
||||||
if (
|
if (offsetBottom !== undefined && targetRect.bottom < placeholderRect.bottom + offsetBottom) {
|
||||||
offsetBottom !== undefined &&
|
|
||||||
Math.round(targetRect.bottom) < Math.round(placeholderRect.bottom) + offsetBottom
|
|
||||||
) {
|
|
||||||
const targetBottomOffset = window.innerHeight - targetRect.bottom;
|
const targetBottomOffset = window.innerHeight - targetRect.bottom;
|
||||||
return `${offsetBottom + targetBottomOffset}px`;
|
return `${offsetBottom + targetBottomOffset}px`;
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +29,7 @@ export function getFixedBottom(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================== Observer ========================
|
// ======================== Observer ========================
|
||||||
const TRIGGER_EVENTS: (keyof WindowEventMap)[] = [
|
const TRIGGER_EVENTS = [
|
||||||
'resize',
|
'resize',
|
||||||
'scroll',
|
'scroll',
|
||||||
'touchstart',
|
'touchstart',
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ const Alert = defineComponent({
|
||||||
props: alertProps(),
|
props: alertProps(),
|
||||||
setup(props, { slots, emit, attrs, expose }) {
|
setup(props, { slots, emit, attrs, expose }) {
|
||||||
const { prefixCls, direction } = useConfigInject('alert', props);
|
const { prefixCls, direction } = useConfigInject('alert', props);
|
||||||
const [wrapSSR, hashId, cssVarCls] = useStyle(prefixCls);
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
const closing = shallowRef(false);
|
const closing = shallowRef(false);
|
||||||
const closed = shallowRef(false);
|
const closed = shallowRef(false);
|
||||||
const alertNode = shallowRef();
|
const alertNode = shallowRef();
|
||||||
|
|
@ -134,7 +134,6 @@ const Alert = defineComponent({
|
||||||
[`${prefixClsValue}-closable`]: closable,
|
[`${prefixClsValue}-closable`]: closable,
|
||||||
[`${prefixClsValue}-rtl`]: direction.value === 'rtl',
|
[`${prefixClsValue}-rtl`]: direction.value === 'rtl',
|
||||||
[hashId.value]: true,
|
[hashId.value]: true,
|
||||||
[cssVarCls.value]: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const closeIcon = closable ? (
|
const closeIcon = closable ? (
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,13 @@
|
||||||
import { CSSObject, unit } from '../../_util/cssinjs';
|
import type { CSSInterpolation, CSSObject } from '../../_util/cssinjs';
|
||||||
import { FullToken, GenerateStyle, genStyleHooks, GetDefaultToken } from '../../theme/internal';
|
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||||
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
import { resetComponent } from '../../style';
|
import { resetComponent } from '../../style';
|
||||||
import { CSSProperties } from 'vue';
|
|
||||||
|
|
||||||
export interface ComponentToken {
|
export interface ComponentToken {}
|
||||||
// Component token here
|
|
||||||
/**
|
|
||||||
* @desc 默认内间距
|
|
||||||
* @descEN Default padding
|
|
||||||
*/
|
|
||||||
defaultPadding: CSSProperties['padding'];
|
|
||||||
/**
|
|
||||||
* @desc 带有描述的内间距
|
|
||||||
* @descEN Padding with description
|
|
||||||
*/
|
|
||||||
withDescriptionPadding: CSSProperties['padding'];
|
|
||||||
/**
|
|
||||||
* @desc 带有描述时的图标尺寸
|
|
||||||
* @descEN Icon size with description
|
|
||||||
*/
|
|
||||||
withDescriptionIconSize: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
type AlertToken = FullToken<'Alert'> & {
|
type AlertToken = FullToken<'Alert'> & {
|
||||||
// Custom token here
|
alertIconSizeLG: number;
|
||||||
|
alertPaddingHorizontal: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const genAlertTypeStyle = (
|
const genAlertTypeStyle = (
|
||||||
|
|
@ -33,8 +17,8 @@ const genAlertTypeStyle = (
|
||||||
token: AlertToken,
|
token: AlertToken,
|
||||||
alertCls: string,
|
alertCls: string,
|
||||||
): CSSObject => ({
|
): CSSObject => ({
|
||||||
background: bgColor,
|
backgroundColor: bgColor,
|
||||||
border: `${unit(token.lineWidth)} ${token.lineType} ${borderColor}`,
|
border: `${token.lineWidth}px ${token.lineType} ${borderColor}`,
|
||||||
[`${alertCls}-icon`]: {
|
[`${alertCls}-icon`]: {
|
||||||
color: iconColor,
|
color: iconColor,
|
||||||
},
|
},
|
||||||
|
|
@ -51,11 +35,12 @@ export const genBaseStyle: GenerateStyle<AlertToken> = (token: AlertToken): CSSO
|
||||||
lineHeight,
|
lineHeight,
|
||||||
borderRadiusLG: borderRadius,
|
borderRadiusLG: borderRadius,
|
||||||
motionEaseInOutCirc,
|
motionEaseInOutCirc,
|
||||||
withDescriptionIconSize,
|
alertIconSizeLG,
|
||||||
colorText,
|
colorText,
|
||||||
colorTextHeading,
|
paddingContentVerticalSM,
|
||||||
withDescriptionPadding,
|
alertPaddingHorizontal,
|
||||||
defaultPadding,
|
paddingMD,
|
||||||
|
paddingContentHorizontalLG,
|
||||||
} = token;
|
} = token;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -64,7 +49,7 @@ export const genBaseStyle: GenerateStyle<AlertToken> = (token: AlertToken): CSSO
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
padding: defaultPadding,
|
padding: `${paddingContentVerticalSM}px ${alertPaddingHorizontal}px`, // Fixed horizontal padding here.
|
||||||
wordWrap: 'break-word',
|
wordWrap: 'break-word',
|
||||||
borderRadius,
|
borderRadius,
|
||||||
|
|
||||||
|
|
@ -82,14 +67,14 @@ export const genBaseStyle: GenerateStyle<AlertToken> = (token: AlertToken): CSSO
|
||||||
lineHeight: 0,
|
lineHeight: 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
'&-description': {
|
[`&-description`]: {
|
||||||
display: 'none',
|
display: 'none',
|
||||||
fontSize,
|
fontSize,
|
||||||
lineHeight,
|
lineHeight,
|
||||||
},
|
},
|
||||||
|
|
||||||
'&-message': {
|
'&-message': {
|
||||||
color: colorTextHeading,
|
color: colorText,
|
||||||
},
|
},
|
||||||
|
|
||||||
[`&${componentCls}-motion-leave`]: {
|
[`&${componentCls}-motion-leave`]: {
|
||||||
|
|
@ -111,23 +96,24 @@ export const genBaseStyle: GenerateStyle<AlertToken> = (token: AlertToken): CSSO
|
||||||
|
|
||||||
[`${componentCls}-with-description`]: {
|
[`${componentCls}-with-description`]: {
|
||||||
alignItems: 'flex-start',
|
alignItems: 'flex-start',
|
||||||
padding: withDescriptionPadding,
|
paddingInline: paddingContentHorizontalLG,
|
||||||
|
paddingBlock: paddingMD,
|
||||||
|
|
||||||
[`${componentCls}-icon`]: {
|
[`${componentCls}-icon`]: {
|
||||||
marginInlineEnd: marginSM,
|
marginInlineEnd: marginSM,
|
||||||
fontSize: withDescriptionIconSize,
|
fontSize: alertIconSizeLG,
|
||||||
lineHeight: 0,
|
lineHeight: 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-message`]: {
|
[`${componentCls}-message`]: {
|
||||||
display: 'block',
|
display: 'block',
|
||||||
marginBottom: marginXS,
|
marginBottom: marginXS,
|
||||||
color: colorTextHeading,
|
color: colorText,
|
||||||
fontSize: fontSizeLG,
|
fontSize: fontSizeLG,
|
||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-description`]: {
|
[`${componentCls}-description`]: {
|
||||||
display: 'block',
|
display: 'block',
|
||||||
color: colorText,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -201,7 +187,7 @@ export const genActionStyle: GenerateStyle<AlertToken> = (token: AlertToken): CS
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[componentCls]: {
|
[componentCls]: {
|
||||||
'&-action': {
|
[`&-action`]: {
|
||||||
marginInlineStart: marginXS,
|
marginInlineStart: marginXS,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -210,7 +196,7 @@ export const genActionStyle: GenerateStyle<AlertToken> = (token: AlertToken): CS
|
||||||
padding: 0,
|
padding: 0,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
fontSize: fontSizeIcon,
|
fontSize: fontSizeIcon,
|
||||||
lineHeight: unit(fontSizeIcon),
|
lineHeight: `${fontSizeIcon}px`,
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
outline: 'none',
|
outline: 'none',
|
||||||
|
|
@ -236,17 +222,19 @@ export const genActionStyle: GenerateStyle<AlertToken> = (token: AlertToken): CS
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const prepareComponentToken: GetDefaultToken<'Alert'> = token => {
|
export const genAlertStyle: GenerateStyle<AlertToken> = (token: AlertToken): CSSInterpolation => [
|
||||||
const paddingHorizontal = 12; // Fixed value here.
|
genBaseStyle(token),
|
||||||
return {
|
genTypeStyle(token),
|
||||||
withDescriptionIconSize: token.fontSizeHeading3,
|
genActionStyle(token),
|
||||||
defaultPadding: `${token.paddingContentVerticalSM}px ${paddingHorizontal}px`,
|
];
|
||||||
withDescriptionPadding: `${token.paddingMD}px ${token.paddingContentHorizontalLG}px`,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default genStyleHooks(
|
export default genComponentStyleHook('Alert', token => {
|
||||||
'Alert',
|
const { fontSizeHeading3 } = token;
|
||||||
token => [genBaseStyle(token), genTypeStyle(token), genActionStyle(token)],
|
|
||||||
prepareComponentToken,
|
const alertToken = mergeToken<AlertToken>(token, {
|
||||||
);
|
alertIconSizeLG: fontSizeHeading3,
|
||||||
|
alertPaddingHorizontal: 12, // Fixed value here.
|
||||||
|
});
|
||||||
|
|
||||||
|
return [genAlertStyle(alertToken)];
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import AnchorLink from './AnchorLink';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import devWarning from '../vc-util/devWarning';
|
import devWarning from '../vc-util/devWarning';
|
||||||
import { arrayType } from '../_util/type';
|
import { arrayType } from '../_util/type';
|
||||||
import useCSSVarCls from '../config-provider/hooks/useCssVarCls';
|
|
||||||
|
|
||||||
export type AnchorDirection = 'vertical' | 'horizontal';
|
export type AnchorDirection = 'vertical' | 'horizontal';
|
||||||
|
|
||||||
|
|
@ -40,7 +39,8 @@ function getOffsetTop(element: HTMLElement, container: AnchorContainer): number
|
||||||
|
|
||||||
if (rect.width || rect.height) {
|
if (rect.width || rect.height) {
|
||||||
if (container === window) {
|
if (container === window) {
|
||||||
return rect.top - element.ownerDocument!.documentElement!.clientTop;
|
container = element.ownerDocument!.documentElement!;
|
||||||
|
return rect.top - container.clientTop;
|
||||||
}
|
}
|
||||||
return rect.top - (container as HTMLElement).getBoundingClientRect().top;
|
return rect.top - (container as HTMLElement).getBoundingClientRect().top;
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,6 @@ export const anchorProps = () => ({
|
||||||
targetOffset: Number,
|
targetOffset: Number,
|
||||||
items: arrayType<AnchorLinkItemProps[]>(),
|
items: arrayType<AnchorLinkItemProps[]>(),
|
||||||
direction: PropTypes.oneOf(['vertical', 'horizontal'] as AnchorDirection[]).def('vertical'),
|
direction: PropTypes.oneOf(['vertical', 'horizontal'] as AnchorDirection[]).def('vertical'),
|
||||||
replace: Boolean,
|
|
||||||
onChange: Function as PropType<(currentActiveLink: string) => void>,
|
onChange: Function as PropType<(currentActiveLink: string) => void>,
|
||||||
onClick: Function as PropType<(e: MouseEvent, link: { title: any; href: string }) => void>,
|
onClick: Function as PropType<(e: MouseEvent, link: { title: any; href: string }) => void>,
|
||||||
});
|
});
|
||||||
|
|
@ -92,7 +91,7 @@ export default defineComponent({
|
||||||
setup(props, { emit, attrs, slots, expose }) {
|
setup(props, { emit, attrs, slots, expose }) {
|
||||||
const { prefixCls, getTargetContainer, direction } = useConfigInject('anchor', props);
|
const { prefixCls, getTargetContainer, direction } = useConfigInject('anchor', props);
|
||||||
const anchorDirection = computed(() => props.direction ?? 'vertical');
|
const anchorDirection = computed(() => props.direction ?? 'vertical');
|
||||||
const rootCls = useCSSVarCls(prefixCls);
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
devWarning(
|
devWarning(
|
||||||
props.items && typeof slots.default !== 'function',
|
props.items && typeof slots.default !== 'function',
|
||||||
|
|
@ -134,7 +133,7 @@ export default defineComponent({
|
||||||
const target = document.getElementById(sharpLinkMatch[1]);
|
const target = document.getElementById(sharpLinkMatch[1]);
|
||||||
if (target) {
|
if (target) {
|
||||||
const top = getOffsetTop(target, container);
|
const top = getOffsetTop(target, container);
|
||||||
if (top <= offsetTop + bounds) {
|
if (top < offsetTop + bounds) {
|
||||||
linkSections.push({
|
linkSections.push({
|
||||||
link,
|
link,
|
||||||
top,
|
top,
|
||||||
|
|
@ -171,7 +170,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = getContainer.value();
|
const container = getContainer.value();
|
||||||
const scrollTop = getScroll(container);
|
const scrollTop = getScroll(container, true);
|
||||||
const eleOffsetTop = getOffsetTop(targetElement, container);
|
const eleOffsetTop = getOffsetTop(targetElement, container);
|
||||||
let y = scrollTop + eleOffsetTop;
|
let y = scrollTop + eleOffsetTop;
|
||||||
y -= targetOffset !== undefined ? targetOffset : offsetTop || 0;
|
y -= targetOffset !== undefined ? targetOffset : offsetTop || 0;
|
||||||
|
|
@ -278,7 +277,6 @@ export default defineComponent({
|
||||||
title={title}
|
title={title}
|
||||||
customTitleProps={option}
|
customTitleProps={option}
|
||||||
v-slots={{ customTitle: slots.customTitle }}
|
v-slots={{ customTitle: slots.customTitle }}
|
||||||
replace={props.replace}
|
|
||||||
>
|
>
|
||||||
{anchorDirection.value === 'vertical' ? createNestedLink(children) : null}
|
{anchorDirection.value === 'vertical' ? createNestedLink(children) : null}
|
||||||
</AnchorLink>
|
</AnchorLink>
|
||||||
|
|
@ -286,7 +284,7 @@ export default defineComponent({
|
||||||
})
|
})
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const [wrapSSR, hashId, cssVarCls] = useStyle(prefixCls, rootCls);
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const { offsetTop, affix, showInkInFixed } = props;
|
const { offsetTop, affix, showInkInFixed } = props;
|
||||||
|
|
@ -298,8 +296,6 @@ export default defineComponent({
|
||||||
const wrapperClass = classNames(hashId.value, props.wrapperClass, `${pre}-wrapper`, {
|
const wrapperClass = classNames(hashId.value, props.wrapperClass, `${pre}-wrapper`, {
|
||||||
[`${pre}-wrapper-horizontal`]: anchorDirection.value === 'horizontal',
|
[`${pre}-wrapper-horizontal`]: anchorDirection.value === 'horizontal',
|
||||||
[`${pre}-rtl`]: direction.value === 'rtl',
|
[`${pre}-rtl`]: direction.value === 'rtl',
|
||||||
[rootCls.value]: true,
|
|
||||||
[cssVarCls.value]: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const anchorClass = classNames(pre, {
|
const anchorClass = classNames(pre, {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ export const anchorLinkProps = () => ({
|
||||||
href: String,
|
href: String,
|
||||||
title: anyType<VueNode | ((item: any) => VueNode)>(),
|
title: anyType<VueNode | ((item: any) => VueNode)>(),
|
||||||
target: String,
|
target: String,
|
||||||
replace: Boolean,
|
|
||||||
/* private use */
|
/* private use */
|
||||||
customTitleProps: objectType<AnchorLinkItemProps>(),
|
customTitleProps: objectType<AnchorLinkItemProps>(),
|
||||||
});
|
});
|
||||||
|
|
@ -54,10 +53,6 @@ export default defineComponent({
|
||||||
const { href } = props;
|
const { href } = props;
|
||||||
contextHandleClick(e, { title: mergedTitle, href });
|
contextHandleClick(e, { title: mergedTitle, href });
|
||||||
scrollTo(href);
|
scrollTo(href);
|
||||||
if (props.replace) {
|
|
||||||
e.preventDefault();
|
|
||||||
window.location.replace(href);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,21 @@
|
||||||
import { unit } from '../../_util/cssinjs';
|
import type { CSSObject } from '../../_util/cssinjs';
|
||||||
import {
|
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||||
FullToken,
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
GenerateStyle,
|
|
||||||
genStyleHooks,
|
|
||||||
GetDefaultToken,
|
|
||||||
mergeToken,
|
|
||||||
} from '../../theme/internal';
|
|
||||||
import { resetComponent, textEllipsis } from '../../style';
|
import { resetComponent, textEllipsis } from '../../style';
|
||||||
|
|
||||||
export interface ComponentToken {
|
export interface ComponentToken {}
|
||||||
/**
|
|
||||||
* @desc 链接纵向内间距
|
|
||||||
* @descEN Vertical padding of link
|
|
||||||
*/
|
|
||||||
linkPaddingBlock: number;
|
|
||||||
/**
|
|
||||||
* @desc 链接横向内间距
|
|
||||||
* @descEN Horizontal padding of link
|
|
||||||
*/
|
|
||||||
linkPaddingInlineStart: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @desc Anchor 组件的 Token
|
|
||||||
* @descEN Token for Anchor component
|
|
||||||
*/
|
|
||||||
interface AnchorToken extends FullToken<'Anchor'> {
|
interface AnchorToken extends FullToken<'Anchor'> {
|
||||||
/**
|
|
||||||
* @desc 容器块偏移量
|
|
||||||
* @descEN Holder block offset
|
|
||||||
*/
|
|
||||||
holderOffsetBlock: number;
|
holderOffsetBlock: number;
|
||||||
/**
|
anchorPaddingBlock: number;
|
||||||
* @desc 次级锚点块内间距
|
anchorPaddingBlockSecondary: number;
|
||||||
* @descEN Secondary anchor block padding
|
anchorPaddingInline: number;
|
||||||
*/
|
anchorBallSize: number;
|
||||||
anchorPaddingBlockSecondary: number | string;
|
anchorTitleBlock: number;
|
||||||
/**
|
|
||||||
* @desc 锚点球大小
|
|
||||||
* @descEN Anchor ball size
|
|
||||||
*/
|
|
||||||
anchorBallSize: number | string;
|
|
||||||
/**
|
|
||||||
* @desc 锚点标题块
|
|
||||||
* @descEN Anchor title block
|
|
||||||
*/
|
|
||||||
anchorTitleBlock: number | string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================== Shared ==============================
|
// ============================== Shared ==============================
|
||||||
const genSharedAnchorStyle: GenerateStyle<AnchorToken> = token => {
|
const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||||
const {
|
const {
|
||||||
componentCls,
|
componentCls,
|
||||||
holderOffsetBlock,
|
holderOffsetBlock,
|
||||||
|
|
@ -58,25 +24,26 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = token => {
|
||||||
colorPrimary,
|
colorPrimary,
|
||||||
lineType,
|
lineType,
|
||||||
colorSplit,
|
colorSplit,
|
||||||
calc,
|
|
||||||
} = token;
|
} = token;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[`${componentCls}-wrapper`]: {
|
[`${componentCls}-wrapper`]: {
|
||||||
marginBlockStart: calc(holderOffsetBlock).mul(-1).equal(),
|
marginBlockStart: -holderOffsetBlock,
|
||||||
paddingBlockStart: holderOffsetBlock,
|
paddingBlockStart: holderOffsetBlock,
|
||||||
|
|
||||||
// delete overflow: auto
|
// delete overflow: auto
|
||||||
// overflow: 'auto',
|
// overflow: 'auto',
|
||||||
|
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
|
||||||
[componentCls]: {
|
[componentCls]: {
|
||||||
...resetComponent(token),
|
...resetComponent(token),
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
paddingInlineStart: lineWidthBold,
|
paddingInlineStart: lineWidthBold,
|
||||||
|
|
||||||
[`${componentCls}-link`]: {
|
[`${componentCls}-link`]: {
|
||||||
paddingBlock: token.linkPaddingBlock,
|
paddingBlock: token.anchorPaddingBlock,
|
||||||
paddingInline: `${unit(token.linkPaddingInlineStart)} 0`,
|
paddingInline: `${token.anchorPaddingInline}px 0`,
|
||||||
|
|
||||||
'&-title': {
|
'&-title': {
|
||||||
...textEllipsis,
|
...textEllipsis,
|
||||||
|
|
@ -106,21 +73,28 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = token => {
|
||||||
[componentCls]: {
|
[componentCls]: {
|
||||||
'&::before': {
|
'&::before': {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
insetInlineStart: 0,
|
left: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
top: 0,
|
top: 0,
|
||||||
height: '100%',
|
height: '100%',
|
||||||
borderInlineStart: `${unit(lineWidthBold)} ${lineType} ${colorSplit}`,
|
borderInlineStart: `${lineWidthBold}px ${lineType} ${colorSplit}`,
|
||||||
content: '" "',
|
content: '" "',
|
||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-ink`]: {
|
[`${componentCls}-ink`]: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
insetInlineStart: 0,
|
left: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
display: 'none',
|
display: 'none',
|
||||||
transform: 'translateY(-50%)',
|
transform: 'translateY(-50%)',
|
||||||
transition: `top ${motionDurationSlow} ease-in-out`,
|
transition: `top ${motionDurationSlow} ease-in-out`,
|
||||||
width: lineWidthBold,
|
width: lineWidthBold,
|
||||||
backgroundColor: colorPrimary,
|
backgroundColor: colorPrimary,
|
||||||
|
|
||||||
[`&${componentCls}-ink-visible`]: {
|
[`&${componentCls}-ink-visible`]: {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
},
|
},
|
||||||
|
|
@ -135,7 +109,7 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = token => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = token => {
|
const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||||
const { componentCls, motionDurationSlow, lineWidthBold, colorPrimary } = token;
|
const { componentCls, motionDurationSlow, lineWidthBold, colorPrimary } = token;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -153,7 +127,7 @@ const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = token => {
|
||||||
value: 0,
|
value: 0,
|
||||||
},
|
},
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
borderBottom: `${unit(token.lineWidth)} ${token.lineType} ${token.colorSplit}`,
|
borderBottom: `1px ${token.lineType} ${token.colorSplit}`,
|
||||||
content: '" "',
|
content: '" "',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -183,23 +157,17 @@ const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = token => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const prepareComponentToken: GetDefaultToken<'Anchor'> = token => ({
|
|
||||||
linkPaddingBlock: token.paddingXXS,
|
|
||||||
linkPaddingInlineStart: token.padding,
|
|
||||||
});
|
|
||||||
|
|
||||||
// ============================== Export ==============================
|
// ============================== Export ==============================
|
||||||
export default genStyleHooks(
|
export default genComponentStyleHook('Anchor', token => {
|
||||||
'Anchor',
|
const { fontSize, fontSizeLG, padding, paddingXXS } = token;
|
||||||
token => {
|
|
||||||
const { fontSize, fontSizeLG, paddingXXS, calc } = token;
|
|
||||||
const anchorToken = mergeToken<AnchorToken>(token, {
|
const anchorToken = mergeToken<AnchorToken>(token, {
|
||||||
holderOffsetBlock: paddingXXS,
|
holderOffsetBlock: paddingXXS,
|
||||||
anchorPaddingBlockSecondary: calc(paddingXXS).div(2).equal(),
|
anchorPaddingBlock: paddingXXS,
|
||||||
anchorTitleBlock: calc(fontSize).div(14).mul(3).equal(),
|
anchorPaddingBlockSecondary: paddingXXS / 2,
|
||||||
anchorBallSize: calc(fontSizeLG).div(2).equal(),
|
anchorPaddingInline: padding,
|
||||||
|
anchorTitleBlock: (fontSize / 14) * 3,
|
||||||
|
anchorBallSize: fontSizeLG / 2,
|
||||||
});
|
});
|
||||||
return [genSharedAnchorStyle(anchorToken), genSharedAnchorHorizontalStyle(anchorToken)];
|
return [genSharedAnchorStyle(anchorToken), genSharedAnchorHorizontalStyle(anchorToken)];
|
||||||
},
|
});
|
||||||
prepareComponentToken,
|
|
||||||
);
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
import { genPresetColor, resetComponent } from '../../style';
|
import { genPresetColor, resetComponent } from '../../style';
|
||||||
|
|
||||||
export interface ComponentToken {}
|
|
||||||
|
|
||||||
interface BadgeToken extends FullToken<'Badge'> {
|
interface BadgeToken extends FullToken<'Badge'> {
|
||||||
badgeFontHeight: number;
|
badgeFontHeight: number;
|
||||||
badgeZIndex: number | string;
|
badgeZIndex: number | string;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
import { genFocusStyle, resetComponent } from '../../style';
|
import { genFocusStyle, resetComponent } from '../../style';
|
||||||
|
|
||||||
export interface ComponentToken {}
|
|
||||||
|
|
||||||
interface BreadcrumbToken extends FullToken<'Breadcrumb'> {
|
interface BreadcrumbToken extends FullToken<'Breadcrumb'> {
|
||||||
breadcrumbBaseColor: string;
|
breadcrumbBaseColor: string;
|
||||||
breadcrumbFontSize: number;
|
breadcrumbFontSize: number;
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,7 @@ export default defineComponent({
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
devWarning(
|
devWarning(!size, 'Button.Group', 'Invalid prop `size`.');
|
||||||
!size || ['large', 'small', 'middle'].includes(size),
|
|
||||||
'Button.Group',
|
|
||||||
'Invalid prop `size`.',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
[`${prefixCls.value}`]: true,
|
[`${prefixCls.value}`]: true,
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ export default defineComponent({
|
||||||
// emits: ['click', 'mousedown'],
|
// emits: ['click', 'mousedown'],
|
||||||
setup(props, { slots, attrs, emit, expose }) {
|
setup(props, { slots, attrs, emit, expose }) {
|
||||||
const { prefixCls, autoInsertSpaceInButton, direction, size } = useConfigInject('btn', props);
|
const { prefixCls, autoInsertSpaceInButton, direction, size } = useConfigInject('btn', props);
|
||||||
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
const groupSizeContext = GroupSizeContext.useInject();
|
const groupSizeContext = GroupSizeContext.useInject();
|
||||||
const disabledContext = useInjectDisabled();
|
const disabledContext = useInjectDisabled();
|
||||||
const mergedDisabled = computed(() => props.disabled ?? disabledContext.value);
|
const mergedDisabled = computed(() => props.disabled ?? disabledContext.value);
|
||||||
|
|
@ -95,7 +95,6 @@ export default defineComponent({
|
||||||
compactItemClassnames.value,
|
compactItemClassnames.value,
|
||||||
{
|
{
|
||||||
[hashId.value]: true,
|
[hashId.value]: true,
|
||||||
[cssVarCls.value]: true,
|
|
||||||
[`${pre}`]: true,
|
[`${pre}`]: true,
|
||||||
[`${pre}-${shape}`]: shape !== 'default' && shape,
|
[`${pre}-${shape}`]: shape !== 'default' && shape,
|
||||||
[`${pre}-${type}`]: type,
|
[`${pre}-${type}`]: type,
|
||||||
|
|
@ -217,7 +216,7 @@ export default defineComponent({
|
||||||
);
|
);
|
||||||
|
|
||||||
if (href !== undefined) {
|
if (href !== undefined) {
|
||||||
return wrapCSSVar(
|
return wrapSSR(
|
||||||
<a {...buttonProps} href={href} target={target} ref={buttonNodeRef}>
|
<a {...buttonProps} href={href} target={target} ref={buttonNodeRef}>
|
||||||
{iconNode}
|
{iconNode}
|
||||||
{kids}
|
{kids}
|
||||||
|
|
@ -240,7 +239,7 @@ export default defineComponent({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrapCSSVar(buttonNode);
|
return wrapSSR(buttonNode);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ If you want specific control over the positioning and placement of the `Icon`, t
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-space direction="vertical">
|
<a-space direction="vertical">
|
||||||
<a-space warp>
|
<a-space wrap>
|
||||||
<a-tooltip title="search">
|
<a-tooltip title="search">
|
||||||
<a-button type="primary" shape="circle" :icon="h(SearchOutlined)" />
|
<a-button type="primary" shape="circle" :icon="h(SearchOutlined)" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
|
@ -32,7 +32,7 @@ If you want specific control over the positioning and placement of the `Icon`, t
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-button :icon="h(SearchOutlined)">Search</a-button>
|
<a-button :icon="h(SearchOutlined)">Search</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
<a-space warp>
|
<a-space wrap>
|
||||||
<a-tooltip title="search">
|
<a-tooltip title="search">
|
||||||
<a-button shape="circle" :icon="h(SearchOutlined)" />
|
<a-button shape="circle" :icon="h(SearchOutlined)" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
// Style as inline component
|
|
||||||
import type { ButtonToken } from './token';
|
|
||||||
import { prepareComponentToken, prepareToken } from './token';
|
|
||||||
import { genCompactItemStyle } from '../../style/compact-item';
|
|
||||||
import { genCompactItemVerticalStyle } from '../../style/compact-item-vertical';
|
|
||||||
import type { GenerateStyle } from '../../theme/internal';
|
|
||||||
import { genSubStyleComponent } from '../../theme/internal';
|
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
|
||||||
import { unit } from '../../_util/cssinjs';
|
|
||||||
|
|
||||||
const genButtonCompactStyle: GenerateStyle<ButtonToken, CSSObject> = token => {
|
|
||||||
const { componentCls, calc } = token;
|
|
||||||
|
|
||||||
return {
|
|
||||||
[componentCls]: {
|
|
||||||
// Special styles for Primary Button
|
|
||||||
[`&-compact-item${componentCls}-primary`]: {
|
|
||||||
[`&:not([disabled]) + ${componentCls}-compact-item${componentCls}-primary:not([disabled])`]:
|
|
||||||
{
|
|
||||||
position: 'relative',
|
|
||||||
|
|
||||||
'&:before': {
|
|
||||||
position: 'absolute',
|
|
||||||
top: calc(token.lineWidth).mul(-1).equal(),
|
|
||||||
insetInlineStart: calc(token.lineWidth).mul(-1).equal(),
|
|
||||||
display: 'inline-block',
|
|
||||||
width: token.lineWidth,
|
|
||||||
height: `calc(100% + ${unit(token.lineWidth)} * 2)`,
|
|
||||||
backgroundColor: token.colorPrimaryHover,
|
|
||||||
content: '""',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Special styles for Primary Button
|
|
||||||
'&-compact-vertical-item': {
|
|
||||||
[`&${componentCls}-primary`]: {
|
|
||||||
[`&:not([disabled]) + ${componentCls}-compact-vertical-item${componentCls}-primary:not([disabled])`]:
|
|
||||||
{
|
|
||||||
position: 'relative',
|
|
||||||
|
|
||||||
'&:before': {
|
|
||||||
position: 'absolute',
|
|
||||||
top: calc(token.lineWidth).mul(-1).equal(),
|
|
||||||
insetInlineStart: calc(token.lineWidth).mul(-1).equal(),
|
|
||||||
display: 'inline-block',
|
|
||||||
width: `calc(100% + ${unit(token.lineWidth)} * 2)`,
|
|
||||||
height: token.lineWidth,
|
|
||||||
backgroundColor: token.colorPrimaryHover,
|
|
||||||
content: '""',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================== Export ==============================
|
|
||||||
export default genSubStyleComponent(
|
|
||||||
['Button', 'compact'],
|
|
||||||
token => {
|
|
||||||
const buttonToken = prepareToken(token);
|
|
||||||
|
|
||||||
return [
|
|
||||||
// Space Compact
|
|
||||||
genCompactItemStyle(buttonToken),
|
|
||||||
genCompactItemVerticalStyle(buttonToken),
|
|
||||||
genButtonCompactStyle(buttonToken),
|
|
||||||
] as CSSObject[];
|
|
||||||
},
|
|
||||||
prepareComponentToken,
|
|
||||||
);
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
import type { ButtonToken } from '.';
|
||||||
import type { ButtonToken } from './token';
|
|
||||||
import type { GenerateStyle } from '../../theme/internal';
|
import type { GenerateStyle } from '../../theme/internal';
|
||||||
|
|
||||||
const genButtonBorderStyle = (buttonTypeCls: string, borderColor: string) => ({
|
const genButtonBorderStyle = (buttonTypeCls: string, borderColor: string) => ({
|
||||||
|
|
@ -23,8 +22,8 @@ const genButtonBorderStyle = (buttonTypeCls: string, borderColor: string) => ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const genGroupStyle: GenerateStyle<ButtonToken, CSSObject> = token => {
|
const genGroupStyle: GenerateStyle<ButtonToken> = token => {
|
||||||
const { componentCls, fontSize, lineWidth, groupBorderColor, colorErrorHover } = token;
|
const { componentCls, fontSize, lineWidth, colorPrimaryHover, colorErrorHover } = token;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[`${componentCls}-group`]: [
|
[`${componentCls}-group`]: [
|
||||||
|
|
@ -42,7 +41,7 @@ const genGroupStyle: GenerateStyle<ButtonToken, CSSObject> = token => {
|
||||||
},
|
},
|
||||||
|
|
||||||
'&:not(:first-child)': {
|
'&:not(:first-child)': {
|
||||||
marginInlineStart: token.calc(lineWidth).mul(-1).equal(),
|
marginInlineStart: -lineWidth,
|
||||||
|
|
||||||
[`&, & > ${componentCls}`]: {
|
[`&, & > ${componentCls}`]: {
|
||||||
borderStartStartRadius: 0,
|
borderStartStartRadius: 0,
|
||||||
|
|
@ -72,7 +71,7 @@ const genGroupStyle: GenerateStyle<ButtonToken, CSSObject> = token => {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Border Color
|
// Border Color
|
||||||
genButtonBorderStyle(`${componentCls}-primary`, groupBorderColor),
|
genButtonBorderStyle(`${componentCls}-primary`, colorPrimaryHover),
|
||||||
genButtonBorderStyle(`${componentCls}-danger`, colorErrorHover),
|
genButtonBorderStyle(`${componentCls}-danger`, colorErrorHover),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,59 +1,51 @@
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
import type { CSSInterpolation, CSSObject } from '../../_util/cssinjs';
|
||||||
import { unit } from '../../_util/cssinjs';
|
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||||
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
import { genFocusStyle } from '../../style';
|
|
||||||
import type { GenerateStyle } from '../../theme/internal';
|
|
||||||
import { genStyleHooks, mergeToken } from '../../theme/internal';
|
|
||||||
import genGroupStyle from './group';
|
import genGroupStyle from './group';
|
||||||
import type { ButtonToken, ComponentToken } from './token';
|
import { genFocusStyle } from '../../style';
|
||||||
import { prepareComponentToken, prepareToken } from './token';
|
import { genCompactItemStyle } from '../../style/compact-item';
|
||||||
|
import { genCompactItemVerticalStyle } from '../../style/compact-item-vertical';
|
||||||
|
|
||||||
export type { ComponentToken };
|
/** Component only token. Which will handle additional calculation of alias token */
|
||||||
|
export interface ComponentToken {}
|
||||||
|
|
||||||
|
export interface ButtonToken extends FullToken<'Button'> {
|
||||||
|
// FIXME: should be removed
|
||||||
|
colorOutlineDefault: string;
|
||||||
|
buttonPaddingHorizontal: number;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================== Shared ==============================
|
// ============================== Shared ==============================
|
||||||
const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSSObject => {
|
const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSSObject => {
|
||||||
const { componentCls, iconCls, fontWeight } = token;
|
const { componentCls, iconCls } = token;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[componentCls]: {
|
[componentCls]: {
|
||||||
outline: 'none',
|
outline: 'none',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
fontWeight,
|
fontWeight: 400,
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
backgroundImage: 'none',
|
backgroundImage: 'none',
|
||||||
background: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
border: `${unit(token.lineWidth)} ${token.lineType} transparent`,
|
border: `${token.lineWidth}px ${token.lineType} transparent`,
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
transition: `all ${token.motionDurationMid} ${token.motionEaseInOut}`,
|
transition: `all ${token.motionDurationMid} ${token.motionEaseInOut}`,
|
||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
touchAction: 'manipulation',
|
touchAction: 'manipulation',
|
||||||
|
lineHeight: token.lineHeight,
|
||||||
color: token.colorText,
|
color: token.colorText,
|
||||||
|
|
||||||
'&:disabled > *': {
|
|
||||||
pointerEvents: 'none',
|
|
||||||
},
|
|
||||||
|
|
||||||
'> span': {
|
'> span': {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-icon`]: {
|
|
||||||
lineHeight: 0,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Leave a space between icon and text.
|
// Leave a space between icon and text.
|
||||||
[`> ${iconCls} + span, > span + ${iconCls}`]: {
|
[`> ${iconCls} + span, > span + ${iconCls}`]: {
|
||||||
marginInlineStart: token.marginXS,
|
marginInlineStart: token.marginXS,
|
||||||
},
|
},
|
||||||
|
|
||||||
[`&:not(${componentCls}-icon-only) > ${componentCls}-icon`]: {
|
|
||||||
[`&${componentCls}-loading-icon, &:not(:last-child)`]: {
|
|
||||||
marginInlineEnd: token.marginXS,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
'> a': {
|
'> a': {
|
||||||
color: 'currentColor',
|
color: 'currentColor',
|
||||||
},
|
},
|
||||||
|
|
@ -62,29 +54,54 @@ const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSS
|
||||||
...genFocusStyle(token),
|
...genFocusStyle(token),
|
||||||
},
|
},
|
||||||
|
|
||||||
[`&${componentCls}-two-chinese-chars::first-letter`]: {
|
|
||||||
letterSpacing: '0.34em',
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&${componentCls}-two-chinese-chars > *:not(${iconCls})`]: {
|
|
||||||
marginInlineEnd: '-0.34em',
|
|
||||||
letterSpacing: '0.34em',
|
|
||||||
},
|
|
||||||
|
|
||||||
// make `btn-icon-only` not too narrow
|
// make `btn-icon-only` not too narrow
|
||||||
[`&-icon-only${componentCls}-compact-item`]: {
|
[`&-icon-only${componentCls}-compact-item`]: {
|
||||||
flex: 'none',
|
flex: 'none',
|
||||||
},
|
},
|
||||||
|
// Special styles for Primary Button
|
||||||
|
[`&-compact-item${componentCls}-primary`]: {
|
||||||
|
[`&:not([disabled]) + ${componentCls}-compact-item${componentCls}-primary:not([disabled])`]:
|
||||||
|
{
|
||||||
|
position: 'relative',
|
||||||
|
|
||||||
|
'&:before': {
|
||||||
|
position: 'absolute',
|
||||||
|
top: -token.lineWidth,
|
||||||
|
insetInlineStart: -token.lineWidth,
|
||||||
|
display: 'inline-block',
|
||||||
|
width: token.lineWidth,
|
||||||
|
height: `calc(100% + ${token.lineWidth * 2}px)`,
|
||||||
|
backgroundColor: token.colorPrimaryHover,
|
||||||
|
content: '""',
|
||||||
},
|
},
|
||||||
} as CSSObject;
|
},
|
||||||
|
},
|
||||||
|
// Special styles for Primary Button
|
||||||
|
'&-compact-vertical-item': {
|
||||||
|
[`&${componentCls}-primary`]: {
|
||||||
|
[`&:not([disabled]) + ${componentCls}-compact-vertical-item${componentCls}-primary:not([disabled])`]:
|
||||||
|
{
|
||||||
|
position: 'relative',
|
||||||
|
|
||||||
|
'&:before': {
|
||||||
|
position: 'absolute',
|
||||||
|
top: -token.lineWidth,
|
||||||
|
insetInlineStart: -token.lineWidth,
|
||||||
|
display: 'inline-block',
|
||||||
|
width: `calc(100% + ${token.lineWidth * 2}px)`,
|
||||||
|
height: token.lineWidth,
|
||||||
|
backgroundColor: token.colorPrimaryHover,
|
||||||
|
content: '""',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const genHoverActiveButtonStyle = (
|
const genHoverActiveButtonStyle = (hoverStyle: CSSObject, activeStyle: CSSObject): CSSObject => ({
|
||||||
btnCls: string,
|
'&:not(:disabled)': {
|
||||||
hoverStyle: CSSObject,
|
|
||||||
activeStyle: CSSObject,
|
|
||||||
): CSSObject => ({
|
|
||||||
[`&:not(:disabled):not(${btnCls}-disabled)`]: {
|
|
||||||
'&:hover': hoverStyle,
|
'&:hover': hoverStyle,
|
||||||
'&:active': activeStyle,
|
'&:active': activeStyle,
|
||||||
},
|
},
|
||||||
|
|
@ -100,22 +117,21 @@ const genCircleButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
|
|
||||||
const genRoundButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
const genRoundButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
borderRadius: token.controlHeight,
|
borderRadius: token.controlHeight,
|
||||||
paddingInlineStart: token.calc(token.controlHeight).div(2).equal(),
|
paddingInlineStart: token.controlHeight / 2,
|
||||||
paddingInlineEnd: token.calc(token.controlHeight).div(2).equal(),
|
paddingInlineEnd: token.controlHeight / 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
// =============================== Type ===============================
|
// =============================== Type ===============================
|
||||||
const genDisabledStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
const genDisabledStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
cursor: 'not-allowed',
|
cursor: 'not-allowed',
|
||||||
borderColor: token.borderColorDisabled,
|
borderColor: token.colorBorder,
|
||||||
color: token.colorTextDisabled,
|
color: token.colorTextDisabled,
|
||||||
background: token.colorBgContainerDisabled,
|
backgroundColor: token.colorBgContainerDisabled,
|
||||||
boxShadow: 'none',
|
boxShadow: 'none',
|
||||||
});
|
});
|
||||||
|
|
||||||
const genGhostButtonStyle = (
|
const genGhostButtonStyle = (
|
||||||
btnCls: string,
|
btnCls: string,
|
||||||
background: string,
|
|
||||||
textColor: string | false,
|
textColor: string | false,
|
||||||
borderColor: string | false,
|
borderColor: string | false,
|
||||||
textColorDisabled: string | false,
|
textColorDisabled: string | false,
|
||||||
|
|
@ -125,18 +141,17 @@ const genGhostButtonStyle = (
|
||||||
): CSSObject => ({
|
): CSSObject => ({
|
||||||
[`&${btnCls}-background-ghost`]: {
|
[`&${btnCls}-background-ghost`]: {
|
||||||
color: textColor || undefined,
|
color: textColor || undefined,
|
||||||
background,
|
backgroundColor: 'transparent',
|
||||||
borderColor: borderColor || undefined,
|
borderColor: borderColor || undefined,
|
||||||
boxShadow: 'none',
|
boxShadow: 'none',
|
||||||
|
|
||||||
...genHoverActiveButtonStyle(
|
...genHoverActiveButtonStyle(
|
||||||
btnCls,
|
|
||||||
{
|
{
|
||||||
background,
|
backgroundColor: 'transparent',
|
||||||
...hoverStyle,
|
...hoverStyle,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
background,
|
backgroundColor: 'transparent',
|
||||||
...activeStyle,
|
...activeStyle,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -150,7 +165,7 @@ const genGhostButtonStyle = (
|
||||||
});
|
});
|
||||||
|
|
||||||
const genSolidDisabledButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
const genSolidDisabledButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
[`&:disabled, &${token.componentCls}-disabled`]: {
|
'&:disabled': {
|
||||||
...genDisabledStyle(token),
|
...genDisabledStyle(token),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -160,7 +175,7 @@ const genSolidButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const genPureDisabledButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
const genPureDisabledButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
[`&:disabled, &${token.componentCls}-disabled`]: {
|
'&:disabled': {
|
||||||
cursor: 'not-allowed',
|
cursor: 'not-allowed',
|
||||||
color: token.colorTextDisabled,
|
color: token.colorTextDisabled,
|
||||||
},
|
},
|
||||||
|
|
@ -170,14 +185,12 @@ const genPureDisabledButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token
|
||||||
const genDefaultButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
const genDefaultButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
...genSolidButtonStyle(token),
|
...genSolidButtonStyle(token),
|
||||||
|
|
||||||
background: token.defaultBg,
|
backgroundColor: token.colorBgContainer,
|
||||||
borderColor: token.defaultBorderColor,
|
borderColor: token.colorBorder,
|
||||||
color: token.defaultColor,
|
|
||||||
|
|
||||||
boxShadow: token.defaultShadow,
|
boxShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlTmpOutline}`,
|
||||||
|
|
||||||
...genHoverActiveButtonStyle(
|
...genHoverActiveButtonStyle(
|
||||||
token.componentCls,
|
|
||||||
{
|
{
|
||||||
color: token.colorPrimaryHover,
|
color: token.colorPrimaryHover,
|
||||||
borderColor: token.colorPrimaryHover,
|
borderColor: token.colorPrimaryHover,
|
||||||
|
|
@ -190,9 +203,8 @@ const genDefaultButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
|
|
||||||
...genGhostButtonStyle(
|
...genGhostButtonStyle(
|
||||||
token.componentCls,
|
token.componentCls,
|
||||||
token.ghostBg,
|
token.colorBgContainer,
|
||||||
token.defaultGhostColor,
|
token.colorBgContainer,
|
||||||
token.defaultGhostBorderColor,
|
|
||||||
token.colorTextDisabled,
|
token.colorTextDisabled,
|
||||||
token.colorBorder,
|
token.colorBorder,
|
||||||
),
|
),
|
||||||
|
|
@ -202,7 +214,6 @@ const genDefaultButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
borderColor: token.colorError,
|
borderColor: token.colorError,
|
||||||
|
|
||||||
...genHoverActiveButtonStyle(
|
...genHoverActiveButtonStyle(
|
||||||
token.componentCls,
|
|
||||||
{
|
{
|
||||||
color: token.colorErrorHover,
|
color: token.colorErrorHover,
|
||||||
borderColor: token.colorErrorBorderHover,
|
borderColor: token.colorErrorBorderHover,
|
||||||
|
|
@ -215,7 +226,6 @@ const genDefaultButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
|
|
||||||
...genGhostButtonStyle(
|
...genGhostButtonStyle(
|
||||||
token.componentCls,
|
token.componentCls,
|
||||||
token.ghostBg,
|
|
||||||
token.colorError,
|
token.colorError,
|
||||||
token.colorError,
|
token.colorError,
|
||||||
token.colorTextDisabled,
|
token.colorTextDisabled,
|
||||||
|
|
@ -229,26 +239,24 @@ const genDefaultButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
const genPrimaryButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
const genPrimaryButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
...genSolidButtonStyle(token),
|
...genSolidButtonStyle(token),
|
||||||
|
|
||||||
color: token.primaryColor,
|
color: token.colorTextLightSolid,
|
||||||
background: token.colorPrimary,
|
backgroundColor: token.colorPrimary,
|
||||||
|
|
||||||
boxShadow: token.primaryShadow,
|
boxShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlOutline}`,
|
||||||
|
|
||||||
...genHoverActiveButtonStyle(
|
...genHoverActiveButtonStyle(
|
||||||
token.componentCls,
|
|
||||||
{
|
{
|
||||||
color: token.colorTextLightSolid,
|
color: token.colorTextLightSolid,
|
||||||
background: token.colorPrimaryHover,
|
backgroundColor: token.colorPrimaryHover,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
color: token.colorTextLightSolid,
|
color: token.colorTextLightSolid,
|
||||||
background: token.colorPrimaryActive,
|
backgroundColor: token.colorPrimaryActive,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
...genGhostButtonStyle(
|
...genGhostButtonStyle(
|
||||||
token.componentCls,
|
token.componentCls,
|
||||||
token.ghostBg,
|
|
||||||
token.colorPrimary,
|
token.colorPrimary,
|
||||||
token.colorPrimary,
|
token.colorPrimary,
|
||||||
token.colorTextDisabled,
|
token.colorTextDisabled,
|
||||||
|
|
@ -264,23 +272,20 @@ const genPrimaryButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
),
|
),
|
||||||
|
|
||||||
[`&${token.componentCls}-dangerous`]: {
|
[`&${token.componentCls}-dangerous`]: {
|
||||||
background: token.colorError,
|
backgroundColor: token.colorError,
|
||||||
boxShadow: token.dangerShadow,
|
boxShadow: `0 ${token.controlOutlineWidth}px 0 ${token.colorErrorOutline}`,
|
||||||
color: token.dangerColor,
|
|
||||||
|
|
||||||
...genHoverActiveButtonStyle(
|
...genHoverActiveButtonStyle(
|
||||||
token.componentCls,
|
|
||||||
{
|
{
|
||||||
background: token.colorErrorHover,
|
backgroundColor: token.colorErrorHover,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
background: token.colorErrorActive,
|
backgroundColor: token.colorErrorActive,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
...genGhostButtonStyle(
|
...genGhostButtonStyle(
|
||||||
token.componentCls,
|
token.componentCls,
|
||||||
token.ghostBg,
|
|
||||||
token.colorError,
|
token.colorError,
|
||||||
token.colorError,
|
token.colorError,
|
||||||
token.colorTextDisabled,
|
token.colorTextDisabled,
|
||||||
|
|
@ -309,10 +314,8 @@ const genLinkButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
color: token.colorLink,
|
color: token.colorLink,
|
||||||
|
|
||||||
...genHoverActiveButtonStyle(
|
...genHoverActiveButtonStyle(
|
||||||
token.componentCls,
|
|
||||||
{
|
{
|
||||||
color: token.colorLinkHover,
|
color: token.colorLinkHover,
|
||||||
background: token.linkHoverBg,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
color: token.colorLinkActive,
|
color: token.colorLinkActive,
|
||||||
|
|
@ -325,7 +328,6 @@ const genLinkButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
color: token.colorError,
|
color: token.colorError,
|
||||||
|
|
||||||
...genHoverActiveButtonStyle(
|
...genHoverActiveButtonStyle(
|
||||||
token.componentCls,
|
|
||||||
{
|
{
|
||||||
color: token.colorErrorHover,
|
color: token.colorErrorHover,
|
||||||
},
|
},
|
||||||
|
|
@ -341,14 +343,13 @@ const genLinkButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
// Type: Text
|
// Type: Text
|
||||||
const genTextButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
const genTextButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
...genHoverActiveButtonStyle(
|
...genHoverActiveButtonStyle(
|
||||||
token.componentCls,
|
|
||||||
{
|
{
|
||||||
color: token.colorText,
|
color: token.colorText,
|
||||||
background: token.textHoverBg,
|
backgroundColor: token.colorBgTextHover,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
color: token.colorText,
|
color: token.colorText,
|
||||||
background: token.colorBgTextActive,
|
backgroundColor: token.colorBgTextActive,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
@ -359,19 +360,26 @@ const genTextButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
|
|
||||||
...genPureDisabledButtonStyle(token),
|
...genPureDisabledButtonStyle(token),
|
||||||
...genHoverActiveButtonStyle(
|
...genHoverActiveButtonStyle(
|
||||||
token.componentCls,
|
|
||||||
{
|
{
|
||||||
color: token.colorErrorHover,
|
color: token.colorErrorHover,
|
||||||
background: token.colorErrorBg,
|
backgroundColor: token.colorErrorBg,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
color: token.colorErrorHover,
|
color: token.colorErrorHover,
|
||||||
background: token.colorErrorBg,
|
backgroundColor: token.colorErrorBg,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Href and Disabled
|
||||||
|
const genDisabledButtonStyle: GenerateStyle<ButtonToken, CSSObject> = token => ({
|
||||||
|
...genDisabledStyle(token),
|
||||||
|
[`&${token.componentCls}:hover`]: {
|
||||||
|
...genDisabledStyle(token),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const genTypeButtonStyle: GenerateStyle<ButtonToken> = token => {
|
const genTypeButtonStyle: GenerateStyle<ButtonToken> = token => {
|
||||||
const { componentCls } = token;
|
const { componentCls } = token;
|
||||||
|
|
||||||
|
|
@ -381,30 +389,26 @@ const genTypeButtonStyle: GenerateStyle<ButtonToken> = token => {
|
||||||
[`${componentCls}-dashed`]: genDashedButtonStyle(token),
|
[`${componentCls}-dashed`]: genDashedButtonStyle(token),
|
||||||
[`${componentCls}-link`]: genLinkButtonStyle(token),
|
[`${componentCls}-link`]: genLinkButtonStyle(token),
|
||||||
[`${componentCls}-text`]: genTextButtonStyle(token),
|
[`${componentCls}-text`]: genTextButtonStyle(token),
|
||||||
[`${componentCls}-ghost`]: genGhostButtonStyle(
|
[`${componentCls}-disabled`]: genDisabledButtonStyle(token),
|
||||||
token.componentCls,
|
|
||||||
token.ghostBg,
|
|
||||||
token.colorBgContainer,
|
|
||||||
token.colorBgContainer,
|
|
||||||
token.colorTextDisabled,
|
|
||||||
token.colorBorder,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// =============================== Size ===============================
|
// =============================== Size ===============================
|
||||||
const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = '') => {
|
const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = ''): CSSInterpolation => {
|
||||||
const {
|
const {
|
||||||
componentCls,
|
componentCls,
|
||||||
|
iconCls,
|
||||||
controlHeight,
|
controlHeight,
|
||||||
fontSize,
|
fontSize,
|
||||||
lineHeight,
|
lineHeight,
|
||||||
|
lineWidth,
|
||||||
borderRadius,
|
borderRadius,
|
||||||
buttonPaddingHorizontal,
|
buttonPaddingHorizontal,
|
||||||
iconCls,
|
|
||||||
buttonPaddingVertical,
|
|
||||||
} = token;
|
} = token;
|
||||||
|
|
||||||
|
const paddingVertical = Math.max(0, (controlHeight - fontSize * lineHeight) / 2 - lineWidth);
|
||||||
|
const paddingHorizontal = buttonPaddingHorizontal - lineWidth;
|
||||||
|
|
||||||
const iconOnlyCls = `${componentCls}-icon-only`;
|
const iconOnlyCls = `${componentCls}-icon-only`;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
@ -412,9 +416,8 @@ const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = '') => {
|
||||||
{
|
{
|
||||||
[`${componentCls}${sizePrefixCls}`]: {
|
[`${componentCls}${sizePrefixCls}`]: {
|
||||||
fontSize,
|
fontSize,
|
||||||
lineHeight,
|
|
||||||
height: controlHeight,
|
height: controlHeight,
|
||||||
padding: `${unit(buttonPaddingVertical!)} ${unit(buttonPaddingHorizontal!)}`,
|
padding: `${paddingVertical}px ${paddingHorizontal}px`,
|
||||||
borderRadius,
|
borderRadius,
|
||||||
|
|
||||||
[`&${iconOnlyCls}`]: {
|
[`&${iconOnlyCls}`]: {
|
||||||
|
|
@ -424,8 +427,8 @@ const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = '') => {
|
||||||
[`&${componentCls}-round`]: {
|
[`&${componentCls}-round`]: {
|
||||||
width: 'auto',
|
width: 'auto',
|
||||||
},
|
},
|
||||||
[iconCls]: {
|
'> span': {
|
||||||
fontSize: token.buttonIconOnlyFontSize,
|
transform: 'scale(1.143)', // 14px -> 16px
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -438,6 +441,10 @@ const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = '') => {
|
||||||
[`${componentCls}-loading-icon`]: {
|
[`${componentCls}-loading-icon`]: {
|
||||||
transition: `width ${token.motionDurationSlow} ${token.motionEaseInOut}, opacity ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
transition: `width ${token.motionDurationSlow} ${token.motionEaseInOut}, opacity ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[`&:not(${iconOnlyCls}) ${componentCls}-loading-icon > ${iconCls}`]: {
|
||||||
|
marginInlineEnd: token.marginXS,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -451,24 +458,14 @@ const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = '') => {
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
const genSizeBaseButtonStyle: GenerateStyle<ButtonToken> = token =>
|
const genSizeBaseButtonStyle: GenerateStyle<ButtonToken> = token => genSizeButtonStyle(token);
|
||||||
genSizeButtonStyle(
|
|
||||||
mergeToken<ButtonToken>(token, {
|
|
||||||
fontSize: token.contentFontSize,
|
|
||||||
lineHeight: token.contentLineHeight,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const genSizeSmallButtonStyle: GenerateStyle<ButtonToken> = token => {
|
const genSizeSmallButtonStyle: GenerateStyle<ButtonToken> = token => {
|
||||||
const smallToken = mergeToken<ButtonToken>(token, {
|
const smallToken = mergeToken<ButtonToken>(token, {
|
||||||
controlHeight: token.controlHeightSM,
|
controlHeight: token.controlHeightSM,
|
||||||
fontSize: token.contentFontSizeSM,
|
|
||||||
lineHeight: token.contentLineHeightSM,
|
|
||||||
padding: token.paddingXS,
|
padding: token.paddingXS,
|
||||||
buttonPaddingHorizontal: token.paddingInlineSM,
|
buttonPaddingHorizontal: 8, // Fixed padding
|
||||||
buttonPaddingVertical: token.paddingBlockSM,
|
|
||||||
borderRadius: token.borderRadiusSM,
|
borderRadius: token.borderRadiusSM,
|
||||||
buttonIconOnlyFontSize: token.onlyIconSizeSM,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return genSizeButtonStyle(smallToken, `${token.componentCls}-sm`);
|
return genSizeButtonStyle(smallToken, `${token.componentCls}-sm`);
|
||||||
|
|
@ -477,12 +474,8 @@ const genSizeSmallButtonStyle: GenerateStyle<ButtonToken> = token => {
|
||||||
const genSizeLargeButtonStyle: GenerateStyle<ButtonToken> = token => {
|
const genSizeLargeButtonStyle: GenerateStyle<ButtonToken> = token => {
|
||||||
const largeToken = mergeToken<ButtonToken>(token, {
|
const largeToken = mergeToken<ButtonToken>(token, {
|
||||||
controlHeight: token.controlHeightLG,
|
controlHeight: token.controlHeightLG,
|
||||||
fontSize: token.contentFontSizeLG,
|
fontSize: token.fontSizeLG,
|
||||||
lineHeight: token.contentLineHeightLG,
|
|
||||||
buttonPaddingHorizontal: token.paddingInlineLG,
|
|
||||||
buttonPaddingVertical: token.paddingBlockLG,
|
|
||||||
borderRadius: token.borderRadiusLG,
|
borderRadius: token.borderRadiusLG,
|
||||||
buttonIconOnlyFontSize: token.onlyIconSizeLG,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return genSizeButtonStyle(largeToken, `${token.componentCls}-lg`);
|
return genSizeButtonStyle(largeToken, `${token.componentCls}-lg`);
|
||||||
|
|
@ -500,10 +493,12 @@ const genBlockButtonStyle: GenerateStyle<ButtonToken> = token => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================== Export ==============================
|
// ============================== Export ==============================
|
||||||
export default genStyleHooks(
|
export default genComponentStyleHook('Button', token => {
|
||||||
'Button',
|
const { controlTmpOutline, paddingContentHorizontal } = token;
|
||||||
token => {
|
const buttonToken = mergeToken<ButtonToken>(token, {
|
||||||
const buttonToken = prepareToken(token);
|
colorOutlineDefault: controlTmpOutline,
|
||||||
|
buttonPaddingHorizontal: paddingContentHorizontal,
|
||||||
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
// Shared
|
// Shared
|
||||||
|
|
@ -517,20 +512,14 @@ export default genStyleHooks(
|
||||||
// Block
|
// Block
|
||||||
genBlockButtonStyle(buttonToken),
|
genBlockButtonStyle(buttonToken),
|
||||||
|
|
||||||
// Group (type, ghost, danger, loading)
|
// Group (type, ghost, danger, disabled, loading)
|
||||||
genTypeButtonStyle(buttonToken),
|
genTypeButtonStyle(buttonToken),
|
||||||
|
|
||||||
// Button Group
|
// Button Group
|
||||||
genGroupStyle(buttonToken),
|
genGroupStyle(buttonToken),
|
||||||
|
|
||||||
|
// Space Compact
|
||||||
|
genCompactItemStyle(token, { focus: false }),
|
||||||
|
genCompactItemVerticalStyle(token),
|
||||||
];
|
];
|
||||||
},
|
});
|
||||||
prepareComponentToken,
|
|
||||||
{
|
|
||||||
unitless: {
|
|
||||||
fontWeight: true,
|
|
||||||
contentLineHeight: true,
|
|
||||||
contentLineHeightSM: true,
|
|
||||||
contentLineHeightLG: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
|
||||||
|
|
@ -1,234 +0,0 @@
|
||||||
import type { CSSProperties } from 'vue';
|
|
||||||
import type { FullToken, GetDefaultToken } from '../../theme/internal';
|
|
||||||
import { getLineHeight, mergeToken } from '../../theme/internal';
|
|
||||||
import type { GenStyleFn } from '../../theme/util/genComponentStyleHook';
|
|
||||||
|
|
||||||
/** Component only token. Which will handle additional calculation of alias token */
|
|
||||||
export interface ComponentToken {
|
|
||||||
/**
|
|
||||||
* @desc 文字字重
|
|
||||||
* @descEN Font weight of text
|
|
||||||
*/
|
|
||||||
fontWeight: CSSProperties['fontWeight'];
|
|
||||||
/**
|
|
||||||
* @desc 默认按钮阴影
|
|
||||||
* @descEN Shadow of default button
|
|
||||||
*/
|
|
||||||
defaultShadow: string;
|
|
||||||
/**
|
|
||||||
* @desc 主要按钮阴影
|
|
||||||
* @descEN Shadow of primary button
|
|
||||||
*/
|
|
||||||
primaryShadow: string;
|
|
||||||
/**
|
|
||||||
* @desc 危险按钮阴影
|
|
||||||
* @descEN Shadow of danger button
|
|
||||||
*/
|
|
||||||
dangerShadow: string;
|
|
||||||
/**
|
|
||||||
* @desc 主要按钮文本颜色
|
|
||||||
* @descEN Text color of primary button
|
|
||||||
*/
|
|
||||||
primaryColor: string;
|
|
||||||
/**
|
|
||||||
* @desc 默认按钮文本颜色
|
|
||||||
* @descEN Text color of default button
|
|
||||||
*/
|
|
||||||
defaultColor: string;
|
|
||||||
/**
|
|
||||||
* @desc 默认按钮背景色
|
|
||||||
* @descEN Background color of default button
|
|
||||||
*/
|
|
||||||
defaultBg: string;
|
|
||||||
/**
|
|
||||||
* @desc 默认按钮边框颜色
|
|
||||||
* @descEN Border color of default button
|
|
||||||
*/
|
|
||||||
defaultBorderColor: string;
|
|
||||||
/**
|
|
||||||
* @desc 危险按钮文本颜色
|
|
||||||
* @descEN Text color of danger button
|
|
||||||
*/
|
|
||||||
dangerColor: string;
|
|
||||||
/**
|
|
||||||
* @desc 禁用状态边框颜色
|
|
||||||
* @descEN Border color of disabled button
|
|
||||||
*/
|
|
||||||
borderColorDisabled: string;
|
|
||||||
/**
|
|
||||||
* @desc 默认幽灵按钮文本颜色
|
|
||||||
* @descEN Text color of default ghost button
|
|
||||||
*/
|
|
||||||
defaultGhostColor: string;
|
|
||||||
/**
|
|
||||||
* @desc 幽灵按钮背景色
|
|
||||||
* @descEN Background color of ghost button
|
|
||||||
*/
|
|
||||||
ghostBg: string;
|
|
||||||
/**
|
|
||||||
* @desc 默认幽灵按钮边框颜色
|
|
||||||
* @descEN Border color of default ghost button
|
|
||||||
*/
|
|
||||||
defaultGhostBorderColor: string;
|
|
||||||
/**
|
|
||||||
* @desc 按钮横向内间距
|
|
||||||
* @descEN Horizontal padding of button
|
|
||||||
*/
|
|
||||||
paddingInline: CSSProperties['paddingInline'];
|
|
||||||
/**
|
|
||||||
* @desc 大号按钮横向内间距
|
|
||||||
* @descEN Horizontal padding of large button
|
|
||||||
*/
|
|
||||||
paddingInlineLG: CSSProperties['paddingInline'];
|
|
||||||
/**
|
|
||||||
* @desc 小号按钮横向内间距
|
|
||||||
* @descEN Horizontal padding of small button
|
|
||||||
*/
|
|
||||||
paddingInlineSM: CSSProperties['paddingInline'];
|
|
||||||
/**
|
|
||||||
* @desc 按钮横向内间距
|
|
||||||
* @descEN Horizontal padding of button
|
|
||||||
*/
|
|
||||||
paddingBlock: CSSProperties['paddingInline'];
|
|
||||||
/**
|
|
||||||
* @desc 大号按钮横向内间距
|
|
||||||
* @descEN Horizontal padding of large button
|
|
||||||
*/
|
|
||||||
paddingBlockLG: CSSProperties['paddingInline'];
|
|
||||||
/**
|
|
||||||
* @desc 小号按钮横向内间距
|
|
||||||
* @descEN Horizontal padding of small button
|
|
||||||
*/
|
|
||||||
paddingBlockSM: CSSProperties['paddingInline'];
|
|
||||||
/**
|
|
||||||
* @desc 只有图标的按钮图标尺寸
|
|
||||||
* @descEN Icon size of button which only contains icon
|
|
||||||
*/
|
|
||||||
onlyIconSize: number;
|
|
||||||
/**
|
|
||||||
* @desc 大号只有图标的按钮图标尺寸
|
|
||||||
* @descEN Icon size of large button which only contains icon
|
|
||||||
*/
|
|
||||||
onlyIconSizeLG: number;
|
|
||||||
/**
|
|
||||||
* @desc 小号只有图标的按钮图标尺寸
|
|
||||||
* @descEN Icon size of small button which only contains icon
|
|
||||||
*/
|
|
||||||
onlyIconSizeSM: number;
|
|
||||||
/**
|
|
||||||
* @desc 按钮组边框颜色
|
|
||||||
* @descEN Border color of button group
|
|
||||||
*/
|
|
||||||
groupBorderColor: string;
|
|
||||||
/**
|
|
||||||
* @desc 链接按钮悬浮态背景色
|
|
||||||
* @descEN Background color of link button when hover
|
|
||||||
*/
|
|
||||||
linkHoverBg: string;
|
|
||||||
/**
|
|
||||||
* @desc 文本按钮悬浮态背景色
|
|
||||||
* @descEN Background color of text button when hover
|
|
||||||
*/
|
|
||||||
textHoverBg: string;
|
|
||||||
/**
|
|
||||||
* @desc 按钮内容字体大小
|
|
||||||
* @descEN Font size of button content
|
|
||||||
*/
|
|
||||||
contentFontSize: number;
|
|
||||||
/**
|
|
||||||
* @desc 大号按钮内容字体大小
|
|
||||||
* @descEN Font size of large button content
|
|
||||||
*/
|
|
||||||
contentFontSizeLG: number;
|
|
||||||
/**
|
|
||||||
* @desc 小号按钮内容字体大小
|
|
||||||
* @descEN Font size of small button content
|
|
||||||
*/
|
|
||||||
contentFontSizeSM: number;
|
|
||||||
/**
|
|
||||||
* @desc 按钮内容字体行高
|
|
||||||
* @descEN Line height of button content
|
|
||||||
*/
|
|
||||||
contentLineHeight: number;
|
|
||||||
/**
|
|
||||||
* @desc 大号按钮内容字体行高
|
|
||||||
* @descEN Line height of large button content
|
|
||||||
*/
|
|
||||||
contentLineHeightLG: number;
|
|
||||||
/**
|
|
||||||
* @desc 小号按钮内容字体行高
|
|
||||||
* @descEN Line height of small button content
|
|
||||||
*/
|
|
||||||
contentLineHeightSM: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ButtonToken extends FullToken<'Button'> {
|
|
||||||
buttonPaddingHorizontal: CSSProperties['paddingInline'];
|
|
||||||
buttonPaddingVertical: CSSProperties['paddingBlock'];
|
|
||||||
buttonIconOnlyFontSize: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const prepareToken: (token: Parameters<GenStyleFn<'Button'>>[0]) => ButtonToken = token => {
|
|
||||||
const { paddingInline, onlyIconSize, paddingBlock } = token;
|
|
||||||
|
|
||||||
const buttonToken = mergeToken<ButtonToken>(token, {
|
|
||||||
buttonPaddingHorizontal: paddingInline,
|
|
||||||
buttonPaddingVertical: paddingBlock,
|
|
||||||
buttonIconOnlyFontSize: onlyIconSize,
|
|
||||||
});
|
|
||||||
|
|
||||||
return buttonToken;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const prepareComponentToken: GetDefaultToken<'Button'> = token => {
|
|
||||||
const contentFontSize = token.contentFontSize ?? token.fontSize;
|
|
||||||
const contentFontSizeSM = token.contentFontSizeSM ?? token.fontSize;
|
|
||||||
const contentFontSizeLG = token.contentFontSizeLG ?? token.fontSizeLG;
|
|
||||||
const contentLineHeight = token.contentLineHeight ?? getLineHeight(contentFontSize);
|
|
||||||
const contentLineHeightSM = token.contentLineHeightSM ?? getLineHeight(contentFontSizeSM);
|
|
||||||
const contentLineHeightLG = token.contentLineHeightLG ?? getLineHeight(contentFontSizeLG);
|
|
||||||
|
|
||||||
return {
|
|
||||||
fontWeight: 400,
|
|
||||||
defaultShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlTmpOutline}`,
|
|
||||||
primaryShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlOutline}`,
|
|
||||||
dangerShadow: `0 ${token.controlOutlineWidth}px 0 ${token.colorErrorOutline}`,
|
|
||||||
primaryColor: token.colorTextLightSolid,
|
|
||||||
dangerColor: token.colorTextLightSolid,
|
|
||||||
borderColorDisabled: token.colorBorder,
|
|
||||||
defaultGhostColor: token.colorBgContainer,
|
|
||||||
ghostBg: 'transparent',
|
|
||||||
defaultGhostBorderColor: token.colorBgContainer,
|
|
||||||
paddingInline: token.paddingContentHorizontal - token.lineWidth,
|
|
||||||
paddingInlineLG: token.paddingContentHorizontal - token.lineWidth,
|
|
||||||
paddingInlineSM: 8 - token.lineWidth,
|
|
||||||
onlyIconSize: token.fontSizeLG,
|
|
||||||
onlyIconSizeSM: token.fontSizeLG - 2,
|
|
||||||
onlyIconSizeLG: token.fontSizeLG + 2,
|
|
||||||
groupBorderColor: token.colorPrimaryHover,
|
|
||||||
linkHoverBg: 'transparent',
|
|
||||||
textHoverBg: token.colorBgTextHover,
|
|
||||||
defaultColor: token.colorText,
|
|
||||||
defaultBg: token.colorBgContainer,
|
|
||||||
defaultBorderColor: token.colorBorder,
|
|
||||||
defaultBorderColorDisabled: token.colorBorder,
|
|
||||||
contentFontSize,
|
|
||||||
contentFontSizeSM,
|
|
||||||
contentFontSizeLG,
|
|
||||||
contentLineHeight,
|
|
||||||
contentLineHeightSM,
|
|
||||||
contentLineHeightLG,
|
|
||||||
paddingBlock: Math.max(
|
|
||||||
(token.controlHeight - contentFontSize * contentLineHeight) / 2 - token.lineWidth,
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
paddingBlockSM: Math.max(
|
|
||||||
(token.controlHeightSM - contentFontSizeSM * contentLineHeightSM) / 2 - token.lineWidth,
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
paddingBlockLG: Math.max(
|
|
||||||
(token.controlHeightLG - contentFontSizeLG * contentLineHeightLG) / 2 - token.lineWidth,
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
@ -57,18 +57,6 @@ export interface ThemeConfig {
|
||||||
algorithm?: MappingAlgorithm | MappingAlgorithm[];
|
algorithm?: MappingAlgorithm | MappingAlgorithm[];
|
||||||
hashed?: boolean;
|
hashed?: boolean;
|
||||||
inherit?: boolean;
|
inherit?: boolean;
|
||||||
cssVar?:
|
|
||||||
| {
|
|
||||||
/**
|
|
||||||
* Prefix for css variable, default to `antd`.
|
|
||||||
*/
|
|
||||||
prefix?: string;
|
|
||||||
/**
|
|
||||||
* Unique key for theme, should be set manually < react@18.
|
|
||||||
*/
|
|
||||||
key?: string;
|
|
||||||
}
|
|
||||||
| boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const configProviderProps = () => ({
|
export const configProviderProps = () => ({
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
import { useToken } from '../../theme/internal';
|
|
||||||
import type { Ref } from 'vue';
|
|
||||||
import { computed } from 'vue';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This hook is only for cssVar to add root className for components.
|
|
||||||
* If root ClassName is needed, this hook could be refactored with `-root`
|
|
||||||
* @param prefixCls
|
|
||||||
*/
|
|
||||||
const useCSSVarCls = (prefixCls: Ref<string>) => {
|
|
||||||
const [, , , , cssVar] = useToken();
|
|
||||||
|
|
||||||
return computed(() => (cssVar.value ? `${prefixCls.value}-css-var` : ''));
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useCSSVarCls;
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
import type { SizeType } from '../SizeContext';
|
|
||||||
import { useInjectSize } from '../SizeContext';
|
|
||||||
import type { Ref } from 'vue';
|
|
||||||
import { computed, shallowRef, watch } from 'vue';
|
|
||||||
|
|
||||||
const useSize = <T>(customSize?: T | ((ctxSize: SizeType) => T)): Ref<T> => {
|
|
||||||
const size = useInjectSize();
|
|
||||||
|
|
||||||
const mergedSize = shallowRef(null);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
computed(() => {
|
|
||||||
return [customSize, size.value];
|
|
||||||
}),
|
|
||||||
() => {
|
|
||||||
if (!customSize) {
|
|
||||||
mergedSize.value = size.value as T;
|
|
||||||
}
|
|
||||||
if (typeof customSize === 'string') {
|
|
||||||
mergedSize.value = customSize ?? (size.value as T);
|
|
||||||
}
|
|
||||||
if (customSize instanceof Function) {
|
|
||||||
mergedSize.value = customSize(size.value) as T;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
return mergedSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useSize;
|
|
||||||
|
|
@ -2,26 +2,13 @@ import type { ThemeConfig } from '../context';
|
||||||
import { defaultConfig } from '../../theme/internal';
|
import { defaultConfig } from '../../theme/internal';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import devWarning from '../../vc-util/warning';
|
|
||||||
const themeKey = 'antdvtheme';
|
|
||||||
export default function useTheme(theme?: Ref<ThemeConfig>, parentTheme?: Ref<ThemeConfig>) {
|
export default function useTheme(theme?: Ref<ThemeConfig>, parentTheme?: Ref<ThemeConfig>) {
|
||||||
const themeConfig = computed(() => theme?.value || {});
|
const themeConfig = computed(() => theme?.value || {});
|
||||||
const parentThemeConfig = computed<ThemeConfig>(() =>
|
const parentThemeConfig = computed<ThemeConfig>(() =>
|
||||||
themeConfig.value.inherit === false || !parentTheme?.value ? defaultConfig : parentTheme.value,
|
themeConfig.value.inherit === false || !parentTheme?.value ? defaultConfig : parentTheme.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
const cssVarEnabled = themeConfig.value.cssVar || parentThemeConfig.value.cssVar;
|
|
||||||
const validKey = !!(
|
|
||||||
(typeof themeConfig.value.cssVar === 'object' && themeConfig.value.cssVar?.key) ||
|
|
||||||
themeKey
|
|
||||||
);
|
|
||||||
devWarning(
|
|
||||||
!cssVarEnabled || validKey,
|
|
||||||
'[Ant Design Vue ConfigProvider] Missing key in `cssVar` config. Please set `cssVar.key` manually in each ConfigProvider inside `cssVar` enabled ConfigProvider.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mergedTheme = computed(() => {
|
const mergedTheme = computed(() => {
|
||||||
if (!theme?.value) {
|
if (!theme?.value) {
|
||||||
return parentTheme?.value;
|
return parentTheme?.value;
|
||||||
|
|
@ -39,17 +26,6 @@ export default function useTheme(theme?: Ref<ThemeConfig>, parentTheme?: Ref<The
|
||||||
} as any;
|
} as any;
|
||||||
});
|
});
|
||||||
|
|
||||||
const cssVarKey = `css-var-${themeKey.replace(/:/g, '')}`;
|
|
||||||
|
|
||||||
const mergedCssVar = (themeConfig.value.cssVar ?? parentThemeConfig.value.cssVar) && {
|
|
||||||
prefix: 'ant', // Default to ant
|
|
||||||
...(typeof parentThemeConfig.value.cssVar === 'object' ? parentThemeConfig.value.cssVar : {}),
|
|
||||||
...(typeof themeConfig.value.cssVar === 'object' ? themeConfig.value.cssVar : {}),
|
|
||||||
key:
|
|
||||||
(typeof themeConfig.value.cssVar === 'object' && themeConfig.value.cssVar?.key) ||
|
|
||||||
cssVarKey,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Base token
|
// Base token
|
||||||
return {
|
return {
|
||||||
...parentThemeConfig.value,
|
...parentThemeConfig.value,
|
||||||
|
|
@ -60,7 +36,6 @@ export default function useTheme(theme?: Ref<ThemeConfig>, parentTheme?: Ref<The
|
||||||
...themeConfig.value.token,
|
...themeConfig.value.token,
|
||||||
},
|
},
|
||||||
components: mergedComponents,
|
components: mergedComponents,
|
||||||
cssVar: mergedCssVar,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
let uid = 0;
|
|
||||||
const useThemeKey = () => {
|
|
||||||
return 'themekey' + uid++;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useThemeKey;
|
|
||||||
|
|
@ -15,7 +15,7 @@ import type { ValidateMessages } from '../form/interface';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
import useTheme from './hooks/useTheme';
|
import useTheme from './hooks/useTheme';
|
||||||
import defaultSeedToken from '../theme/themes/seed';
|
import defaultSeedToken from '../theme/themes/seed';
|
||||||
import type { ConfigProviderInnerProps, ConfigProviderProps, Theme, ThemeConfig } from './context';
|
import type { ConfigProviderInnerProps, ConfigProviderProps, Theme } from './context';
|
||||||
import {
|
import {
|
||||||
useConfigContextProvider,
|
useConfigContextProvider,
|
||||||
useConfigContextInject,
|
useConfigContextInject,
|
||||||
|
|
@ -26,7 +26,7 @@ import {
|
||||||
import { useProviderSize } from './SizeContext';
|
import { useProviderSize } from './SizeContext';
|
||||||
import { useProviderDisabled } from './DisabledContext';
|
import { useProviderDisabled } from './DisabledContext';
|
||||||
import { createTheme } from '../_util/cssinjs';
|
import { createTheme } from '../_util/cssinjs';
|
||||||
import { defaultTheme, DesignTokenProvider } from '../theme/context';
|
import { DesignTokenProvider } from '../theme/internal';
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
ConfigProviderProps,
|
ConfigProviderProps,
|
||||||
|
|
@ -226,47 +226,19 @@ const ConfigProvider = defineComponent({
|
||||||
|
|
||||||
// ================================ Dynamic theme ================================
|
// ================================ Dynamic theme ================================
|
||||||
const memoTheme = computed(() => {
|
const memoTheme = computed(() => {
|
||||||
const { algorithm, token, components, cssVar, ...rest } = mergedTheme.value || {};
|
const { algorithm, token, ...rest } = mergedTheme.value || {};
|
||||||
const themeObj =
|
const themeObj =
|
||||||
algorithm && (!Array.isArray(algorithm) || algorithm.length > 0)
|
algorithm && (!Array.isArray(algorithm) || algorithm.length > 0)
|
||||||
? createTheme(algorithm)
|
? createTheme(algorithm)
|
||||||
: defaultTheme;
|
: undefined;
|
||||||
|
|
||||||
const parsedComponents: any = {};
|
|
||||||
Object.entries(components || {}).forEach(([componentName, componentToken]) => {
|
|
||||||
const parsedToken: typeof componentToken & { theme?: typeof defaultTheme } = {
|
|
||||||
...componentToken,
|
|
||||||
};
|
|
||||||
if ('algorithm' in parsedToken) {
|
|
||||||
if (parsedToken.algorithm === true) {
|
|
||||||
parsedToken.theme = themeObj;
|
|
||||||
} else if (
|
|
||||||
Array.isArray(parsedToken.algorithm) ||
|
|
||||||
typeof parsedToken.algorithm === 'function'
|
|
||||||
) {
|
|
||||||
parsedToken.theme = createTheme(parsedToken.algorithm as any);
|
|
||||||
}
|
|
||||||
delete parsedToken.algorithm;
|
|
||||||
}
|
|
||||||
parsedComponents[componentName] = parsedToken;
|
|
||||||
});
|
|
||||||
|
|
||||||
const mergedToken = {
|
|
||||||
...defaultSeedToken,
|
|
||||||
...token,
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...rest,
|
...rest,
|
||||||
theme: themeObj,
|
theme: themeObj,
|
||||||
|
|
||||||
token: mergedToken,
|
token: {
|
||||||
components: parsedComponents,
|
...defaultSeedToken,
|
||||||
override: {
|
...token,
|
||||||
override: mergedToken,
|
|
||||||
...parsedComponents,
|
|
||||||
},
|
},
|
||||||
cssVar: cssVar as Exclude<ThemeConfig['cssVar'], boolean>,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const validateMessagesRef = computed(() => {
|
const validateMessagesRef = computed(() => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
|
||||||
import { useStyleRegister } from '../../_util/cssinjs';
|
import { useStyleRegister } from '../../_util/cssinjs';
|
||||||
import { resetIcon } from '../../style';
|
import { resetIcon } from '../../style';
|
||||||
import { useToken } from '../../theme/internal';
|
import { useToken } from '../../theme/internal';
|
||||||
|
|
@ -14,8 +13,7 @@ const useStyle = (iconPrefixCls: Ref<string>) => {
|
||||||
hashId: '',
|
hashId: '',
|
||||||
path: ['ant-design-icons', iconPrefixCls.value],
|
path: ['ant-design-icons', iconPrefixCls.value],
|
||||||
})),
|
})),
|
||||||
() =>
|
() => [
|
||||||
[
|
|
||||||
{
|
{
|
||||||
[`.${iconPrefixCls.value}`]: {
|
[`.${iconPrefixCls.value}`]: {
|
||||||
...resetIcon(),
|
...resetIcon(),
|
||||||
|
|
@ -24,7 +22,7 @@ const useStyle = (iconPrefixCls: Ref<string>) => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
] as CSSObject[],
|
],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,6 @@ import type { TokenWithCommonCls } from '../../theme/util/genComponentStyleHook'
|
||||||
import { resetComponent, roundedArrow, textEllipsis } from '../../style';
|
import { resetComponent, roundedArrow, textEllipsis } from '../../style';
|
||||||
import { genCompactItemStyle } from '../../style/compact-item';
|
import { genCompactItemStyle } from '../../style/compact-item';
|
||||||
|
|
||||||
export interface ComponentToken {}
|
|
||||||
|
|
||||||
export interface ComponentToken {
|
export interface ComponentToken {
|
||||||
presetsWidth: number;
|
presetsWidth: number;
|
||||||
presetsMaxWidth: number;
|
presetsMaxWidth: number;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
import { resetComponent, textEllipsis } from '../../style';
|
import { resetComponent, textEllipsis } from '../../style';
|
||||||
|
|
||||||
export interface ComponentToken {}
|
|
||||||
|
|
||||||
interface DescriptionsToken extends FullToken<'Descriptions'> {
|
interface DescriptionsToken extends FullToken<'Descriptions'> {
|
||||||
descriptionsTitleMarginBottom: number;
|
descriptionsTitleMarginBottom: number;
|
||||||
descriptionsExtraColor: string;
|
descriptionsExtraColor: string;
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ const BackTop = defineComponent({
|
||||||
|
|
||||||
const handleScroll = throttleByAnimationFrame((e: Event | { target: any }) => {
|
const handleScroll = throttleByAnimationFrame((e: Event | { target: any }) => {
|
||||||
const { visibilityHeight } = props;
|
const { visibilityHeight } = props;
|
||||||
const scrollTop = getScroll(e.target);
|
const scrollTop = getScroll(e.target, true);
|
||||||
state.visible = scrollTop >= visibilityHeight;
|
state.visible = scrollTop >= visibilityHeight;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
import { resetComponent } from '../../style';
|
import { resetComponent } from '../../style';
|
||||||
import genFormValidateMotionStyle from './explain';
|
import genFormValidateMotionStyle from './explain';
|
||||||
|
|
||||||
export interface ComponentToken {}
|
|
||||||
|
|
||||||
export interface FormToken extends FullToken<'Form'> {
|
export interface FormToken extends FullToken<'Form'> {
|
||||||
formItemCls: string;
|
formItemCls: string;
|
||||||
rootPrefixCls: string;
|
rootPrefixCls: string;
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ import type { CSSObject } from '../../_util/cssinjs';
|
||||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
|
|
||||||
export interface ComponentToken {}
|
|
||||||
|
|
||||||
interface GridRowToken extends FullToken<'Grid'> {}
|
interface GridRowToken extends FullToken<'Grid'> {}
|
||||||
|
|
||||||
interface GridColToken extends FullToken<'Grid'> {
|
interface GridColToken extends FullToken<'Grid'> {
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,13 @@ exports[`renders ./components/image/demo/placeholder.vue correctly 1`] = `
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/image/demo/preview-group.vue correctly 1`] = `
|
exports[`renders ./components/image/demo/preview-group.vue correctly 1`] = `
|
||||||
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://aliyuncdn.antdv.com/vue.png">
|
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://www.antdv.com/vue.png">
|
||||||
<!---->
|
<!---->
|
||||||
<div class="ant-image-mask">
|
<div class="ant-image-mask">
|
||||||
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
|
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://aliyuncdn.antdv.com/logo.png">
|
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://www.antdv.com/logo.png">
|
||||||
<!---->
|
<!---->
|
||||||
<div class="ant-image-mask">
|
<div class="ant-image-mask">
|
||||||
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
|
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
|
||||||
|
|
@ -106,7 +106,7 @@ exports[`renders ./components/image/demo/preview-group-visible.vue correctly 1`]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/image/demo/preview-src.vue correctly 1`] = `
|
exports[`renders ./components/image/demo/preview-src.vue correctly 1`] = `
|
||||||
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://aliyuncdn.antdv.com/logo.png">
|
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://www.antdv.com/logo.png">
|
||||||
<!---->
|
<!---->
|
||||||
<div class="ant-image-mask">
|
<div class="ant-image-mask">
|
||||||
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
|
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ Click the left and right switch buttons to preview multiple images.
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-image-preview-group>
|
<a-image-preview-group>
|
||||||
<a-image :width="200" src="https://aliyuncdn.antdv.com/vue.png" />
|
<a-image :width="200" src="https://www.antdv.com/vue.png" />
|
||||||
<a-image :width="200" src="https://aliyuncdn.antdv.com/logo.png" />
|
<a-image :width="200" src="https://www.antdv.com/logo.png" />
|
||||||
</a-image-preview-group>
|
</a-image-preview-group>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ You can set different preview image.
|
||||||
<template>
|
<template>
|
||||||
<a-image
|
<a-image
|
||||||
:width="200"
|
:width="200"
|
||||||
src="https://aliyuncdn.antdv.com/logo.png"
|
src="https://www.antdv.com/logo.png"
|
||||||
:preview="{
|
:preview="{
|
||||||
src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||||
}"
|
}"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import type { App } from 'vue';
|
||||||
|
|
||||||
import * as components from './components';
|
import * as components from './components';
|
||||||
import { default as version } from './version';
|
import { default as version } from './version';
|
||||||
import * as cssinjs from './_util/cssinjs';
|
import cssinjs from './_util/cssinjs';
|
||||||
export * from './components';
|
export * from './components';
|
||||||
export * from './_util/cssinjs';
|
export * from './_util/cssinjs';
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue