chore: use monorepo
parent
f5560db05d
commit
c49a9aa6c3
|
@ -1,36 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const restCssPath = path.join(process.cwd(), 'components', 'style', 'reset.css');
|
||||
const tokenStatisticPath = path.join(process.cwd(), 'components', 'version', 'token.json');
|
||||
const tokenMetaPath = path.join(process.cwd(), 'components', 'version', 'token-meta.json');
|
||||
|
||||
function finalizeCompile() {
|
||||
if (fs.existsSync(path.join(__dirname, './es'))) {
|
||||
fs.copyFileSync(restCssPath, path.join(process.cwd(), 'es', 'style', 'reset.css'));
|
||||
fs.copyFileSync(tokenStatisticPath, path.join(process.cwd(), 'es', 'version', 'token.json'));
|
||||
fs.copyFileSync(tokenMetaPath, path.join(process.cwd(), 'es', 'version', 'token-meta.json'));
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.join(__dirname, './lib'))) {
|
||||
fs.copyFileSync(restCssPath, path.join(process.cwd(), 'lib', 'style', 'reset.css'));
|
||||
fs.copyFileSync(tokenStatisticPath, path.join(process.cwd(), 'lib', 'version', 'token.json'));
|
||||
fs.copyFileSync(tokenMetaPath, path.join(process.cwd(), 'lib', 'version', 'token-meta.json'));
|
||||
}
|
||||
}
|
||||
|
||||
function finalizeDist() {
|
||||
if (fs.existsSync(path.join(__dirname, './dist'))) {
|
||||
fs.copyFileSync(restCssPath, path.join(process.cwd(), 'dist', 'reset.css'));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
compile: {
|
||||
finalize: finalizeCompile,
|
||||
},
|
||||
dist: {
|
||||
finalize: finalizeDist,
|
||||
},
|
||||
bail: true,
|
||||
};
|
|
@ -1,2 +0,0 @@
|
|||
codecov:
|
||||
branch: master
|
|
@ -1,11 +0,0 @@
|
|||
# 🎨 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
|
|
@ -1,13 +0,0 @@
|
|||
node_modules/
|
||||
**/*.spec.*
|
||||
**/style/
|
||||
*.html
|
||||
/components/test/*
|
||||
es/
|
||||
lib/
|
||||
_site/
|
||||
dist/
|
||||
site/dist/
|
||||
components/version/version.ts
|
||||
site/src/router/demoRoutes.js
|
||||
locale/
|
112
.eslintrc.js
112
.eslintrc.js
|
@ -1,112 +0,0 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
jasmine: true,
|
||||
jest: true,
|
||||
es6: true,
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
},
|
||||
extends: [
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'@vue/typescript/recommended',
|
||||
'@vue/prettier',
|
||||
// 'prettier',
|
||||
],
|
||||
// extends: [
|
||||
// 'eslint:recommended',
|
||||
// 'plugin:vue/vue3-recommended',
|
||||
// '@vue/typescript/recommended',
|
||||
// '@vue/prettier',
|
||||
// ],
|
||||
plugins: ['markdown', 'jest', '@typescript-eslint', 'import'],
|
||||
globals: {
|
||||
h: true,
|
||||
defineProps: 'readonly',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.md'],
|
||||
processor: 'markdown/markdown',
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*.ts', '*.tsx'],
|
||||
// extends: ['@vue/typescript/recommended', '@vue/prettier'],
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/ban-types': 0,
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 0,
|
||||
'@typescript-eslint/no-empty-function': 0,
|
||||
'@typescript-eslint/no-non-null-assertion': 0,
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{ vars: 'all', args: 'after-used', ignoreRestSiblings: true },
|
||||
],
|
||||
'@typescript-eslint/ban-ts-comment': 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*.vue'],
|
||||
parser: 'vue-eslint-parser',
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser',
|
||||
ecmaVersion: 2021,
|
||||
},
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
'vue/no-reserved-component-names': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 0,
|
||||
'@typescript-eslint/no-empty-function': 0,
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{ vars: 'all', args: 'after-used', ignoreRestSiblings: true, argsIgnorePattern: '^_' },
|
||||
],
|
||||
'import/no-named-as-default': 'off',
|
||||
'import/namespace': [2, { allowComputed: true }],
|
||||
'import/no-named-as-default-member': 'off',
|
||||
'import/no-unresolved': [2, { ignore: ['ant-design-vue'] }],
|
||||
'comma-dangle': [2, 'always-multiline'],
|
||||
'no-var': 'error',
|
||||
'no-console': [2, { allow: ['warn', 'error'] }],
|
||||
'object-shorthand': 2,
|
||||
'no-unused-vars': [2, { ignoreRestSiblings: true, argsIgnorePattern: '^_' }],
|
||||
'no-undef': 2,
|
||||
camelcase: 'off',
|
||||
'no-extra-boolean-cast': 'off',
|
||||
semi: ['error', 'always'],
|
||||
'vue/no-v-html': 'off',
|
||||
'vue/require-explicit-emits': 'off',
|
||||
'vue/require-prop-types': 'off',
|
||||
'vue/require-default-prop': 'off',
|
||||
'vue/no-reserved-keys': 'off',
|
||||
'vue/comment-directive': 'off',
|
||||
'vue/prop-name-casing': 'off',
|
||||
'vue/one-component-per-file': 'off',
|
||||
'vue/custom-event-name-casing': 'off',
|
||||
'vue/v-on-event-hyphenation': 'off',
|
||||
'vue/max-attributes-per-line': [
|
||||
2,
|
||||
{
|
||||
singleline: 20,
|
||||
multiline: 1,
|
||||
},
|
||||
],
|
||||
'vue/multi-word-component-names': 'off',
|
||||
},
|
||||
};
|
|
@ -66,9 +66,6 @@ package-lock.json
|
|||
pnpm-lock.yaml
|
||||
/coverage
|
||||
|
||||
# 备份文件
|
||||
/components/test/*
|
||||
list.txt
|
||||
|
||||
site/dev.js
|
||||
|
||||
|
@ -77,10 +74,39 @@ vetur/
|
|||
|
||||
report.html
|
||||
|
||||
site/src/router/demoRoutes.js
|
||||
|
||||
components/version/version.ts
|
||||
components/version/version.tsx
|
||||
components/version/token.json
|
||||
components/version/token-meta.json
|
||||
~component-api.json
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.template
|
||||
|
||||
# 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/
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no-install pretty-quick --staged
|
7
.huskyrc
7
.huskyrc
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"hooks": {
|
||||
"pre-commit": "pretty-quick --staged",
|
||||
"pre-publish": "npm run lint",
|
||||
"commit-msg": "commitlint -x @commitlint/config-conventional -e $GIT_PARAMS"
|
||||
}
|
||||
}
|
60
.jest.js
60
.jest.js
|
@ -1,60 +0,0 @@
|
|||
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,
|
||||
},
|
||||
},
|
||||
};
|
|
@ -1,31 +0,0 @@
|
|||
**/*.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/
|
||||
|
17
.prettierrc
17
.prettierrc
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"endOfLine": "lf",
|
||||
"printWidth": 100,
|
||||
"proseWrap": "never",
|
||||
"arrowParens": "avoid",
|
||||
"htmlWhitespaceSensitivity": "ignore",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ".prettierrc",
|
||||
"options": {
|
||||
"parser": "json"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
23
.stylelintrc
23
.stylelintrc
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"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
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"stylelint-config-standard",
|
||||
"stylelint-config-rational-order",
|
||||
"stylelint-config-prettier"
|
||||
],
|
||||
"customSyntax": "postcss-less",
|
||||
"plugins": ["stylelint-declaration-block-no-ignored-properties"],
|
||||
"rules": {
|
||||
"function-name-case": ["lower"],
|
||||
"function-no-unknown": [
|
||||
true,
|
||||
{
|
||||
"ignoreFunctions": [
|
||||
"fade",
|
||||
"fadeout",
|
||||
"tint",
|
||||
"darken",
|
||||
"ceil",
|
||||
"fadein",
|
||||
"floor",
|
||||
"unit",
|
||||
"shade",
|
||||
"lighten",
|
||||
"percentage",
|
||||
"-"
|
||||
]
|
||||
}
|
||||
],
|
||||
"import-notation": null,
|
||||
"no-descending-specificity": null,
|
||||
"no-invalid-position-at-import-rule": null,
|
||||
"declaration-empty-line-before": null,
|
||||
"keyframes-name-pattern": null,
|
||||
"custom-property-pattern": null,
|
||||
"number-max-precision": 8,
|
||||
"alpha-value-notation": "number",
|
||||
"color-function-notation": "legacy",
|
||||
"selector-class-pattern": null,
|
||||
"selector-id-pattern": null,
|
||||
"selector-not-notation": null
|
||||
}
|
||||
}
|
17
.vcmrc
17
.vcmrc
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"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
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
@import '@ant-design-vue/tailwind-config';
|
||||
|
||||
@source '../index.html';
|
||||
@source '../src/**/*.{vue,ts}';
|
||||
@source '../../../node_modules/ant-design-vue/dist/lib.mjs';
|
||||
* {
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
export { default } from '@ant-design-vue/eslint-config/vue'
|
|
@ -0,0 +1,12 @@
|
|||
<!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>
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"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": "*",
|
||||
"@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",
|
||||
"react": "18",
|
||||
"react-dom": "18",
|
||||
"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/tailwind-config": "*",
|
||||
"@ant-design-vue/typescript-config": "*",
|
||||
"@ant-design-vue/vite-config": "*",
|
||||
"@tailwindcss/vite": "^4.1.3",
|
||||
"@types/cookies": "^0.9.0",
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"@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"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
export { default } from "@ant-design-vue/prettier-config/tailwind";
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<RouterView></RouterView>
|
||||
</template>
|
|
@ -0,0 +1,12 @@
|
|||
import '~/tailwind.css'
|
||||
import { createApp } from 'vue'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import App from './App.vue'
|
||||
import routes from './routes'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
})
|
||||
|
||||
createApp(App).use(router).mount('#app')
|
|
@ -0,0 +1,4 @@
|
|||
import { RouteRecordRaw } from 'vue-router'
|
||||
|
||||
const items = import.meta.glob('./pages/*/index.ts', { import: 'default', eager: true })
|
||||
export default Object.values(items) as RouteRecordRaw[]
|
|
@ -0,0 +1,5 @@
|
|||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
const component: DefineComponent<Record<string, never>, Record<string, never>, any>
|
||||
export default component
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
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
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
import tailwindcss from '@tailwindcss/vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { resolve } from 'node:path'
|
||||
import { defineConfig, Plugin } from 'vite'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
appType: 'mpa',
|
||||
plugins: [
|
||||
vue(),
|
||||
react(),
|
||||
tailwindcss(),
|
||||
],
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: resolve(__dirname, './index.html'),
|
||||
},
|
||||
},
|
||||
},
|
||||
server: {
|
||||
watch: {
|
||||
ignored: ['!**/node_modules/@ant-design-vue/**'],
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve(__dirname, './src'),
|
||||
'~': resolve(__dirname, './assets'),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
interface ImportmapOptions {
|
||||
imports: Record<string, string>
|
||||
}
|
||||
function importmapPlugin(options: ImportmapOptions): Plugin {
|
||||
return {
|
||||
name: 'vite-plugin-importmap',
|
||||
apply: 'build',
|
||||
config() {
|
||||
return {
|
||||
build: {
|
||||
rollupOptions: {
|
||||
external: Object.keys(options.imports),
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
transformIndexHtml: {
|
||||
order: 'pre',
|
||||
handler(html) {
|
||||
return {
|
||||
html,
|
||||
tags: [
|
||||
{
|
||||
tag: 'script',
|
||||
attrs: {
|
||||
type: 'importmap',
|
||||
},
|
||||
children: JSON.stringify(options),
|
||||
injectTo: 'head-prepend',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
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',
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
5
build.sh
5
build.sh
|
@ -1,5 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
rm -rf dist
|
||||
mkdir dist
|
||||
./node_modules/.bin/webpack --config webpack.site.config.js
|
||||
cp dist/index.html index.html
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
export default '4.2.6';
|
|
@ -0,0 +1,13 @@
|
|||
// @ts-check
|
||||
|
||||
import typescript from '@ant-design-vue/eslint-config/typescript'
|
||||
|
||||
/**
|
||||
* @type {import('eslint').Linter.Config[]}
|
||||
*/
|
||||
export default [
|
||||
...typescript,
|
||||
{
|
||||
ignores: ['apps/**', 'packages/**', 'packages-*/**'],
|
||||
},
|
||||
]
|
334
package.json
334
package.json
|
@ -1,316 +1,34 @@
|
|||
{
|
||||
"name": "ant-design-vue",
|
||||
"version": "4.2.6",
|
||||
"name": "@ant-design-vue/ant-design-vue",
|
||||
"private": true,
|
||||
"version": "5.0.0-alpha.1",
|
||||
"title": "Ant Design Vue",
|
||||
"description": "An enterprise-class UI design language and Vue-based implementation",
|
||||
"keywords": [
|
||||
"vue",
|
||||
"vue3",
|
||||
"ant",
|
||||
"design",
|
||||
"antd",
|
||||
"vueComponent",
|
||||
"component",
|
||||
"components",
|
||||
"ui",
|
||||
"framework",
|
||||
"frontend"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"unpkg": "dist/antd.min.js",
|
||||
"typings": "es/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"lib",
|
||||
"es",
|
||||
"scripts",
|
||||
"vetur",
|
||||
"typings/global.d.ts",
|
||||
"locale"
|
||||
"description": "An enterprise-class UI design language and Vue-based implementation for Ant Design",
|
||||
"type": "module",
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
"packages/*",
|
||||
"packages-*/*"
|
||||
],
|
||||
"scripts": {
|
||||
"collect-token-statistic": "tsx scripts/collect-token-statistic.js",
|
||||
"token-meta": "node scripts/generate-token-meta.js",
|
||||
"predev": "npm run version & npm run collect-token-statistic & npm run token-meta && node node_modules/esbuild/install.js",
|
||||
"precompile": "npm run version & npm run collect-token-statistic & npm run token-meta",
|
||||
"pretest": "npm run version",
|
||||
"predist": "npm run version",
|
||||
"presite": "npm run version & npm run routes & npm run collect-token-statistic & npm run token-meta",
|
||||
"dev": "npm run routes && vite serve site",
|
||||
"fast-dev": "npm run routes && vite serve site",
|
||||
"test": "cross-env NODE_ENV=test jest --config .jest.js",
|
||||
"compile": "node antd-tools/cli/run.js compile",
|
||||
"generator-webtypes": "tsc -p antd-tools/generator-types/tsconfig.json && node antd-tools/generator-types/index.js",
|
||||
"pub": "npm run version & npm run collect-token-statistic & npm run token-meta && node --max_old_space_size=8192 antd-tools/cli/run.js pub",
|
||||
"pub-with-ci": "npm run version & npm run collect-token-statistic & npm run token-meta && node antd-tools/cli/run.js pub-with-ci",
|
||||
"prepublishOnly": "node antd-tools/cli/run.js guard",
|
||||
"pre-publish": "npm run generator-webtypes",
|
||||
"prettier": "prettier -c --write **/*",
|
||||
"pretty-quick": "pretty-quick",
|
||||
"dist": "node --max_old_space_size=8192 antd-tools/cli/run.js dist",
|
||||
"lint": "npm run tsc && npm run lint:demo && npm run lint:md && npm run lint:script && npm run lint:site",
|
||||
"lint:components": "eslint --fix --ext .jsx,.js,.ts,.tsx ./components",
|
||||
"lint:demo": "eslint --fix components/*/demo/*.vue",
|
||||
"lint:md": "eslint --fix *.md",
|
||||
"lint:script": "eslint . --ext '.js,.jsx,.ts,.tsx'",
|
||||
"lint:site": "eslint --fix -c ./.eslintrc.js --ext .jsx,.js,.ts,.tsx,vue ./site",
|
||||
"lint:style": "stylelint \"{site,components}/**/*.less\" --syntax less",
|
||||
"codecov": "codecov",
|
||||
"routes": "node site/scripts/genrateRoutes.js",
|
||||
"tsc": "tsc --noEmit",
|
||||
"vue-tsc": "vue-tsc --noEmit",
|
||||
"site": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build site --base=https://next.antdv.com/",
|
||||
"pub:site": "npm run site && node site/scripts/pushToOSS.js",
|
||||
"prepare": "husky install",
|
||||
"version": "node ./scripts/generate-version",
|
||||
"sort-api": "node antd-tools/cli/run.js sort-api-table"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 0.5%",
|
||||
"last 2 versions",
|
||||
"Firefox ESR",
|
||||
"not dead"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vueComponent/ant-design-vue.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/ant-design-vue"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/vueComponent/ant-design-vue/issues"
|
||||
},
|
||||
"homepage": "https://www.antdv.com/",
|
||||
"peerDependencies": {
|
||||
"vue": ">=3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.22.0"
|
||||
"build": "turbo build",
|
||||
"dev": "turbo dev",
|
||||
"dev:apps": "turbo dev --filter=\"./apps/*\"",
|
||||
"lint": "turbo lint"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.8.4",
|
||||
"@babel/core": "^7.10.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.8.3",
|
||||
"@babel/plugin-proposal-export-namespace-from": "^7.12.1",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.9.6",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.10.1",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-transform-member-expression-literals": "^7.8.3",
|
||||
"@babel/plugin-transform-object-assign": "^7.8.3",
|
||||
"@babel/plugin-transform-property-literals": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.10.5",
|
||||
"@babel/plugin-transform-template-literals": "^7.8.3",
|
||||
"@babel/plugin-transform-typescript": "^7.12.1",
|
||||
"@babel/polyfill": "^7.8.7",
|
||||
"@babel/preset-env": "^7.9.6",
|
||||
"@babel/preset-typescript": "^7.10.4",
|
||||
"@commitlint/cli": "^12.0.0",
|
||||
"@commitlint/config-conventional": "^12.0.0",
|
||||
"@octokit/rest": "^18.0.0",
|
||||
"@rollup/plugin-babel": "^5.3.0",
|
||||
"@types/compression": "^1.7.0",
|
||||
"@types/fs-extra": "^9.0.8",
|
||||
"@types/jest": "^28.1.4",
|
||||
"@types/koa": "^2.11.6",
|
||||
"@types/lodash-es": "^4.17.3",
|
||||
"@types/lru-cache": "^5.1.0",
|
||||
"@types/markdown-it": "^10.0.2",
|
||||
"@types/node": "^14.0.0",
|
||||
"@types/postcss-load-config": "^2.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"@vitejs/plugin-legacy": "^2.2.0",
|
||||
"@vitejs/plugin-vue": "^3.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "^2.0.0",
|
||||
"@vue/babel-plugin-jsx": "^1.0.0",
|
||||
"@vue/cli-plugin-eslint": "^5.0.0",
|
||||
"@vue/eslint-config-prettier": "^8.0.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.0",
|
||||
"@vue/test-utils": "^2.0.2",
|
||||
"@vue/vue3-jest": "28",
|
||||
"@vueuse/core": "^8.3.1",
|
||||
"@webpack-cli/serve": "^1.3.1",
|
||||
"acorn": "^8.0.0",
|
||||
"ali-oss": "^6.16.0",
|
||||
"autoprefixer": "^10.2.0",
|
||||
"axios": "^0.22.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-jest": "^28.1.2",
|
||||
"babel-loader": "^8.0.0",
|
||||
"babel-plugin-import": "^1.1.1",
|
||||
"babel-plugin-inline-import-data-uri": "^1.0.1",
|
||||
"babel-plugin-istanbul": "^6.0.0",
|
||||
"babel-plugin-transform-require-context": "^0.1.1",
|
||||
"case-sensitive-paths-webpack-plugin": "^2.1.2",
|
||||
"chalk": "^4.1.1",
|
||||
"cheerio": "^1.0.0-rc.2",
|
||||
"codecov": "^3.0.0",
|
||||
"codesandbox": "^2.2.3",
|
||||
"colorful": "^2.1.0",
|
||||
"commander": "^6.1.0",
|
||||
"compare-versions": "^3.3.0",
|
||||
"cross-env": "^7.0.0",
|
||||
"css-loader": "^5.0.0",
|
||||
"css-minimizer-webpack-plugin": "^3.0.0",
|
||||
"cz-git": "^1.3.8",
|
||||
"date-fns": "^2.24.0",
|
||||
"diacritics": "^1.3.0",
|
||||
"docsearch.js": "^2.6.3",
|
||||
"duplicate-package-checker-webpack-plugin": "^3.0.0",
|
||||
"enquire-js": "^0.2.1",
|
||||
"esbuild": "~0.12.29",
|
||||
"esbuild-loader": "^3.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"eslint": "^8.3.0",
|
||||
"eslint-config-prettier": "^8.0.0",
|
||||
"eslint-plugin-html": "^6.0.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"eslint-plugin-jest": "^26.0.0",
|
||||
"eslint-plugin-markdown": "^2.0.0",
|
||||
"eslint-plugin-no-explicit-type-exports": "^0.12.0",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
"eslint-plugin-vue": "^9.17.0",
|
||||
"fast-glob": "^3.2.7",
|
||||
"fetch-jsonp": "^1.1.3",
|
||||
"fs-extra": "^10.0.0",
|
||||
"glob": "^7.1.2",
|
||||
"globby": "^11.1.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
"gulp": "^4.0.1",
|
||||
"gulp-babel": "^8.0.0",
|
||||
"gulp-strip-code": "^0.1.4",
|
||||
"gulp-typescript": "^6.0.0-alpha.1",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"husky": "^6.0.0",
|
||||
"ignore-emit-webpack-plugin": "^2.0.6",
|
||||
"is-windows": "^1.0.2",
|
||||
"jest": "^28.1.2",
|
||||
"jest-environment-jsdom": "^28.0.0",
|
||||
"jest-environment-node": "^28.0.2",
|
||||
"jest-serializer-vue": "^2.0.0",
|
||||
"jest-transform-stub": "^2.0.0",
|
||||
"js-base64": "^3.0.0",
|
||||
"json-templater": "^1.2.0",
|
||||
"jsonp": "^0.2.1",
|
||||
"less": "^4.0.0",
|
||||
"less-loader": "^10.0.0",
|
||||
"less-plugin-npm-import": "^2.1.0",
|
||||
"less-vars-to-js": "^1.3.0",
|
||||
"lint-staged": "^11.0.0",
|
||||
"majo": "^0.10.1",
|
||||
"markdown-it": "^8.4.2",
|
||||
"markdown-it-anchor": "^8.0.4",
|
||||
"markdown-it-container": "^3.0.0",
|
||||
"markdown-it-emoji": "^2.0.0",
|
||||
"markdown-it-table-of-contents": "^0.5.2",
|
||||
"marked": "0.3.18",
|
||||
"merge2": "^1.2.1",
|
||||
"mini-css-extract-plugin": "^2.4.5",
|
||||
"minimist": "^1.2.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mockdate": "^2.0.2",
|
||||
"moment": "^2.29.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"postcss": "^8.2.12",
|
||||
"postcss-loader": "^6.0.0",
|
||||
"prettier": "^2.2.0",
|
||||
"pretty-quick": "^3.0.0",
|
||||
"prismjs": "^1.23.0",
|
||||
"progress": "^2.0.3",
|
||||
"raw-loader": "^4.0.2",
|
||||
"remark-frontmatter": "^2.0.0",
|
||||
"remark-parse": "^8.0.0",
|
||||
"remark-stringify": "^8.0.0",
|
||||
"remark-yaml-config": "^4.1.0",
|
||||
"remove-files-webpack-plugin": "^1.5.0",
|
||||
"reqwest": "^2.0.5",
|
||||
"rimraf": "^3.0.0",
|
||||
"rucksack-css": "^1.0.2",
|
||||
"selenium-server": "^3.0.1",
|
||||
"semver": "^7.0.0",
|
||||
"slash": "^3.0.0",
|
||||
"string-replace-loader": "^3.1.0",
|
||||
"style-loader": "^3.0.0",
|
||||
"stylelint": "^14.0.0",
|
||||
"stylelint-config-prettier": "^9.0.0",
|
||||
"stylelint-config-rational-order": "^0.1.2",
|
||||
"stylelint-config-standard": "^25.0.0",
|
||||
"stylelint-declaration-block-no-ignored-properties": "^2.1.0",
|
||||
"stylelint-order": "^5.0.0",
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"through2": "^3.0.0",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"ts-jest": "^28.0.5",
|
||||
"ts-loader": "^9.1.0",
|
||||
"tsx": "^4.0.0",
|
||||
"typedoc": "^0.23.25",
|
||||
"typescript": "~4.9.3",
|
||||
"umi-request": "^1.3.5",
|
||||
"unified": "9.2.2",
|
||||
"url-loader": "^3.0.0",
|
||||
"vanilla-jsoneditor": "^0.15.1",
|
||||
"vite": "^3.0.0",
|
||||
"vue": "^3.2.0",
|
||||
"vue-clipboard2": "0.3.3",
|
||||
"vue-drag-resize": "^2.0.3",
|
||||
"vue-eslint-parser": "^9.3.1",
|
||||
"vue-i18n": "^9.1.7",
|
||||
"vue-infinite-scroll": "^2.0.2",
|
||||
"vue-loader": "^17.0.0",
|
||||
"vue-request": "^2.0.4",
|
||||
"vue-router": "^4.0.0",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
"vue-tsc": "^1.0.6",
|
||||
"vuex": "^4.0.0",
|
||||
"webpack": "^5.0.0",
|
||||
"webpack-bundle-analyzer": "^4.4.2",
|
||||
"webpack-cli": "^4.6.0",
|
||||
"webpack-dev-server": "^4.0.0",
|
||||
"webpack-merge": "^5.0.0",
|
||||
"webpackbar": "^5.0.2",
|
||||
"xhr-mock": "^2.5.1"
|
||||
"@ant-design-vue/eslint-config": "*",
|
||||
"@ant-design-vue/prettier-config": "*",
|
||||
"@ant-design-vue/typescript-config": "*",
|
||||
"@types/node": "^20.0.0",
|
||||
"eslint": "^8.56.0",
|
||||
"prettier": "^3.3.3",
|
||||
"esbuild": "^0.25.8",
|
||||
"turbo": "^2.4.4",
|
||||
"typescript": "^5.8.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
"@ant-design/icons-vue": "^7.0.0",
|
||||
"@babel/runtime": "^7.10.5",
|
||||
"@ctrl/tinycolor": "^3.5.0",
|
||||
"@emotion/hash": "^0.9.0",
|
||||
"@emotion/unitless": "^0.8.0",
|
||||
"@simonwep/pickr": "~1.8.0",
|
||||
"array-tree-filter": "^2.1.0",
|
||||
"async-validator": "^4.0.0",
|
||||
"csstype": "^3.1.3",
|
||||
"dayjs": "^1.10.5",
|
||||
"dom-align": "^1.12.1",
|
||||
"dom-scroll-into-view": "^2.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.15",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"scroll-into-view-if-needed": "^2.2.25",
|
||||
"shallow-equal": "^1.0.0",
|
||||
"stylis": "^4.1.3",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
"vue-types": "^3.0.0",
|
||||
"warning": "^4.0.0"
|
||||
},
|
||||
"sideEffects": [
|
||||
"site/*",
|
||||
"*.vue",
|
||||
"*.md",
|
||||
"dist/*",
|
||||
"*.css"
|
||||
],
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "node_modules/cz-git",
|
||||
"czConfig": "./scripts/commitizen.js"
|
||||
}
|
||||
},
|
||||
"web-types": "vetur/web-types.json"
|
||||
"packageManager": "npm@10.8.2",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import { Linter } from 'eslint'
|
||||
|
||||
declare const e: Linter.Config[]
|
||||
|
||||
export default e
|
|
@ -0,0 +1,21 @@
|
|||
// @ts-check
|
||||
|
||||
/**
|
||||
* @type {Pick<import('eslint').Linter.Config, 'rules'>}
|
||||
*/
|
||||
export default {
|
||||
rules: {
|
||||
'no-redeclare': 'off',
|
||||
'@typescript-eslint/no-namespace': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{
|
||||
vars: 'all',
|
||||
args: 'after-used',
|
||||
ignoreRestSiblings: true,
|
||||
argsIgnorePattern: '^_',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// @ts-check
|
||||
|
||||
/**
|
||||
* @type {Pick<import('eslint').Linter.Config, 'ignores'>}
|
||||
*/
|
||||
export default {
|
||||
ignores: [
|
||||
'**/node_modules/',
|
||||
'**/dist/',
|
||||
'**/public/',
|
||||
'**/assets/',
|
||||
'**/*.js',
|
||||
'**/.turbo/',
|
||||
'**/.next/',
|
||||
'**/*.html',
|
||||
'.github/',
|
||||
'.vscode/',
|
||||
'**/.tsup/',
|
||||
],
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// @ts-check
|
||||
|
||||
import eslint from '@eslint/js'
|
||||
import prettier from 'eslint-config-prettier'
|
||||
import checkFile from 'eslint-plugin-check-file'
|
||||
import tseslint from 'typescript-eslint'
|
||||
import base from './eslint.config.base.js'
|
||||
import ignore from './eslint.config.ignore.js'
|
||||
|
||||
export default tseslint.config(
|
||||
ignore,
|
||||
eslint.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
{
|
||||
files: ['**/src/**/*.{ts}'],
|
||||
plugins: {
|
||||
'check-file': checkFile,
|
||||
},
|
||||
rules: {
|
||||
'check-file/filename-naming-convention': [
|
||||
'warn',
|
||||
{
|
||||
'**/*.ts': 'KEBAB_CASE',
|
||||
},
|
||||
{ ignoreMiddleExtensions: true },
|
||||
],
|
||||
},
|
||||
},
|
||||
base,
|
||||
prettier,
|
||||
)
|
|
@ -0,0 +1,77 @@
|
|||
// @ts-check
|
||||
|
||||
import eslint from '@eslint/js';
|
||||
import prettier from 'eslint-config-prettier';
|
||||
import checkFile from 'eslint-plugin-check-file';
|
||||
import pluginVue from 'eslint-plugin-vue';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import base from './eslint.config.base.js';
|
||||
import ignore from './eslint.config.ignore.js';
|
||||
|
||||
export default tseslint.config(
|
||||
ignore,
|
||||
{
|
||||
files: ['**/*.vue'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
parser: tseslint.parser,
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/src/**/*.{ts,vue}'],
|
||||
plugins: {
|
||||
'check-file': checkFile,
|
||||
},
|
||||
rules: {
|
||||
'check-file/filename-naming-convention': [
|
||||
'warn',
|
||||
{
|
||||
'**/*.vue': 'PASCAL_CASE',
|
||||
'**/*.ts': 'KEBAB_CASE',
|
||||
},
|
||||
{ ignoreMiddleExtensions: true },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.vue'],
|
||||
rules: {
|
||||
'check-file/no-index': 'warn',
|
||||
},
|
||||
},
|
||||
eslint.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
// @ts-ignore
|
||||
...pluginVue.configs['flat/recommended'],
|
||||
base,
|
||||
{
|
||||
rules: {
|
||||
'vue/require-default-prop': 'off',
|
||||
'vue/no-mutating-props': 'off',
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'vue/no-v-html': 'off',
|
||||
semi: ['error', 'always'],
|
||||
quotes: [
|
||||
2,
|
||||
'single',
|
||||
{
|
||||
avoidEscape: true,
|
||||
allowTemplateLiterals: true,
|
||||
},
|
||||
],
|
||||
'vue/require-prop-types': 0,
|
||||
'vue/v-on-event-hyphenation': 0,
|
||||
'import/no-unresolved': [2, { ignore: ['^@ant-design-vue/table'] }],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/ban-types': 0,
|
||||
'@typescript-eslint/explicit-module-boundary-types': 0,
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
},
|
||||
},
|
||||
prettier,
|
||||
);
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "@ant-design-vue/eslint-config",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./typescript": {
|
||||
"import": "./eslint.config.typescript.js",
|
||||
"types": "./config.d.ts"
|
||||
},
|
||||
"./vue": {
|
||||
"import": "./eslint.config.vue.js",
|
||||
"types": "./config.d.ts"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^8.56.0",
|
||||
"@types/eslint__js": "^8.42.3",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-check-file": "^2.8.0",
|
||||
"eslint-plugin-vue": "^9.27.0",
|
||||
"typescript": "^5.8.2",
|
||||
"typescript-eslint": "^7.17.0",
|
||||
"globby": "^14.1.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import { Config } from 'prettier'
|
||||
|
||||
declare const e: Config
|
||||
|
||||
export default e
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "@ant-design-vue/prettier-config",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./prettier.config.base.js",
|
||||
"types": "./config.d.ts"
|
||||
},
|
||||
"./tailwind": {
|
||||
"import": "./prettier.config.tailwind.js",
|
||||
"types": "./config.d.ts"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prettier-plugin-tailwindcss": "*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// @ts-check
|
||||
|
||||
/**
|
||||
* @type {import('prettier').Config}
|
||||
*/
|
||||
export default {
|
||||
semi: false,
|
||||
tabWidth: 2,
|
||||
singleQuote: true,
|
||||
printWidth: 100,
|
||||
trailingComma: 'all',
|
||||
proseWrap: 'never',
|
||||
arrowParens: 'avoid',
|
||||
htmlWhitespaceSensitivity: 'ignore',
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// @ts-check
|
||||
|
||||
import base from './prettier.config.base.js'
|
||||
|
||||
/**
|
||||
* @type {import('prettier').Config}
|
||||
*/
|
||||
export default {
|
||||
...base,
|
||||
plugins: ['prettier-plugin-tailwindcss'],
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "@ant-design-vue/tailwind-config",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./tailwind.css"
|
||||
},
|
||||
"./themes/*": {
|
||||
"default": "./themes/*.css"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"tailwindcss": "^4.0.9",
|
||||
"@tailwindcss/typography": "^0.5.16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": "^4",
|
||||
"@tailwindcss/typography": "^0.5.16"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
@import 'tailwindcss' source(none);
|
||||
@import './themes/light.css';
|
||||
@plugin '@tailwindcss/typography';
|
||||
|
||||
@utility text-tint-* {
|
||||
color: color-mix(in srgb, --value(--color- *, [ *]), white calc(--modifier(integer) * 1%));
|
||||
}
|
||||
|
||||
@utility text-shade-* {
|
||||
color: color-mix(in srgb, --value(--color- *, [ *]), black calc(--modifier(integer) * 1%));
|
||||
}
|
||||
|
||||
@utility bg-tint-* {
|
||||
background-color: color-mix(
|
||||
in srgb,
|
||||
--value(--color- *, [ *]),
|
||||
white calc(--modifier(integer) * 1%)
|
||||
);
|
||||
}
|
||||
|
||||
@utility bg-shade-* {
|
||||
background-color: color-mix(
|
||||
in srgb,
|
||||
--value(--color- *, [ *]),
|
||||
black calc(--modifier(integer) * 1%)
|
||||
);
|
||||
}
|
||||
|
||||
@utility border-tint-* {
|
||||
border-color: color-mix(in srgb, --value(--color- *, [ *]), white calc(--modifier(integer) * 1%));
|
||||
}
|
||||
|
||||
@utility border-shade-* {
|
||||
border-color: color-mix(in srgb, --value(--color- *, [ *]), black calc(--modifier(integer) * 1%));
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
@theme {
|
||||
--color-base-100: #ffffff;
|
||||
--color-base-200: #f7f7f7;
|
||||
--color-base-300: #ededed;
|
||||
--color-base-content: #222222;
|
||||
--color-primary: #151415;
|
||||
--color-primary-content: #ffffff;
|
||||
--color-secondary: #0d58fc;
|
||||
--color-secondary-content: #ffffff;
|
||||
--color-accent: #0289ff;
|
||||
--color-accent-content: #ffffff;
|
||||
--color-neutral: #666666;
|
||||
--color-neutral-content: #ffffff;
|
||||
--color-info: #0d58fc;
|
||||
--color-info-content: #ffffff;
|
||||
--color-success: #00c573;
|
||||
--color-success-content: #ffffff;
|
||||
--color-warning: #ff9900;
|
||||
--color-warning-content: #ffffff;
|
||||
--color-error: #ff3333;
|
||||
--color-error-content: #ffffff;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "@ant-design-vue/typescript-config",
|
||||
"version": "0.0.0",
|
||||
"private": true
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"allowImportingTsExtensions": true,
|
||||
"allowJs": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": false,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"lib": ["DOM", "DOM.Iterable", "ES2020"],
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"moduleResolution": "bundler",
|
||||
"noEmit": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"target": "ES2020",
|
||||
"types": ["vite/client"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "./tsconfig.vite.json",
|
||||
"compilerOptions": {
|
||||
"types": ["vite/client"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import { GetUserConfig } from './index.d'
|
||||
|
||||
declare const e: GetUserConfig
|
||||
|
||||
export default e
|
|
@ -0,0 +1,8 @@
|
|||
import { UserConfig, UserConfigFnObject } from 'vite'
|
||||
|
||||
export type GetUserConfig = (dirname: string) => UserConfig | UserConfigFnObject
|
||||
|
||||
export declare function extendsConfig(
|
||||
base: UserConfig | UserConfigFnObject,
|
||||
overwrite: UserConfig | UserConfigFnObject,
|
||||
): UserConfigFnObject
|
|
@ -0,0 +1,14 @@
|
|||
// @ts-check
|
||||
|
||||
import { mergeConfig } from 'vite'
|
||||
|
||||
/**
|
||||
* @type {typeof import('./index.d.ts').extendsConfig}
|
||||
*/
|
||||
export function extendsConfig(base, overwrite) {
|
||||
return env =>
|
||||
mergeConfig(
|
||||
typeof base === 'function' ? base(env) : base,
|
||||
typeof overwrite === 'function' ? overwrite(env) : overwrite,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "@ant-design-vue/vite-config",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./index.js",
|
||||
"types": "./index.d.ts"
|
||||
},
|
||||
"./typescript": {
|
||||
"import": "./vite.config.typescript.js",
|
||||
"types": "./config.d.ts"
|
||||
},
|
||||
"./vue": {
|
||||
"import": "./vite.config.vue.js",
|
||||
"types": "./config.d.ts"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@vitejs/plugin-vue": "^5.1.3",
|
||||
"vite": "^5.3.5",
|
||||
"vite-plugin-dts": "^4.5.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vitejs/plugin-vue": "*",
|
||||
"typescript": "*",
|
||||
"vite": "5",
|
||||
"vite-plugin-dts": "*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// @ts-nocheck
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { defineConfig } from 'vite';
|
||||
import dts from 'vite-plugin-dts';
|
||||
|
||||
/**
|
||||
* @type {import('./index.d.ts').GetUserConfig}
|
||||
*/
|
||||
export default dirname =>
|
||||
defineConfig(({ mode }) => {
|
||||
const pkg = JSON.parse(readFileSync(resolve(dirname, './package.json'), 'utf-8'));
|
||||
const isDev = mode === 'development';
|
||||
return {
|
||||
plugins: [
|
||||
dts({
|
||||
outDir: 'dist',
|
||||
compilerOptions: { declarationMap: isDev },
|
||||
include: ['src/**/*.ts', 'src/**/*.vue', 'src/**/*.d.ts'],
|
||||
insertTypesEntry: true,
|
||||
skipDiagnostics: false,
|
||||
}),
|
||||
],
|
||||
build: {
|
||||
cssCodeSplit: true,
|
||||
lib: {
|
||||
entry: {
|
||||
lib: resolve(dirname, 'src/index.ts'),
|
||||
},
|
||||
lib: {
|
||||
entry: {
|
||||
lib: resolve(dirname, 'src/index.ts'),
|
||||
},
|
||||
formats: ['es', 'cjs'],
|
||||
fileName: (format, entryName) => `${entryName}.${format === 'es' ? 'mjs' : 'cjs'}`,
|
||||
},
|
||||
},
|
||||
rollupOptions: {
|
||||
external: isDev
|
||||
? id => {
|
||||
if (pkg.peerDependencies && id in pkg.peerDependencies) {
|
||||
return true;
|
||||
}
|
||||
if (/^@(ant-design-vue)\//.test(id) || id === 'ant-design-vue') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
: pkg.peerDependencies && Object.keys(pkg.peerDependencies),
|
||||
},
|
||||
sourcemap: isDev ? 'inline' : undefined,
|
||||
minify: !isDev,
|
||||
emptyOutDir: !isDev,
|
||||
watch: process.argv.includes('--watch')
|
||||
? {
|
||||
buildDelay: 300,
|
||||
}
|
||||
: null,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve(dirname, './src'),
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
// @ts-check
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import { extendsConfig } from './index.js'
|
||||
import lib from './vite.config.lib.js'
|
||||
|
||||
/**
|
||||
* @type {import('./index.d.ts').GetUserConfig}
|
||||
*/
|
||||
export default dirname =>
|
||||
extendsConfig(
|
||||
lib(dirname),
|
||||
defineConfig({
|
||||
plugins: [],
|
||||
}),
|
||||
)
|
|
@ -0,0 +1,28 @@
|
|||
import vue from '@vitejs/plugin-vue'
|
||||
import { defineConfig } from 'vite'
|
||||
import { extendsConfig } from './index.js'
|
||||
import lib from './vite.config.lib.js'
|
||||
|
||||
/**
|
||||
* @type {import('./index.d.ts').GetUserConfig}
|
||||
*/
|
||||
export default dirname =>
|
||||
extendsConfig(
|
||||
lib(dirname),
|
||||
defineConfig(({ mode }) => {
|
||||
return {
|
||||
plugins: [vue()],
|
||||
build: {
|
||||
cssCodeSplit: true,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
exports: 'named',
|
||||
globals: {
|
||||
vue: 'Vue',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}),
|
||||
)
|
|
@ -0,0 +1,4 @@
|
|||
// @ts-check
|
||||
|
||||
export { default } from '@ant-design-vue/eslint-config/vue';
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
"name": "ant-design-vue",
|
||||
"version": "5.0.0-alpha.1",
|
||||
"title": "Ant Design Vue",
|
||||
"description": "An enterprise-class UI design language and Vue-based implementation",
|
||||
"keywords": [
|
||||
"vue",
|
||||
"vue3",
|
||||
"ant",
|
||||
"design",
|
||||
"antd",
|
||||
"vueComponent",
|
||||
"component",
|
||||
"components",
|
||||
"ui",
|
||||
"framework",
|
||||
"frontend"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"build:dev": "vite build --mode development",
|
||||
"dev": "vite build --watch --mode development",
|
||||
"lint": "eslint . --fix",
|
||||
"tsc": "tsc --noEmit",
|
||||
"tsg": "tsc --declaration --declarationMap --emitDeclarationOnly --noEmit false --outDir dist/types"
|
||||
},
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.esm.js",
|
||||
"require": "./dist/index.umd.js"
|
||||
},
|
||||
"./style.css": {
|
||||
"import": "./dist/index.css",
|
||||
"require": "./dist/index.css"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ant-design-vue/core.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/ant-design-vue/table/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.umd.js",
|
||||
"module": "./dist/index.esm.js",
|
||||
"types": "./dist/src/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"src/style",
|
||||
"typings"
|
||||
],
|
||||
"sideEffects": [
|
||||
"dist/*",
|
||||
"*.less"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"vue": "^3.2.34"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^7.0.0",
|
||||
"@ant-design/icons-vue": "^6.0.1",
|
||||
"@floating-ui/dom": "^1.6.13",
|
||||
"@floating-ui/vue": "^1.1.6",
|
||||
"lodash-es": "^4.17.21",
|
||||
"resize-observer-polyfill": "^1.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ant-design-vue/eslint-config": "*",
|
||||
"@ant-design-vue/prettier-config": "*",
|
||||
"@ant-design-vue/tailwind-config": "*",
|
||||
"@ant-design-vue/typescript-config": "*",
|
||||
"@ant-design-vue/vite-config": "*",
|
||||
"@tailwindcss/vite": "^4.1.3",
|
||||
"@vitejs/plugin-vue": "^5.1.3",
|
||||
"@vueuse/core": "^12.0.0",
|
||||
"@types/node": "^20.19.7",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"tailwindcss": "^4.0.14",
|
||||
"typescript": "^5.8.2",
|
||||
"vite": "^5.3.5",
|
||||
"vite-plugin-dts": "^4.5.4",
|
||||
"vite-svg-loader": "^5.1.0",
|
||||
"vue": "^3.4.34",
|
||||
"vue-tsc": "^3.0.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
export { default } from "@ant-design-vue/prettier-config/tailwind";
|
|
@ -0,0 +1,24 @@
|
|||
import { App } from 'vue'
|
||||
|
||||
const components = {} as any
|
||||
export const install = function (app: App) {
|
||||
Object.keys(components).forEach(key => {
|
||||
const component = components[key]
|
||||
if (component.install) {
|
||||
app.use(component)
|
||||
}
|
||||
})
|
||||
app.config.globalProperties.$message = components.message
|
||||
app.config.globalProperties.$notification = components.notification
|
||||
app.config.globalProperties.$info = components.Modal.info
|
||||
app.config.globalProperties.$success = components.Modal.success
|
||||
app.config.globalProperties.$error = components.Modal.error
|
||||
app.config.globalProperties.$warning = components.Modal.warning
|
||||
app.config.globalProperties.$confirm = components.Modal.confirm
|
||||
app.config.globalProperties.$destroyAll = components.Modal.destroyAll
|
||||
return app
|
||||
}
|
||||
|
||||
export default {
|
||||
install,
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@ant-design-vue/typescript-config/tsconfig.vue.json",
|
||||
"include": ["src/**/*.ts", "src/**/*.vue", "src/**/*.d.ts"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }],
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"~/*": ["./assets/*"]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": "@ant-design-vue/typescript-config/tsconfig.node.json",
|
||||
"include": ["vite.config.*"]
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
/* eslint-disable @typescript-eslint/consistent-type-imports */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {}
|
||||
}
|
||||
export {}
|
|
@ -0,0 +1,23 @@
|
|||
import { extendsConfig } from '@ant-design-vue/vite-config';
|
||||
import vue from '@ant-design-vue/vite-config/vue';
|
||||
import { resolve } from 'node:path';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
|
||||
export default extendsConfig(vue(__dirname), {
|
||||
resolve: {
|
||||
alias: {
|
||||
'~': resolve(__dirname, './assets'),
|
||||
},
|
||||
},
|
||||
plugins: [tailwindcss()],
|
||||
build: {
|
||||
lib: {
|
||||
name: 'antd',
|
||||
entry: {
|
||||
lib: resolve(__dirname, 'src/index.ts'),
|
||||
},
|
||||
formats: ['umd'],
|
||||
fileName: (format, entryName) => `${entryName}.${format}.js`,
|
||||
},
|
||||
},
|
||||
})
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
plugins: [require('autoprefixer')],
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
export { default } from '@ant-design-vue/prettier-config'
|
|
@ -1,102 +0,0 @@
|
|||
const TypeDoc = require('typedoc');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
const getTokenList = (list, source) =>
|
||||
list
|
||||
.filter(
|
||||
item =>
|
||||
!item.comment?.blockTags.some(tag => tag.tag === '@internal' || tag.tag === '@private'),
|
||||
)
|
||||
.map(item => ({
|
||||
source,
|
||||
token: item.name,
|
||||
type: item.type.toString(),
|
||||
desc:
|
||||
item.comment?.blockTags
|
||||
?.find(tag => tag.tag === '@desc')
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '',
|
||||
descEn:
|
||||
item.comment?.blockTags
|
||||
?.find(tag => tag.tag === '@descEN')
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '',
|
||||
name:
|
||||
item.comment?.blockTags
|
||||
?.find(tag => tag.tag === '@nameZH')
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '',
|
||||
nameEn:
|
||||
item.comment?.blockTags
|
||||
?.find(tag => tag.tag === '@nameEN')
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '',
|
||||
}));
|
||||
|
||||
function main() {
|
||||
const app = new TypeDoc.Application();
|
||||
|
||||
// If you want TypeDoc to load tsconfig.json / typedoc.json files
|
||||
app.options.addReader(new TypeDoc.TSConfigReader());
|
||||
app.options.addReader(new TypeDoc.TypeDocReader());
|
||||
|
||||
app.bootstrap({
|
||||
// typedoc options here
|
||||
entryPoints: ['components/theme/interface/index.ts'],
|
||||
skipErrorChecking: true,
|
||||
});
|
||||
|
||||
const project = app.convert();
|
||||
|
||||
if (project) {
|
||||
// Project may not have converted correctly
|
||||
const output = 'components/version/token-meta.json';
|
||||
const tokenMeta = {};
|
||||
let presetColors = [];
|
||||
project.children.forEach(type => {
|
||||
if (type.name === 'SeedToken') {
|
||||
tokenMeta.seed = getTokenList(type.children, 'seed');
|
||||
} else if (type.name === 'MapToken') {
|
||||
tokenMeta.map = getTokenList(type.children, 'map');
|
||||
} else if (type.name === 'AliasToken') {
|
||||
tokenMeta.alias = getTokenList(type.children, 'alias');
|
||||
} else if (type.name === 'PresetColors') {
|
||||
presetColors = type.type.target.elements.map(item => item.value);
|
||||
}
|
||||
});
|
||||
|
||||
// Exclude preset colors
|
||||
tokenMeta.seed = tokenMeta.seed.filter(
|
||||
item => !presetColors.some(color => item.token.startsWith(color)),
|
||||
);
|
||||
tokenMeta.map = tokenMeta.map.filter(
|
||||
item => !presetColors.some(color => item.token.startsWith(color)),
|
||||
);
|
||||
tokenMeta.alias = tokenMeta.alias.filter(
|
||||
item => !presetColors.some(color => item.token.startsWith(color)),
|
||||
);
|
||||
|
||||
tokenMeta.alias = tokenMeta.alias.filter(
|
||||
item => !tokenMeta.map.some(mapItem => mapItem.token === item.token),
|
||||
);
|
||||
tokenMeta.map = tokenMeta.map.filter(
|
||||
item => !tokenMeta.seed.some(seedItem => seedItem.token === item.token),
|
||||
);
|
||||
|
||||
const finalMeta = Object.entries(tokenMeta).reduce((acc, [key, value]) => {
|
||||
value.forEach(item => {
|
||||
acc[item.token] = {
|
||||
name: item.name,
|
||||
nameEn: item.nameEn,
|
||||
desc: item.desc,
|
||||
descEn: item.descEn,
|
||||
type: item.type,
|
||||
source: key,
|
||||
};
|
||||
});
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
fs.writeJsonSync(output, finalMeta, 'utf8');
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`✅ Token Meta has been written to ${output}`);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
102
site/404.html
102
site/404.html
|
@ -1,102 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<meta
|
||||
name="description"
|
||||
content="An enterprise-class UI components based on Ant Design and Vue"
|
||||
/>
|
||||
<title>Ant Design Vue</title>
|
||||
<link rel="icon" type="image/x-icon" href="//aliyuncdn.antdv.com/favicon.ico" />
|
||||
<style id="nprogress-style">
|
||||
#page-404 {
|
||||
background-image: url('https://os.alipayobjects.com/rmsportal/NOAjOBbnYCrNzrW.jpg');
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
background-position: center;
|
||||
background-size: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
section {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 55%;
|
||||
margin: -103px 0 0 -120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #1890ff;
|
||||
font-size: 120px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #314659;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
if (location.host === 'ant-design-vue.gitee.io' || location.host === 'vue.ant.design') {
|
||||
location.replace(location.href.replace(location.host, 'www.antdv.com'));
|
||||
}
|
||||
var _hmt = _hmt || [];
|
||||
var srcMap = {
|
||||
'ant-design-vue.gitee.io': 'https://hm.baidu.com/hm.js?1e30265f06f76fabfcdb7ed272017441',
|
||||
'www.antdv.com': 'https://hm.baidu.com/hm.js?4ad38a0c8f0960d731b654425317da22',
|
||||
};
|
||||
var src =
|
||||
srcMap[location.host] || 'https://hm.baidu.com/hm.js?4ad38a0c8f0960d731b654425317da22';
|
||||
(function () {
|
||||
var hm = document.createElement('script');
|
||||
hm.src = src;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div id="page-404" data-reactroot="">
|
||||
<section>
|
||||
<h1>404</h1>
|
||||
<p>
|
||||
你要找的页面不存在
|
||||
<a href="/">返回首页</a>
|
||||
</p>
|
||||
</section>
|
||||
<style>
|
||||
#app {
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-151755889-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-151755889-1');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,17 +0,0 @@
|
|||
<template>
|
||||
<a-button type="primary">Tooltip will show when mouse enter.</a-button>
|
||||
<a-config-provider
|
||||
:theme="{
|
||||
cssVar: {
|
||||
key: 'test',
|
||||
},
|
||||
components: {
|
||||
Button: {
|
||||
colorPrimary: '#123456',
|
||||
},
|
||||
},
|
||||
}"
|
||||
>
|
||||
<a-button type="primary">Tooltip will show when mouse enter.</a-button>
|
||||
</a-config-provider>
|
||||
</template>
|
|
@ -1,10 +0,0 @@
|
|||
// debugger tsx
|
||||
// import Demo from '../../components/select/demo/field-names.vue';
|
||||
import Demo from './demo/demo.vue';
|
||||
|
||||
export default {
|
||||
setup() {},
|
||||
render() {
|
||||
return <Demo />;
|
||||
},
|
||||
};
|
|
@ -1,81 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<meta
|
||||
name="description"
|
||||
content="An enterprise-class UI components based on Ant Design and Vue"
|
||||
/>
|
||||
<title>Ant Design Vue — An enterprise-class UI components based on Ant Design and Vue.js</title>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="ant design vue,ant-design-vue,ant-design-vue admin,ant design pro,vue ant design,vue ant design pro,vue ant design admin,ant design vue官网,ant design vue中文文档,ant design vue文档"
|
||||
/>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="//aliyuncdn.antdv.com/favicon.ico" />
|
||||
<style id="nprogress-style">
|
||||
#nprogress {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
if (location.host === 'ant-design-vue.gitee.io' || location.host === 'vue.ant.design') {
|
||||
location.replace(location.href.replace(location.host, 'www.antdv.com'));
|
||||
}
|
||||
var _hmt = _hmt || [];
|
||||
var srcMap = {
|
||||
'ant-design-vue.gitee.io': 'https://hm.baidu.com/hm.js?1e30265f06f76fabfcdb7ed272017441',
|
||||
'vue.ant.design': 'https://hm.baidu.com/hm.js?f0ba868f114e674b816b4880f7525811',
|
||||
'www.antdv.com': 'https://hm.baidu.com/hm.js?4ad38a0c8f0960d731b654425317da22',
|
||||
};
|
||||
var src =
|
||||
srcMap[location.host] || 'https://hm.baidu.com/hm.js?4ad38a0c8f0960d731b654425317da22';
|
||||
(function () {
|
||||
var hm = document.createElement('script');
|
||||
hm.src = src;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="https://aliyuncdn.antdv.com/common/docsearch.min_2.6.3.js"></script>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-151755889-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-151755889-1');
|
||||
</script>
|
||||
<script type="text/javascript" src="https://cdn.wwads.cn/js/makemoney.js" async></script>
|
||||
<!-- <div
|
||||
class="surveybyantdv"
|
||||
data-sf-id="63ad5912f3e10066"
|
||||
data-sf-mode="popover"
|
||||
data-sf-button-color="#3a3939"
|
||||
data-sf-text-color="#ffffff"
|
||||
data-sf-button-radius="50"
|
||||
data-sf-button-icon="form-outlined"
|
||||
data-sf-default-open="false"
|
||||
data-sf-allow-repeat-submit="true"
|
||||
data-sf-close-after-submit="false"
|
||||
data-sf-hide-after-submit="false"
|
||||
data-sf-delay-visible="false"
|
||||
data-sf-preload="true"
|
||||
data-sf-width="368px"
|
||||
data-sf-height="407px"
|
||||
></div>
|
||||
<script async src="https://aliyuncdn.antdv.com/form/static/embed/runtime.js"></script> -->
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB |
|
@ -1,40 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const globby = require('globby');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const matter = require('gray-matter');
|
||||
const { ESLint } = require('eslint');
|
||||
|
||||
(async () => {
|
||||
const paths = await globby('components/*/index.*.md');
|
||||
const components = {};
|
||||
|
||||
paths.forEach(path => {
|
||||
const content = fs.readFileSync(path).toString();
|
||||
const componentName = path.split('/')[1];
|
||||
|
||||
const { data } = matter(content);
|
||||
components[componentName] = { ...components[componentName], ...data };
|
||||
});
|
||||
const TEMPLATE = `
|
||||
export default [
|
||||
${Object.keys(components).map(
|
||||
component => `
|
||||
{
|
||||
path: '${component}:lang(-cn)?',
|
||||
meta: ${JSON.stringify(components[component])},
|
||||
component: () => import('../../../components/${component}/demo/index.vue'),
|
||||
}`,
|
||||
)}
|
||||
];`;
|
||||
|
||||
const engine = new ESLint({
|
||||
fix: true,
|
||||
useEslintrc: false,
|
||||
baseConfig: require(path.join(process.cwd(), '.eslintrc.js')),
|
||||
});
|
||||
|
||||
const report = await engine.lintText(TEMPLATE);
|
||||
|
||||
fs.writeFileSync('site/src/router/demoRoutes.js', report[0].output);
|
||||
})();
|
|
@ -1,59 +0,0 @@
|
|||
/* eslint-disable no-console */
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const OSS = require('ali-oss');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const accessKeyId = process.env.ALI_OSS_ACCESSKEY;
|
||||
const accessKeySecret = process.env.ALI_OSS_SECRETKEY;
|
||||
|
||||
const client = new OSS({
|
||||
bucket: '4x-antdv',
|
||||
cname: 'true',
|
||||
endpoint: '4x-antdv.oss-cn-beijing.aliyuncs.com',
|
||||
region: 'oss-cn-beijing',
|
||||
accessKeyId,
|
||||
accessKeySecret,
|
||||
});
|
||||
|
||||
const assetsPath = path.join(process.cwd(), 'site', 'dist', 'assets');
|
||||
|
||||
const put = (target, source) => {
|
||||
return new Promise((reslove, reject) => {
|
||||
client
|
||||
.put(target, source)
|
||||
.then(res => {
|
||||
if (res.res.status !== 200) {
|
||||
console.log(`${res.name} upload failed!`);
|
||||
reject();
|
||||
process.exit(500);
|
||||
} else {
|
||||
console.log(`${res.name} upload success!`);
|
||||
reslove();
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
if (err) {
|
||||
err && console.log(err);
|
||||
process.exit(500);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
async function upload() {
|
||||
try {
|
||||
const files = await fs.promises.readdir(assetsPath, {
|
||||
withFileTypes: true,
|
||||
});
|
||||
for (const file of files) {
|
||||
if (file.isFile()) {
|
||||
await put(`assets/${file.name}`, path.join(assetsPath, file.name));
|
||||
}
|
||||
}
|
||||
await put('index.html', path.join(process.cwd(), 'site', 'dist', 'index.html'));
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
upload();
|
148
site/src/App.vue
148
site/src/App.vue
|
@ -1,148 +0,0 @@
|
|||
<template>
|
||||
<a-style-provider :hash-priority="hashPriority">
|
||||
<a-config-provider :locale="locale" :theme="themeConfig">
|
||||
<SiteToken>
|
||||
<router-view />
|
||||
</SiteToken>
|
||||
</a-config-provider>
|
||||
</a-style-provider>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, provide, watch, ref } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import useMediaQuery from './hooks/useMediaQuery';
|
||||
import { GLOBAL_CONFIG } from './SymbolKey';
|
||||
import enUS from '../../components/locale/en_US';
|
||||
import zhCN from '../../components/locale/zh_CN';
|
||||
import dayjs from 'dayjs';
|
||||
import 'dayjs/locale/zh-cn';
|
||||
import { theme as antdTheme } from 'ant-design-vue';
|
||||
import type { ThemeConfig } from '../../components/config-provider/context';
|
||||
import SiteToken from './SiteToken.vue';
|
||||
function isZhCN(name: string) {
|
||||
return /-cn\/?$/.test(name);
|
||||
}
|
||||
export interface GlobalConfig {
|
||||
isMobile: Ref<boolean>;
|
||||
lang: Ref<'zh-CN' | 'en-US'>;
|
||||
isZhCN: Ref<boolean>;
|
||||
responsive: Ref<null | 'narrow' | 'crowded'>;
|
||||
blocked: Ref<boolean>;
|
||||
}
|
||||
export type ThemeName = '' | 'light' | 'dark' | 'compact';
|
||||
const getAlgorithm = (themes: ThemeName[] = []) =>
|
||||
themes
|
||||
.filter(theme => !!theme)
|
||||
.map(theme => {
|
||||
if (theme === 'dark') {
|
||||
return antdTheme.darkAlgorithm;
|
||||
}
|
||||
if (theme === 'compact') {
|
||||
return antdTheme.compactAlgorithm;
|
||||
}
|
||||
return antdTheme.defaultAlgorithm;
|
||||
});
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
SiteToken,
|
||||
},
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const i18n = useI18n();
|
||||
const colSize = useMediaQuery();
|
||||
const isMobile = computed(() => colSize.value === 'sm' || colSize.value === 'xs');
|
||||
const theme = ref<ThemeName>((localStorage.getItem('theme') as ThemeName) || 'light');
|
||||
const compactTheme = ref<ThemeName>((localStorage.getItem('compactTheme') as ThemeName) || '');
|
||||
const themeConfig = computed(() => {
|
||||
return {
|
||||
algorithm: getAlgorithm([...new Set([theme.value, compactTheme.value])]),
|
||||
cssVar: true,
|
||||
} as ThemeConfig;
|
||||
});
|
||||
const hashPriority = ref('low' as const);
|
||||
watch(hashPriority, () => {
|
||||
location.reload();
|
||||
});
|
||||
// useSiteToken();
|
||||
const responsive = computed(() => {
|
||||
if (colSize.value === 'xs') {
|
||||
return 'crowded';
|
||||
} else if (colSize.value === 'sm') {
|
||||
return 'narrow';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
const globalConfig: GlobalConfig = {
|
||||
isMobile,
|
||||
responsive,
|
||||
lang: computed<any>(() => i18n.locale.value),
|
||||
isZhCN: computed(() => i18n.locale.value === 'zh-CN'),
|
||||
blocked: ref(false),
|
||||
};
|
||||
const changeTheme = (t: ThemeName) => {
|
||||
theme.value = t;
|
||||
localStorage.setItem('theme', t);
|
||||
};
|
||||
|
||||
const changeCompactTheme = (t: ThemeName) => {
|
||||
compactTheme.value = t;
|
||||
localStorage.setItem('compactTheme', t);
|
||||
};
|
||||
|
||||
provide('themeMode', {
|
||||
theme,
|
||||
compactTheme,
|
||||
changeTheme,
|
||||
changeCompactTheme,
|
||||
});
|
||||
provide(GLOBAL_CONFIG, globalConfig);
|
||||
watch(
|
||||
() => route.path,
|
||||
val => {
|
||||
i18n.locale.value = isZhCN(val) ? 'zh-CN' : 'en-US';
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
watch(
|
||||
globalConfig.isZhCN,
|
||||
val => {
|
||||
if (val) {
|
||||
dayjs.locale(zhCN.locale);
|
||||
} else {
|
||||
dayjs.locale(enUS.locale);
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
const locale = computed(() => {
|
||||
return globalConfig.isZhCN.value ? zhCN : enUS;
|
||||
});
|
||||
setTimeout(() => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'adsbox';
|
||||
document.body.appendChild(div);
|
||||
globalConfig.blocked.value = 'none' === getComputedStyle(div).display;
|
||||
}, 300);
|
||||
watch(
|
||||
theme,
|
||||
() => {
|
||||
if (theme.value === 'dark') {
|
||||
document.getElementsByTagName('html')[0].setAttribute('data-doc-theme', 'dark');
|
||||
document.getElementsByTagName('body')[0].setAttribute('data-theme', 'dark');
|
||||
document.getElementsByTagName('html')[0].style.colorScheme = 'dark';
|
||||
} else {
|
||||
document.getElementsByTagName('html')[0].setAttribute('data-doc-theme', 'light');
|
||||
document.getElementsByTagName('body')[0].setAttribute('data-theme', 'light');
|
||||
document.getElementsByTagName('html')[0].style.colorScheme = 'light';
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
return { globalConfig, locale, themeConfig, hashPriority };
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -1,7 +0,0 @@
|
|||
<template>
|
||||
<slot></slot>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import useSiteToken from './hooks/useSiteToken';
|
||||
useSiteToken();
|
||||
</script>
|
|
@ -1 +0,0 @@
|
|||
export const GLOBAL_CONFIG = Symbol('globalConfig');
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 7.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 155 KiB |
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="128px" height="128px" viewBox="0 0 128 128" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Vue</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="69.644116%" y1="0%" x2="69.644116%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#29CDFF" offset="0%"></stop>
|
||||
<stop stop-color="#148EFF" offset="37.8600687%"></stop>
|
||||
<stop stop-color="#0A60FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="-19.8191553%" y1="-36.7931464%" x2="138.57919%" y2="157.637507%" id="linearGradient-2">
|
||||
<stop stop-color="#29CDFF" offset="0%"></stop>
|
||||
<stop stop-color="#0F78FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="68.1279872%" y1="-35.6905737%" x2="30.4400914%" y2="114.942679%" id="linearGradient-3">
|
||||
<stop stop-color="#FA8E7D" offset="0%"></stop>
|
||||
<stop stop-color="#F74A5C" offset="51.2635191%"></stop>
|
||||
<stop stop-color="#F51D2C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Vue" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Group" transform="translate(19.000000, 9.000000)">
|
||||
<path d="M89.96,90.48 C78.58,93.48 68.33,83.36 67.62,82.48 L46.6604487,62.2292258 C45.5023849,61.1103236 44.8426845,59.5728835 44.8296987,57.9626396 L44.5035564,17.5209948 C44.4948861,16.4458744 44.0537714,15.4195095 43.2796864,14.6733517 L29.6459999,1.53153737 C28.055475,-0.00160504005 25.5232423,0.0449126588 23.9900999,1.63543756 C23.2715121,2.38092066 22.87,3.37600834 22.87,4.41143746 L22.87,64.3864751 C22.87,67.0807891 23.9572233,69.6611067 25.885409,71.5429748 L63.6004615,108.352061 C65.9466323,110.641873 69.6963584,110.624605 72.0213403,108.313281" id="Path-Copy" fill="url(#linearGradient-1)" fill-rule="nonzero" transform="translate(56.415000, 54.831157) scale(-1, 1) translate(-56.415000, -54.831157) "></path>
|
||||
<path d="M68,90.1163122 C56.62,93.1163122 45.46,83.36 44.75,82.48 L23.7904487,62.2292258 C22.6323849,61.1103236 21.9726845,59.5728835 21.9596987,57.9626396 L21.6335564,17.5209948 C21.6248861,16.4458744 21.1837714,15.4195095 20.4096864,14.6733517 L6.7759999,1.53153737 C5.185475,-0.00160504005 2.65324232,0.0449126588 1.12009991,1.63543756 C0.401512125,2.38092066 3.90211878e-13,3.37600834 3.90798505e-13,4.41143746 L3.94351218e-13,64.3864751 C3.94681177e-13,67.0807891 1.08722326,69.6611067 3.01540903,71.5429748 L40.7807092,108.401101 C43.1069304,110.671444 46.8180151,110.676525 49.1504445,108.412561" id="Path" fill="url(#linearGradient-2)" fill-rule="nonzero"></path>
|
||||
<path d="M43.2983488,19.0991931 L27.5566079,3.88246244 C26.7624281,3.11476967 26.7409561,1.84862177 27.5086488,1.05444194 C27.8854826,0.664606611 28.4044438,0.444472651 28.9466386,0.444472651 L60.3925021,0.444472651 C61.4970716,0.444472651 62.3925021,1.33990315 62.3925021,2.44447265 C62.3925021,2.9858375 62.1730396,3.50407742 61.7842512,3.88079942 L46.0801285,19.0975301 C45.3051579,19.8484488 44.0742167,19.8491847 43.2983488,19.0991931 Z" id="Path" fill="url(#linearGradient-3)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.3 KiB |
|
@ -1,56 +0,0 @@
|
|||
import { defineComponent, toRefs, computed } from 'vue';
|
||||
import type { CSSProperties, PropType } from 'vue';
|
||||
import { TinyColor, type ColorInput } from '@ctrl/tinycolor';
|
||||
import useSiteToken from '../../hooks/useSiteToken';
|
||||
|
||||
const ColorChunk = defineComponent({
|
||||
props: {
|
||||
color: {
|
||||
type: String as PropType<ColorInput>,
|
||||
default: '#000',
|
||||
},
|
||||
},
|
||||
setup(props, { attrs, slots }) {
|
||||
const SiteToken = useSiteToken();
|
||||
|
||||
const token = computed(() => SiteToken.value.token);
|
||||
|
||||
const { color } = toRefs(props);
|
||||
|
||||
const dotColor = computed(() => {
|
||||
const _color = new TinyColor(color.value).toHex8String();
|
||||
return _color.endsWith('ff') ? _color.slice(0, -2) : _color;
|
||||
});
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<span
|
||||
{...attrs}
|
||||
style={{
|
||||
padding: '0.2em 0.4em',
|
||||
fontSize: '0.9em',
|
||||
background: token.value.siteMarkdownCodeBg,
|
||||
borderRadius: `${token.value.borderRadius}px`,
|
||||
fontFamily: 'monospace',
|
||||
...(attrs.style as CSSProperties),
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '6px',
|
||||
height: '6px',
|
||||
borderRadius: `${token.value.borderRadiusSM}px`,
|
||||
marginRight: '4px',
|
||||
border: `1px solid ${token.value.colorSplit}`,
|
||||
backgroundColor: dotColor.value,
|
||||
}}
|
||||
/>
|
||||
{slots.default ? slots.default() : dotColor.value}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default ColorChunk;
|
|
@ -1,205 +0,0 @@
|
|||
import { defineComponent, toRefs, computed } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
import { ConfigProvider, Table } from 'ant-design-vue';
|
||||
import { getDesignToken } from '../antdv-token-previewer';
|
||||
import tokenMeta from 'ant-design-vue/es/version/token-meta.json';
|
||||
import tokenData from 'ant-design-vue/es/version/token.json';
|
||||
import { useLocale } from '../../i18n';
|
||||
import useSiteToken from '../../hooks/useSiteToken';
|
||||
import { useColumns } from '../TokenTable';
|
||||
import ColorChunk from '../ColorChunk';
|
||||
|
||||
const defaultToken = getDesignToken();
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
token: 'Token 名称',
|
||||
description: '描述',
|
||||
type: '类型',
|
||||
value: '默认值',
|
||||
},
|
||||
en: {
|
||||
token: 'Token Name',
|
||||
description: 'Description',
|
||||
type: 'Type',
|
||||
value: 'Default Value',
|
||||
},
|
||||
};
|
||||
|
||||
interface SubTokenTableProps {
|
||||
defaultOpen?: boolean;
|
||||
title: string;
|
||||
tokens: string[];
|
||||
}
|
||||
|
||||
const SubTokenTable = defineComponent({
|
||||
props: {
|
||||
defaultOpen: {
|
||||
type: Boolean as PropType<SubTokenTableProps['defaultOpen']>,
|
||||
},
|
||||
title: {
|
||||
type: String as PropType<SubTokenTableProps['title']>,
|
||||
},
|
||||
tokens: {
|
||||
type: Array as PropType<SubTokenTableProps['tokens']>,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { defaultOpen, title, tokens } = toRefs(props);
|
||||
const [, lang] = useLocale(locales);
|
||||
const siteToken = useSiteToken();
|
||||
const token = computed(() => siteToken.value.token);
|
||||
const columns = useColumns();
|
||||
|
||||
return () => {
|
||||
if (!tokens.value.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = tokens.value
|
||||
.sort((token1, token2) => {
|
||||
const hasColor1 = token1.toLowerCase().includes('color');
|
||||
const hasColor2 = token2.toLowerCase().includes('color');
|
||||
|
||||
if (hasColor1 && !hasColor2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!hasColor1 && hasColor2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return token1 < token2 ? -1 : 1;
|
||||
})
|
||||
.map(name => {
|
||||
const meta = tokenMeta[name];
|
||||
|
||||
if (!meta) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
desc: lang.value === 'cn' ? meta.desc : meta.descEn,
|
||||
type: meta.type,
|
||||
value: (defaultToken as any)[name],
|
||||
};
|
||||
})
|
||||
.filter(info => info);
|
||||
|
||||
return (
|
||||
// Reuse `.markdown` style
|
||||
<details class="markdown" open={defaultOpen.value || process.env.NODE_ENV !== 'production'}>
|
||||
<summary>
|
||||
<h3 style={{ display: 'inline' }}>{title.value}</h3>
|
||||
</summary>
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
token: {
|
||||
borderRadius: 0,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Table
|
||||
size="middle"
|
||||
columns={columns}
|
||||
bordered
|
||||
dataSource={data}
|
||||
style={{ marginBottom: token.value.margin }}
|
||||
pagination={false}
|
||||
rowKey={record => record.name}
|
||||
v-slots={{
|
||||
bodyCell: ({ text, record, column }) => {
|
||||
if (column.key === 'type') {
|
||||
return (
|
||||
<span
|
||||
style={{
|
||||
margin: '0 1px',
|
||||
padding: '0.2em 0.4em',
|
||||
fontSize: '0.9em',
|
||||
background: `${token.value.siteMarkdownCodeBg}`,
|
||||
border: `1px solid ${token.value.colorSplit}`,
|
||||
borderRadius: '3px',
|
||||
fontFamily: 'monospace',
|
||||
}}
|
||||
>
|
||||
{record.type}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (column.key === 'value') {
|
||||
const isColor =
|
||||
typeof record.value === 'string' &&
|
||||
(record.value.startsWith('#') || record.value.startsWith('rgb'));
|
||||
if (isColor) {
|
||||
return <ColorChunk color={record.value}>{record.value}</ColorChunk>;
|
||||
}
|
||||
return (
|
||||
<span>
|
||||
{typeof record.value !== 'string'
|
||||
? JSON.stringify(record.value)
|
||||
: record.value}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return <span>{text} </span>;
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</ConfigProvider>
|
||||
</details>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export interface ComponentTokenTableProps {
|
||||
component: string;
|
||||
}
|
||||
|
||||
const ComponentTokenTable = defineComponent({
|
||||
props: {
|
||||
component: {
|
||||
type: String as PropType<ComponentTokenTableProps['component']>,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { component } = toRefs(props);
|
||||
|
||||
const mergedTokens = computed(() => {
|
||||
const globalTokenSet = new Set<string>();
|
||||
let componentTokens: Record<string, string> = {};
|
||||
|
||||
component.value.split(',').forEach(comp => {
|
||||
const { global: globalTokens = [], component: singleComponentTokens = [] } =
|
||||
tokenData[comp] || {};
|
||||
|
||||
globalTokens.forEach((token: string) => {
|
||||
globalTokenSet.add(token);
|
||||
});
|
||||
|
||||
componentTokens = {
|
||||
...componentTokens,
|
||||
...singleComponentTokens,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
mergedGlobalTokens: Array.from(globalTokenSet),
|
||||
mergedComponentTokens: componentTokens,
|
||||
};
|
||||
});
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<>
|
||||
{/* Component Token 先不展示 */}
|
||||
{/* <SubTokenTable title="Component Token" tokens={mergedComponentTokens} defaultOpen /> */}
|
||||
<SubTokenTable title="Global Token" tokens={mergedTokens.value.mergedGlobalTokens} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default ComponentTokenTable;
|
|
@ -1,4 +0,0 @@
|
|||
export const REPO_OWNER = 'VueComponent';
|
||||
export const REPO_NAME = 'ant-design-vue';
|
||||
export const REPO_PATH = `${REPO_OWNER}/${REPO_NAME}`;
|
||||
export const REPO_BRANCH = 'main';
|
|
@ -1,112 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watchEffect } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { REPO_PATH } from './constants';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
defineProps({
|
||||
isZn: Boolean,
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const contributors = ref([]);
|
||||
const lastCommitTime = ref(0);
|
||||
|
||||
const filterData = data => {
|
||||
const arr = [];
|
||||
data.forEach(item => {
|
||||
if (!!item.author?.login || !!item.author?.html_url || !!item.author?.avatar_url) {
|
||||
lastCommitTime.value = Math.max(lastCommitTime.value, +new Date(item.commit.author.date));
|
||||
|
||||
arr.push({
|
||||
login: item.author.login,
|
||||
url: item.author.html_url,
|
||||
avatar: item.author.avatar_url,
|
||||
});
|
||||
}
|
||||
});
|
||||
contributors.value = arr.reduce((acc, curr) => {
|
||||
if (!acc.find(item => item.login === curr.login)) {
|
||||
acc.push(curr);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
};
|
||||
const getContributors = async () => {
|
||||
const path = route.path;
|
||||
const parts = path.split('/');
|
||||
const name = parts[2];
|
||||
const componentName = name.includes('-') ? name.replace('-cn', '') : name;
|
||||
const url = `https://api.github.com/repos/${REPO_PATH}/commits?path=/components/${componentName}`;
|
||||
try {
|
||||
const req = await fetch(url);
|
||||
const res = await req.json();
|
||||
filterData(res);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
watchEffect(() => {
|
||||
getContributors();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="contributors.length > 0" class="contributors-list">
|
||||
<ul class="acss-1ppw8kl">
|
||||
<li v-for="item in contributors" :key="item.login">
|
||||
<a-tooltip :title="`${isZn ? '文档贡献者:' : 'Contributor: '}${item.login}`">
|
||||
<a :href="item.url" target="_blank">
|
||||
<a-avatar :src="item.avatar" size="small" />
|
||||
</a>
|
||||
</a-tooltip>
|
||||
</li>
|
||||
</ul>
|
||||
<span>
|
||||
{{ isZn ? '最后更新' : 'Last updated' }} : {{ dayjs(lastCommitTime).format('YYYY/MM/DD') }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.contributors-list {
|
||||
margin-top: 120px !important;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.contributors-list span {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.acss-1ppw8kl {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-flex-wrap: wrap;
|
||||
-webkit-flex-wrap: wrap;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
clear: both;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.acss-1ppw8kl li {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.acss-1ppw8kl li,
|
||||
.acss-1ppw8kl .ant-avatar + .ant-avatar {
|
||||
-webkit-transition: all 0.3s;
|
||||
transition: all 0.3s;
|
||||
-webkit-margin-end: -8px;
|
||||
margin-inline-end: -8px;
|
||||
}
|
||||
|
||||
.acss-1ppw8kl:hover li,
|
||||
.acss-1ppw8kl:hover .ant-avatar {
|
||||
-webkit-margin-end: 0;
|
||||
margin-inline-end: 0;
|
||||
}
|
||||
</style>
|
|
@ -1,265 +0,0 @@
|
|||
<template>
|
||||
<template v-if="inIframe">
|
||||
<div :id="sectionId"><slot /></div>
|
||||
</template>
|
||||
<section v-else :id="sectionId" class="code-box">
|
||||
<section class="code-box-demo">
|
||||
<template v-if="iframeDemo[iframeDemoKey]">
|
||||
<div class="browser-mockup with-url">
|
||||
<iframe :src="iframeDemo[iframeDemoKey]" :height="iframeHeight" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<slot />
|
||||
</template>
|
||||
</section>
|
||||
<section class="code-box-meta markdown">
|
||||
<div class="code-box-title">
|
||||
<a :href="`#${sectionId}`">{{ title }}</a>
|
||||
</div>
|
||||
<div class="code-box-description" v-html="docHtml"></div>
|
||||
<div class="code-box-actions">
|
||||
<a-tooltip :title="$t('app.demo.codesandbox')">
|
||||
<CodeSandboxOutlined
|
||||
class="code-box-code-copy code-box-code-action"
|
||||
@click="handleCodeSandbox"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="$t(`app.demo.type.${type === 'JS' ? 'js' : 'ts'}`)">
|
||||
<span
|
||||
class="code-expand-icon code-box-code-action"
|
||||
style="width: auto"
|
||||
@click="handleChangeType"
|
||||
>
|
||||
{{ type }}
|
||||
</span>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
v-if="!blocked"
|
||||
:title="$t(`app.demo.${copied ? 'copied' : 'copy'}`)"
|
||||
:open="copyTooltipVisible"
|
||||
@openChange="onCopyTooltipVisibleChange"
|
||||
>
|
||||
<component
|
||||
:is="copied && copyTooltipVisible ? 'CheckOutlined' : 'SnippetsOutlined'"
|
||||
key="copy"
|
||||
v-clipboard:copy="type === 'TS' ? sourceCode : jsSourceCode"
|
||||
v-clipboard:success="handleCodeCopied"
|
||||
class="code-box-code-copy code-box-code-action"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-else :title="$t('app.demo.copy')">
|
||||
<SnippetsOutlined class="code-box-code-copy code-box-code-action" @click="warning" />
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="$t(`app.demo.code.${codeExpand ? 'hide' : 'show'}`)">
|
||||
<span class="code-expand-icon code-box-code-action">
|
||||
<img
|
||||
alt="expand code"
|
||||
:src="
|
||||
theme === 'dark'
|
||||
? 'https://gw.alipayobjects.com/zos/antfincdn/btT3qDZn1U/wSAkBuJFbdxsosKKpqyq.svg'
|
||||
: 'https://gw.alipayobjects.com/zos/antfincdn/Z5c7kzvi30/expand.svg'
|
||||
"
|
||||
:class="codeExpand ? 'code-expand-icon-hide' : 'code-expand-icon-show'"
|
||||
@click="handleCodeExpand"
|
||||
/>
|
||||
<img
|
||||
alt="expand code"
|
||||
:src="
|
||||
theme === 'dark'
|
||||
? 'https://gw.alipayobjects.com/zos/antfincdn/CjZPwcKUG3/OpROPHYqWmrMDBFMZtKF.svg'
|
||||
: 'https://gw.alipayobjects.com/zos/antfincdn/4zAaozCvUH/unexpand.svg'
|
||||
"
|
||||
:class="codeExpand ? 'code-expand-icon-show' : 'code-expand-icon-hide'"
|
||||
@click="handleCodeExpand"
|
||||
/>
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</section>
|
||||
<section :class="highlightClass">
|
||||
<div ref="codeRef" class="highlight">
|
||||
<slot v-if="type === 'TS'" name="htmlCode" />
|
||||
<slot v-else name="jsVersionHtml" />
|
||||
</div>
|
||||
<div class="code-box-actions code-box-actions-bottom">
|
||||
<a-tooltip :title="$t(`app.demo.code.hide`)">
|
||||
<span class="code-expand-icon code-box-code-action">
|
||||
<img
|
||||
alt="expand code"
|
||||
:src="
|
||||
theme === 'dark'
|
||||
? 'https://gw.alipayobjects.com/zos/antfincdn/CjZPwcKUG3/OpROPHYqWmrMDBFMZtKF.svg'
|
||||
: 'https://gw.alipayobjects.com/zos/antfincdn/4zAaozCvUH/unexpand.svg'
|
||||
"
|
||||
:class="'code-expand-icon-show'"
|
||||
@click="handleCodeExpand($event, sectionId)"
|
||||
/>
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { GlobalConfig } from '../App.vue';
|
||||
import { GLOBAL_CONFIG } from '../SymbolKey';
|
||||
import { computed, defineComponent, inject, onMounted, ref } from 'vue';
|
||||
import { CheckOutlined, SnippetsOutlined, CodeSandboxOutlined } from '@ant-design/icons-vue';
|
||||
import { getCodeSandboxParams } from '../utils/generateOnlineDemo';
|
||||
import packageInfo from '../../../package.json';
|
||||
|
||||
// import { Modal } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
name: 'DemoBox',
|
||||
components: {
|
||||
CheckOutlined,
|
||||
SnippetsOutlined,
|
||||
CodeSandboxOutlined,
|
||||
},
|
||||
props: {
|
||||
jsfiddle: Object,
|
||||
},
|
||||
setup(props) {
|
||||
const codeExpand = ref(false);
|
||||
const type = ref('TS');
|
||||
const copyTooltipVisible = ref(false);
|
||||
const copied = ref(false);
|
||||
const codeRef = ref<HTMLDivElement>();
|
||||
const sectionId = computed(() => {
|
||||
const relativePath = props.jsfiddle?.relativePath || '';
|
||||
return `${relativePath.split('/').join('-').replace('.vue', '')}`.toLocaleLowerCase();
|
||||
});
|
||||
const inIframe = inject('inIframe', false);
|
||||
const iframeHeight = computed(() => props.jsfiddle?.iframe);
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
const addDemosInfo: any = inject('addDemosInfo', () => {});
|
||||
|
||||
const globalConfig = inject<GlobalConfig>(GLOBAL_CONFIG);
|
||||
const title = computed(
|
||||
() =>
|
||||
props.jsfiddle &&
|
||||
props.jsfiddle.title &&
|
||||
props.jsfiddle?.title[globalConfig.isZhCN.value ? 'zh-CN' : 'en-US'],
|
||||
);
|
||||
const warning = () => {
|
||||
// Modal.warning({
|
||||
// content: globalConfig.isZhCN
|
||||
// ? '我们检测到你可能使用了 AdBlock 或 Adblock Plus,它会影响到复制、展开代码等功能。 你可以将 Ant Design Vue 加入白名单,以便我们更好地提供服务。'
|
||||
// : 'We have detected that you may have used AdBlock or Adblock Plus, which will affect functions such as copying and expanding code. You can add Ant Design Vue to the whitelist so that we can provide better services.',
|
||||
// });
|
||||
};
|
||||
const iframeDemoKey = computed(() => {
|
||||
return (
|
||||
props.jsfiddle &&
|
||||
props.jsfiddle.title &&
|
||||
props.jsfiddle?.title['en-US'] &&
|
||||
String(props.jsfiddle?.title['en-US']).split(' ').join('-').toLowerCase()
|
||||
);
|
||||
});
|
||||
const onCopyTooltipVisibleChange = (visible: boolean) => {
|
||||
if (visible) {
|
||||
copyTooltipVisible.value = visible;
|
||||
copied.value = false;
|
||||
} else {
|
||||
copyTooltipVisible.value = visible;
|
||||
}
|
||||
};
|
||||
const docHtml = computed(() =>
|
||||
props.jsfiddle && props.jsfiddle.docHtml
|
||||
? (
|
||||
props.jsfiddle.docHtml.replace(
|
||||
`<h2 id="zh-cn">zh-CN <a class="header-anchor" href="#zh-cn">
|
||||
<span aria-hidden="true" class="anchor">#</span>
|
||||
</a></h2>`,
|
||||
'',
|
||||
).split(`<h2 id="en-us">en-US <a class="header-anchor" href="#en-us">
|
||||
<span aria-hidden="true" class="anchor">#</span>
|
||||
</a></h2>`)[globalConfig.isZhCN.value ? 0 : 1] || ''
|
||||
).trim()
|
||||
: '',
|
||||
);
|
||||
const handleCodeExpand = (_, sectionId?) => {
|
||||
if (globalConfig.blocked.value) {
|
||||
warning();
|
||||
return;
|
||||
}
|
||||
if (sectionId) {
|
||||
const element = document.getElementById(sectionId);
|
||||
if (element) {
|
||||
element.scrollIntoView();
|
||||
}
|
||||
}
|
||||
codeExpand.value = !codeExpand.value;
|
||||
};
|
||||
const handleCodeCopied = () => {
|
||||
copied.value = true;
|
||||
};
|
||||
const handleChangeType = () => {
|
||||
if (globalConfig.blocked.value) {
|
||||
warning();
|
||||
return;
|
||||
}
|
||||
type.value = type.value === 'TS' ? 'JS' : 'TS';
|
||||
};
|
||||
const handleCodeSandbox = () => {
|
||||
const code = codeRef.value.innerText;
|
||||
const params = getCodeSandboxParams(code, {
|
||||
title: `${title.value} - ant-design-vue@${packageInfo.version}`,
|
||||
});
|
||||
const div = document.createElement('div');
|
||||
div.style.display = 'none';
|
||||
div.innerHTML = `<form action="https://codesandbox.io/api/v1/sandboxes/define" method="POST" target="_blank">
|
||||
<input type="hidden" name="parameters" value="${params}" />
|
||||
<input type="submit" value="Open in sandbox" />
|
||||
</form>`;
|
||||
document.body.appendChild(div);
|
||||
(div.firstElementChild as HTMLFormElement).submit();
|
||||
document.body.removeChild(div);
|
||||
};
|
||||
const highlightClass = computed(() => {
|
||||
return {
|
||||
'highlight-wrapper': true,
|
||||
'highlight-wrapper-expand': codeExpand.value,
|
||||
};
|
||||
});
|
||||
const iframeDemo = inject('iframeDemo', {});
|
||||
onMounted(() => {
|
||||
addDemosInfo({
|
||||
href: `#${sectionId.value}`,
|
||||
title,
|
||||
});
|
||||
});
|
||||
const theme = computed(() => inject('themeMode', { theme: ref('light') }).theme.value);
|
||||
return {
|
||||
docHtml,
|
||||
iframeDemo,
|
||||
iframeDemoKey,
|
||||
iframeHeight,
|
||||
inIframe,
|
||||
theme,
|
||||
type,
|
||||
warning,
|
||||
blocked: globalConfig.blocked,
|
||||
isZhCN: globalConfig.isZhCN,
|
||||
sectionId,
|
||||
title,
|
||||
codeExpand,
|
||||
copyTooltipVisible,
|
||||
copied,
|
||||
onCopyTooltipVisibleChange,
|
||||
handleCodeExpand,
|
||||
handleCodeCopied,
|
||||
handleChangeType,
|
||||
highlightClass,
|
||||
sourceCode: decodeURIComponent(escape(window.atob(props.jsfiddle?.sourceCode))),
|
||||
jsSourceCode: decodeURIComponent(escape(window.atob(props.jsfiddle?.jsSourceCode))),
|
||||
codeRef,
|
||||
handleCodeSandbox,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style></style>
|
|
@ -1,5 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
|
@ -1,143 +0,0 @@
|
|||
import { defineComponent, toRefs, computed } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
import type { TableProps } from 'ant-design-vue';
|
||||
import { Table } from 'ant-design-vue';
|
||||
import { getDesignToken } from '../antdv-token-previewer';
|
||||
import tokenMeta from 'ant-design-vue/es/version/token-meta.json';
|
||||
import { useLocale } from '../../i18n';
|
||||
import useSiteToken from '../../hooks/useSiteToken';
|
||||
import ColorChunk from '../ColorChunk';
|
||||
|
||||
type TokenTableProps = {
|
||||
type: 'seed' | 'map' | 'alias';
|
||||
lang: 'zh' | 'en';
|
||||
};
|
||||
|
||||
type TokenData = {
|
||||
name: string;
|
||||
desc: string;
|
||||
type: string;
|
||||
value: any;
|
||||
};
|
||||
|
||||
const defaultToken = getDesignToken();
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
token: 'Token 名称',
|
||||
description: '描述',
|
||||
type: '类型',
|
||||
value: '默认值',
|
||||
},
|
||||
en: {
|
||||
token: 'Token Name',
|
||||
description: 'Description',
|
||||
type: 'Type',
|
||||
value: 'Default Value',
|
||||
},
|
||||
};
|
||||
|
||||
export function useColumns(): Exclude<TableProps<TokenData>['columns'], undefined> {
|
||||
const [locale] = useLocale(locales);
|
||||
|
||||
return [
|
||||
{
|
||||
title: locale.value.token,
|
||||
key: 'name',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: locale.value.description,
|
||||
key: 'desc',
|
||||
dataIndex: 'desc',
|
||||
},
|
||||
{
|
||||
title: locale.value.type,
|
||||
key: 'type',
|
||||
dataIndex: 'type',
|
||||
},
|
||||
{
|
||||
title: locale.value.value,
|
||||
key: 'value',
|
||||
dataIndex: 'value',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const TokenTable = defineComponent({
|
||||
props: {
|
||||
type: {
|
||||
type: String as PropType<TokenTableProps['type']>,
|
||||
},
|
||||
lang: {
|
||||
type: String as PropType<TokenTableProps['lang']>,
|
||||
},
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const { type } = toRefs(props);
|
||||
const SiteToken = useSiteToken();
|
||||
const token = computed(() => SiteToken.value.token);
|
||||
|
||||
const [, lang] = useLocale(locales);
|
||||
const columns = useColumns();
|
||||
|
||||
const data = computed<TokenData[]>(() => {
|
||||
return Object.entries(tokenMeta)
|
||||
.filter(([, meta]: any) => meta.source === type.value)
|
||||
.map(([token, meta]: any) => ({
|
||||
name: token,
|
||||
desc: lang.value === 'cn' ? meta.desc : meta.descEn,
|
||||
type: meta.type,
|
||||
value: (defaultToken as any)[token],
|
||||
}));
|
||||
});
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<Table
|
||||
dataSource={data.value}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
bordered
|
||||
{...attrs}
|
||||
v-slots={{
|
||||
bodyCell: ({ text, record, column }) => {
|
||||
if (column.key === 'type') {
|
||||
return (
|
||||
<span
|
||||
style={{
|
||||
margin: '0 1px',
|
||||
padding: '0.2em 0.4em',
|
||||
fontSize: '0.9em',
|
||||
background: `${token.value.siteMarkdownCodeBg}`,
|
||||
border: `1px solid ${token.value.colorSplit}`,
|
||||
borderRadius: '3px',
|
||||
fontFamily: 'monospace',
|
||||
}}
|
||||
>
|
||||
{record.type}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (column.key === 'value') {
|
||||
const isColor =
|
||||
typeof record.value === 'string' &&
|
||||
(record.value.startsWith('#') || record.value.startsWith('rgb'));
|
||||
if (isColor) {
|
||||
return <ColorChunk color={record.value}>{record.value}</ColorChunk>;
|
||||
}
|
||||
return (
|
||||
<span>
|
||||
{typeof record.value !== 'string' ? JSON.stringify(record.value) : record.value}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return <span>{text} </span>;
|
||||
},
|
||||
}}
|
||||
></Table>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
export default TokenTable;
|
|
@ -1,364 +0,0 @@
|
|||
import type { InputProps } from 'ant-design-vue';
|
||||
import { ConfigProvider, Input, InputNumber, Select, theme } from 'ant-design-vue';
|
||||
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent, watchEffect, computed, toRefs, ref } from 'vue';
|
||||
import { HexColorPicker, RgbaColorPicker } from '../vue-colorful';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import makeStyle from './utils/makeStyle';
|
||||
import type { ValueType } from 'ant-design-vue/es/input-number/src/utils/MiniDecimal';
|
||||
|
||||
const { useToken } = theme;
|
||||
|
||||
const useStyle = makeStyle('ColorPanel', token => ({
|
||||
'.color-panel': {
|
||||
padding: 12,
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 12,
|
||||
border: '1px solid rgba(0, 0, 0, 0.06)',
|
||||
boxShadow: token.boxShadow,
|
||||
width: 224,
|
||||
boxSizing: 'border-box',
|
||||
|
||||
'.color-panel-mode': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginBottom: 6,
|
||||
},
|
||||
'.color-panel-preview': {
|
||||
width: 24,
|
||||
height: 24,
|
||||
borderRadius: 4,
|
||||
boxShadow: '0 2px 3px -1px rgba(0,0,0,0.20), inset 0 0 0 1px rgba(0,0,0,0.09)',
|
||||
flex: 'none',
|
||||
overflow: 'hidden',
|
||||
background:
|
||||
'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAFpJREFUWAntljEKADAIA23p6v//qQ+wfUEcCu1yriEgp0FHRJSJcnehmmWm1Dv/lO4HIg1AAAKjTqm03ea88zMCCEDgO4HV5bS757f+7wRoAAIQ4B9gByAAgQ3pfiDmXmAeEwAAAABJRU5ErkJggg==) 0% 0% / 32px',
|
||||
},
|
||||
'.color-panel-preset-colors': {
|
||||
paddingTop: 12,
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
width: 200,
|
||||
},
|
||||
'.color-panel-preset-color-btn': {
|
||||
borderRadius: 4,
|
||||
width: 20,
|
||||
height: 20,
|
||||
border: 'none',
|
||||
outline: 'none',
|
||||
margin: 4,
|
||||
cursor: 'pointer',
|
||||
boxShadow: '0 2px 3px -1px rgba(0,0,0,0.20), inset 0 0 0 1px rgba(0,0,0,0.09)',
|
||||
},
|
||||
'.color-panel-mode-title': {
|
||||
color: token.colorTextPlaceholder,
|
||||
marginTop: 2,
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
},
|
||||
'.color-panel-rgba-input': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
'&-part': {
|
||||
flex: 1,
|
||||
width: 0,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
|
||||
'&-title': {
|
||||
color: token.colorTextPlaceholder,
|
||||
marginTop: 2,
|
||||
fontSize: 12,
|
||||
},
|
||||
|
||||
'&:not(:last-child)': {
|
||||
marginRight: 4,
|
||||
},
|
||||
|
||||
[`${token.rootCls}-input-number`]: {
|
||||
width: '100%',
|
||||
input: {
|
||||
fontSize: 12,
|
||||
padding: '0 4px',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export type HexColorInputProps = {
|
||||
value: string;
|
||||
onChange?: (value: string) => void;
|
||||
alpha?: boolean;
|
||||
};
|
||||
|
||||
const getHexValue = (value: string, alpha = false) => {
|
||||
return alpha ? tinycolor(value).toHex8() : tinycolor(value).toHex();
|
||||
};
|
||||
const HexColorInput = defineComponent({
|
||||
name: 'HexColorInput',
|
||||
props: {
|
||||
value: { type: String },
|
||||
alpha: { type: Boolean },
|
||||
onChange: { type: Function as PropType<(value: string) => void> },
|
||||
},
|
||||
setup(props) {
|
||||
const { value, alpha } = toRefs(props);
|
||||
|
||||
const hexValue = ref<string>(value.value);
|
||||
const focusRef = ref<boolean>(false);
|
||||
|
||||
const handleChange: InputProps['onChange'] = e => {
|
||||
hexValue.value = e.target.value;
|
||||
props.onChange(getHexValue(e.target.value, alpha.value));
|
||||
};
|
||||
|
||||
const handleBlur: InputProps['onBlur'] = (e: any) => {
|
||||
focusRef.value = false;
|
||||
hexValue.value = getHexValue(e.target.value, alpha.value);
|
||||
};
|
||||
|
||||
const handleFocus = () => {
|
||||
focusRef.value = true;
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
if (!focusRef.value) {
|
||||
hexValue.value = getHexValue(value.value, alpha.value);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<div>
|
||||
<Input
|
||||
size="small"
|
||||
value={hexValue.value}
|
||||
onFocus={handleFocus}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
v-slots={{
|
||||
prefix: () => '#',
|
||||
}}
|
||||
/>
|
||||
<div class="color-panel-mode-title">HEX{alpha.value ? '8' : ''}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
type RgbaColor = tinycolor.ColorFormats.RGBA;
|
||||
|
||||
export type RgbColorInputProps = {
|
||||
value?: RgbaColor;
|
||||
onChange?: (value: RgbaColor) => void;
|
||||
alpha?: boolean;
|
||||
};
|
||||
|
||||
const RgbColorInput = defineComponent({
|
||||
name: 'RgbColorInput',
|
||||
props: {
|
||||
value: { type: Object as PropType<RgbaColor>, default: () => ({ r: 0, g: 0, b: 0, a: 1 }) },
|
||||
onChange: { type: Function as PropType<(value: RgbaColor) => void> },
|
||||
alpha: { type: Boolean },
|
||||
},
|
||||
setup(props) {
|
||||
const { value, alpha } = toRefs(props);
|
||||
|
||||
const handleChange = (val: ValueType, key: 'r' | 'g' | 'b' | 'a') => {
|
||||
value.value[key] = val;
|
||||
props.onChange(value.value);
|
||||
};
|
||||
return () => {
|
||||
return (
|
||||
<div class="color-panel-rgba-input">
|
||||
<ConfigProvider theme={{ components: { InputNumber: { handleWidth: 12 } } }}>
|
||||
<div class="color-panel-rgba-input-part">
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={255}
|
||||
size="small"
|
||||
value={value.value.r}
|
||||
onChange={val => handleChange(val, 'r')}
|
||||
/>
|
||||
<div class="color-panel-mode-title">R</div>
|
||||
</div>
|
||||
<div class="color-panel-rgba-input-part">
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={255}
|
||||
size="small"
|
||||
value={value.value.g}
|
||||
onChange={val => handleChange(val, 'g')}
|
||||
/>
|
||||
<div class="color-panel-mode-title">G</div>
|
||||
</div>
|
||||
<div class="color-panel-rgba-input-part">
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={255}
|
||||
size="small"
|
||||
value={value.value.b}
|
||||
onChange={val => handleChange(val, 'b')}
|
||||
/>
|
||||
<div class="color-panel-mode-title">B</div>
|
||||
</div>
|
||||
{alpha.value && (
|
||||
<div class="color-panel-rgba-input-part">
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.01}
|
||||
size="small"
|
||||
value={value.value.a}
|
||||
onChange={val => handleChange(val, 'a')}
|
||||
/>
|
||||
<div class="color-panel-mode-title">A</div>
|
||||
</div>
|
||||
)}
|
||||
</ConfigProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export type ColorPanelProps = {
|
||||
color: string;
|
||||
onChange: (color: string) => void;
|
||||
alpha?: boolean;
|
||||
};
|
||||
|
||||
const colorModes = ['HEX', 'HEX8', 'RGB', 'RGBA'] as const;
|
||||
|
||||
type ColorMode = (typeof colorModes)[number];
|
||||
|
||||
const getColorStr = (color: any, mode: ColorMode) => {
|
||||
switch (mode) {
|
||||
case 'HEX':
|
||||
return tinycolor(color).toHexString();
|
||||
case 'HEX8':
|
||||
return tinycolor(color).toHex8String();
|
||||
case 'RGBA':
|
||||
case 'RGB':
|
||||
default:
|
||||
return tinycolor(color).toRgbString();
|
||||
}
|
||||
};
|
||||
const ColorPanel = defineComponent({
|
||||
name: 'ColorPanel',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
color: { type: String },
|
||||
onChange: { type: Function as PropType<(color: string) => void> },
|
||||
alpha: { type: Boolean },
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const { color, alpha } = toRefs(props);
|
||||
|
||||
const { token } = useToken();
|
||||
const [wrapSSR, hashId] = useStyle();
|
||||
const colorMode = ref<ColorMode>('HEX');
|
||||
|
||||
const presetColors = computed(() => {
|
||||
return [
|
||||
token.value.blue,
|
||||
token.value.purple,
|
||||
token.value.cyan,
|
||||
token.value.green,
|
||||
token.value.magenta,
|
||||
token.value.pink,
|
||||
token.value.red,
|
||||
token.value.orange,
|
||||
token.value.yellow,
|
||||
token.value.volcano,
|
||||
token.value.geekblue,
|
||||
token.value.gold,
|
||||
token.value.lime,
|
||||
'#000',
|
||||
];
|
||||
});
|
||||
|
||||
const handleColorModeChange = (value: ColorMode) => {
|
||||
colorMode.value = value;
|
||||
props.onChange(getColorStr(color.value, value));
|
||||
};
|
||||
return () => {
|
||||
return wrapSSR(
|
||||
<div {...attrs} class={classNames(hashId.value, 'color-panel')}>
|
||||
{(colorMode.value === 'HEX' || colorMode.value === 'RGB') && (
|
||||
<HexColorPicker
|
||||
style={{ height: '160px' }}
|
||||
color={tinycolor(color.value).toHex()}
|
||||
onChange={value => {
|
||||
props.onChange(getColorStr(value, colorMode.value));
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{(colorMode.value === 'RGBA' || colorMode.value === 'HEX8') && (
|
||||
<RgbaColorPicker
|
||||
style={{ height: '160px' }}
|
||||
color={tinycolor(color.value).toRgb()}
|
||||
onChange={value => {
|
||||
props.onChange(getColorStr(value, colorMode.value));
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div style={{ marginTop: '12px' }}>
|
||||
<div class="color-panel-mode">
|
||||
<div class="color-panel-preview">
|
||||
<div style={{ backgroundColor: color.value, width: '100%', height: '100%' }} />
|
||||
</div>
|
||||
<Select
|
||||
value={colorMode.value}
|
||||
onChange={handleColorModeChange}
|
||||
options={colorModes
|
||||
.filter(item => alpha.value || item === 'HEX' || item === 'RGB')
|
||||
.map(item => ({ value: item, key: item }))}
|
||||
size="small"
|
||||
bordered={false}
|
||||
dropdownMatchSelectWidth={false}
|
||||
/>
|
||||
</div>
|
||||
{colorMode.value === 'HEX' && (
|
||||
<HexColorInput
|
||||
value={tinycolor(color.value).toHex()}
|
||||
onChange={v => props.onChange(tinycolor(v).toHexString())}
|
||||
/>
|
||||
)}
|
||||
{colorMode.value === 'HEX8' && (
|
||||
<HexColorInput
|
||||
alpha
|
||||
value={tinycolor(color.value).toHex8()}
|
||||
onChange={v => props.onChange(tinycolor(v).toHex8String())}
|
||||
/>
|
||||
)}
|
||||
{(colorMode.value === 'RGBA' || colorMode.value === 'RGB') && (
|
||||
<RgbColorInput
|
||||
alpha={colorMode.value === 'RGBA'}
|
||||
value={tinycolor(color.value).toRgb()}
|
||||
onChange={v => props.onChange(tinycolor(v).toRgbString())}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div class="color-panel-preset-colors">
|
||||
{presetColors.value.map(presetColor => (
|
||||
<button
|
||||
key={presetColor}
|
||||
class="color-panel-preset-color-btn"
|
||||
style={{ backgroundColor: presetColor }}
|
||||
onClick={() => props.onChange(presetColor)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default ColorPanel;
|
|
@ -1,80 +0,0 @@
|
|||
import { defineComponent, toRefs } from 'vue';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||
import makeStyle from './utils/makeStyle';
|
||||
import getColorBgImg from './utils/getColorBgImg';
|
||||
|
||||
export type ColorPreviewProps = {
|
||||
color: string;
|
||||
dark?: boolean;
|
||||
};
|
||||
|
||||
const useStyle = makeStyle('ColorPreview', () => ({
|
||||
'.previewer-color-preview': {
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
position: 'relative',
|
||||
borderRadius: '50%',
|
||||
padding: 0,
|
||||
display: 'inline-block',
|
||||
|
||||
'&::before': {
|
||||
content: '""',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
borderRadius: '50%',
|
||||
top: 0,
|
||||
insetInlineStart: 0,
|
||||
position: 'absolute',
|
||||
zIndex: 2,
|
||||
backgroundColor: 'var(--antd-token-previewer-color-preview)',
|
||||
boxShadow: '0 2px 3px -1px rgba(0,0,0,0.20), inset 0 0 0 1px rgba(0,0,0,0.09)',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const ColorPreview = defineComponent({
|
||||
name: 'ColorPreview',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
color: { type: String },
|
||||
dark: { type: Boolean },
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const { color, dark } = toRefs(props);
|
||||
|
||||
const [warpSSR, hashId] = useStyle();
|
||||
|
||||
return () => {
|
||||
return warpSSR(
|
||||
<div
|
||||
{...attrs}
|
||||
class={classNames('previewer-color-preview', attrs.class, hashId.value)}
|
||||
style={[
|
||||
{
|
||||
// @ts-ignore
|
||||
['--antd-token-previewer-color-preview']: color.value,
|
||||
...(attrs.style as CSSProperties),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
content: '""',
|
||||
width: '18px',
|
||||
height: '18px',
|
||||
borderRadius: '50%',
|
||||
top: '1px',
|
||||
insetInlineStart: '1px',
|
||||
position: 'absolute',
|
||||
zIndex: 1,
|
||||
background: `${getColorBgImg(dark.value)} 0% 0% / 20px`,
|
||||
}}
|
||||
/>
|
||||
</div>,
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default ColorPreview;
|
|
@ -1,133 +0,0 @@
|
|||
import type { CSSProperties, PropType } from 'vue';
|
||||
import { defineComponent, toRefs, ref } from 'vue';
|
||||
import makeStyle from './utils/makeStyle';
|
||||
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||
import { Segmented, Tag } from 'ant-design-vue';
|
||||
|
||||
const useStyle = makeStyle('FilterPanel', token => ({
|
||||
'.previewer-filter-panel': {
|
||||
// boxShadow:
|
||||
// '0 2px 4px 0 rgba(0,0,0,0.05), 0 1px 2px 0 rgba(25,15,15,0.07), 0 0 1px 0 rgba(0,0,0,0.08)',
|
||||
// backgroundColor: '#fff',
|
||||
// borderRadius: 6,
|
||||
// padding: '8px 12px',
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
alignItems: 'start',
|
||||
|
||||
'.component-tree-head': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
flex: 'none',
|
||||
marginInlineEnd: 20,
|
||||
|
||||
'.component-tree-filter-type': {
|
||||
color: token.colorTextSecondary,
|
||||
marginInlineEnd: token.marginXS,
|
||||
fontSize: token.fontSizeSM,
|
||||
},
|
||||
|
||||
'.component-tree-filter-segmented': {
|
||||
fontSize: token.fontSizeSM,
|
||||
},
|
||||
},
|
||||
|
||||
'.preview-panel-subtitle': {
|
||||
fontSize: token.fontSizeSM,
|
||||
color: token.colorTextSecondary,
|
||||
},
|
||||
|
||||
[`${token.rootCls}-tag.previewer-token-filter-tag`]: {
|
||||
color: token.colorPrimary,
|
||||
backgroundColor: 'rgba(22,119,255,0.10)',
|
||||
border: 'none',
|
||||
borderRadius: 4,
|
||||
|
||||
'> .anticon': {
|
||||
color: token.colorPrimary,
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export type FilterMode = 'highlight' | 'filter';
|
||||
|
||||
export type FilterPanelProps = {
|
||||
filterMode?: FilterMode;
|
||||
onFilterModeChange?: (mode: FilterMode) => void;
|
||||
selectedTokens: string[];
|
||||
onSelectedTokensChange?: (newTokens: string[]) => void;
|
||||
onTokenClick?: (token: string) => void;
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
|
||||
const FilterPanel = defineComponent({
|
||||
name: 'FilterPanel',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
filterMode: { type: String as PropType<FilterMode> },
|
||||
onFilterModeChange: { type: Function as PropType<(mode: FilterMode) => void> },
|
||||
selectedTokens: { type: Array as PropType<string[]> },
|
||||
onSelectedTokensChange: { type: Function as PropType<(newTokens: string[]) => void> },
|
||||
onTokenClick: { type: Function as PropType<(token: string) => void> },
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const { filterMode: customFilterMode, selectedTokens } = toRefs(props);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle();
|
||||
|
||||
const filterMode = ref<FilterMode>(customFilterMode.value || 'filter');
|
||||
|
||||
return () => {
|
||||
if (selectedTokens.value.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return wrapSSR(
|
||||
<div {...attrs} class={classNames('previewer-filter-panel', hashId.value, attrs.class)}>
|
||||
{selectedTokens.value && selectedTokens.value.length > 0 && (
|
||||
<>
|
||||
<div class="component-tree-head">
|
||||
<div class="component-tree-filter-type">筛选方式:</div>
|
||||
<Segmented
|
||||
class="component-tree-filter-segmented"
|
||||
size="small"
|
||||
value={filterMode.value}
|
||||
onChange={value => {
|
||||
props.onFilterModeChange?.(value as any);
|
||||
filterMode.value = value as any;
|
||||
}}
|
||||
options={[
|
||||
{ label: '过滤', value: 'filter' },
|
||||
{ label: '高亮', value: 'highlight' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<span class="preview-panel-subtitle">已选中:</span>
|
||||
{selectedTokens.value.map(token => (
|
||||
<Tag
|
||||
key={token}
|
||||
closable
|
||||
onClose={() =>
|
||||
props.onSelectedTokensChange?.(
|
||||
selectedTokens.value?.filter(item => item !== token),
|
||||
)
|
||||
}
|
||||
style={{ marginBlock: '2px', cursor: 'pointer' }}
|
||||
class="previewer-token-filter-tag"
|
||||
onClick={() => props.onTokenClick?.(token)}
|
||||
>
|
||||
{token}
|
||||
</Tag>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>,
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default FilterPanel;
|
|
@ -1,102 +0,0 @@
|
|||
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||
import makeStyle from './utils/makeStyle';
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent, toRefs } from 'vue';
|
||||
|
||||
const useStyle = makeStyle('IconSwitch', () => {
|
||||
const activeBackground = '#314659';
|
||||
return {
|
||||
'.theme-editor-icon-switch': {
|
||||
display: 'inline-block',
|
||||
|
||||
'.holder': {
|
||||
position: 'relative',
|
||||
display: 'inline-flex',
|
||||
background: '#ebedf0',
|
||||
borderRadius: '100vw',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.3s',
|
||||
|
||||
'&::before': {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 'calc(100% - 32px)',
|
||||
width: 32,
|
||||
height: 32,
|
||||
background: activeBackground,
|
||||
borderRadius: '100vw',
|
||||
transition: 'all 0.3s',
|
||||
content: '""',
|
||||
},
|
||||
|
||||
'&.leftChecked::before': {
|
||||
left: 0,
|
||||
},
|
||||
|
||||
'&:hover': {
|
||||
boxShadow: '0 0 3px fade(@active-background, 40%)',
|
||||
},
|
||||
},
|
||||
|
||||
'.icon': {
|
||||
position: 'relative',
|
||||
width: 32,
|
||||
height: 32,
|
||||
color: '#a3b1bf',
|
||||
lineHeight: '32px',
|
||||
textAlign: 'center',
|
||||
transition: 'all 0.3s',
|
||||
fontSize: 16,
|
||||
|
||||
'.anticon': {
|
||||
fontSize: 14,
|
||||
},
|
||||
|
||||
'&:first-child': {
|
||||
marginInlineEnd: -4,
|
||||
},
|
||||
|
||||
'&.active': {
|
||||
color: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export interface IconSwitchProps {
|
||||
leftChecked?: boolean;
|
||||
onChange?: (leftChecked: boolean) => void;
|
||||
}
|
||||
const IconSwitch = defineComponent({
|
||||
name: 'IconSwitch',
|
||||
props: {
|
||||
leftChecked: { type: Boolean },
|
||||
onChange: { type: Function as PropType<(leftChecked: boolean) => void> },
|
||||
},
|
||||
setup(props, { attrs, slots }) {
|
||||
const { leftChecked } = toRefs(props);
|
||||
const [wrapSSR, hashId] = useStyle();
|
||||
|
||||
return () => {
|
||||
return wrapSSR(
|
||||
<div {...attrs} class={classNames('theme-editor-icon-switch', attrs.class, hashId.value)}>
|
||||
<div
|
||||
class={classNames('holder', leftChecked.value && 'leftChecked')}
|
||||
onClick={() => {
|
||||
props.onChange(!leftChecked.value);
|
||||
}}
|
||||
>
|
||||
<span class={classNames('icon', leftChecked.value && 'active')}>
|
||||
{slots.leftIcon && slots.leftIcon()}
|
||||
</span>
|
||||
<span class={classNames('icon', !leftChecked.value && 'active')}>
|
||||
{slots.rightIcon && slots.rightIcon()}
|
||||
</span>
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
export default IconSwitch;
|
|
@ -1,35 +0,0 @@
|
|||
import type { CSSProperties, PropType } from 'vue';
|
||||
import { defineComponent, toRefs } from 'vue';
|
||||
import { antdComponents } from './component-panel';
|
||||
import type { Theme } from './interface';
|
||||
import ComponentDemoPro from './token-panel-pro/ComponentDemoPro';
|
||||
|
||||
export type PreviewDemoProps = {
|
||||
theme: Theme;
|
||||
};
|
||||
|
||||
const PreviewDemo = defineComponent({
|
||||
name: 'PreviewDemo',
|
||||
props: {
|
||||
theme: { type: Object as PropType<Theme> },
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const { theme } = toRefs(props);
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<div {...attrs} style={{ ...(attrs.style as CSSProperties), overflow: 'auto' }}>
|
||||
<ComponentDemoPro
|
||||
theme={theme.value}
|
||||
components={antdComponents}
|
||||
componentDrawer={false}
|
||||
showAll
|
||||
style={{ minHeight: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default PreviewDemo;
|
|
@ -1,168 +0,0 @@
|
|||
import type { PropType } from 'vue';
|
||||
import { defineComponent, toRefs, ref, computed } from 'vue';
|
||||
import type { DerivativeFunc } from 'ant-design-vue/es/_util/cssinjs';
|
||||
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||
import type { SelectedToken, Theme } from './interface';
|
||||
import type { Locale } from './locale';
|
||||
import { useProvideLocaleContext, zhCN } from './locale';
|
||||
import { mapRelatedAlias, seedRelatedAlias, seedRelatedMap } from './meta/TokenRelation';
|
||||
import { getRelatedComponents } from './utils/statistic';
|
||||
import makeStyle from './utils/makeStyle';
|
||||
import useControlledTheme from './hooks/useControlledTheme';
|
||||
|
||||
import type { TokenPanelProProps } from './token-panel-pro';
|
||||
import TokenPanelPro from './token-panel-pro';
|
||||
import ComponentDemoPro from './token-panel-pro/ComponentDemoPro';
|
||||
import { antdComponents } from './component-panel';
|
||||
|
||||
const useStyle = makeStyle('ThemeEditor', token => ({
|
||||
'.antd-theme-editor': {
|
||||
backgroundColor: token.colorBgLayout,
|
||||
display: 'flex',
|
||||
},
|
||||
}));
|
||||
|
||||
const defaultTheme: Theme = {
|
||||
name: '默认主题',
|
||||
key: 'default',
|
||||
config: {},
|
||||
};
|
||||
|
||||
export type ThemeEditorProps = {
|
||||
/**
|
||||
* @deprecated
|
||||
* @default true
|
||||
*/
|
||||
simple?: boolean;
|
||||
theme?: Theme;
|
||||
onThemeChange?: (theme: Theme) => void;
|
||||
darkAlgorithm?: DerivativeFunc<any, any>;
|
||||
locale?: Locale;
|
||||
};
|
||||
|
||||
const ThemeEditor = defineComponent({
|
||||
name: 'ThemeEditor',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
simple: { type: Boolean },
|
||||
theme: { type: Object as PropType<Theme> },
|
||||
onThemeChange: { type: Function as PropType<(theme: Theme) => void> },
|
||||
darkAlgorithm: { type: Function as PropType<DerivativeFunc<any, any>> },
|
||||
locale: { type: Object as PropType<Locale>, default: zhCN },
|
||||
},
|
||||
setup(props, { attrs, expose }) {
|
||||
const { theme: customTheme, darkAlgorithm, locale } = toRefs(props);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle();
|
||||
|
||||
const selectedTokens = ref<SelectedToken>({
|
||||
seed: ['colorPrimary'],
|
||||
});
|
||||
|
||||
const aliasOpen = ref<boolean>(false);
|
||||
|
||||
const { theme, infoFollowPrimary, onInfoFollowPrimaryChange, updateRef } = useControlledTheme({
|
||||
theme: customTheme,
|
||||
defaultTheme,
|
||||
onChange: props.onThemeChange,
|
||||
darkAlgorithm,
|
||||
});
|
||||
|
||||
const handleTokenSelect: TokenPanelProProps['onTokenSelect'] = (token, type) => {
|
||||
const tokens = typeof token === 'string' ? (token ? [token] : []) : token;
|
||||
if (type === 'seed') {
|
||||
return {
|
||||
seed: tokens,
|
||||
};
|
||||
}
|
||||
|
||||
let newSelectedTokens = { ...selectedTokens.value };
|
||||
tokens.forEach(newToken => {
|
||||
newSelectedTokens = {
|
||||
...selectedTokens.value,
|
||||
[type]: selectedTokens.value[type]?.includes(newToken)
|
||||
? selectedTokens.value[type]?.filter(t => t !== newToken)
|
||||
: [...(selectedTokens.value[type] ?? []), newToken],
|
||||
};
|
||||
});
|
||||
if (type === 'map') {
|
||||
delete newSelectedTokens.alias;
|
||||
}
|
||||
selectedTokens.value = newSelectedTokens;
|
||||
};
|
||||
|
||||
const computedSelectedTokens = computed(() => {
|
||||
if (
|
||||
selectedTokens.value.seed?.length &&
|
||||
!selectedTokens.value.map?.length &&
|
||||
!selectedTokens.value.alias?.length
|
||||
) {
|
||||
return [
|
||||
...selectedTokens.value.seed,
|
||||
...((seedRelatedMap as any)[selectedTokens.value.seed[0]] ?? []),
|
||||
...((seedRelatedAlias as any)[selectedTokens.value.seed[0]] ?? []),
|
||||
];
|
||||
}
|
||||
if (selectedTokens.value.map?.length && !selectedTokens.value.alias?.length) {
|
||||
return [
|
||||
...selectedTokens.value.map,
|
||||
...selectedTokens.value.map.reduce((result, item) => {
|
||||
return result.concat((mapRelatedAlias as any)[item]);
|
||||
}, []),
|
||||
];
|
||||
}
|
||||
if (selectedTokens.value.alias?.length) {
|
||||
return [...selectedTokens.value.alias];
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
const relatedComponents = computed(() => {
|
||||
return computedSelectedTokens.value ? getRelatedComponents(computedSelectedTokens.value) : [];
|
||||
});
|
||||
|
||||
expose({
|
||||
updateRef,
|
||||
});
|
||||
|
||||
useProvideLocaleContext(locale);
|
||||
|
||||
return () => {
|
||||
return wrapSSR(
|
||||
<div {...attrs} class={classNames(hashId.value, 'antd-theme-editor', attrs.class)}>
|
||||
<div
|
||||
style={{
|
||||
flex: aliasOpen.value ? '0 0 860px' : `0 0 ${860 - 320}px`,
|
||||
height: '100%',
|
||||
backgroundColor: '#F7F8FA',
|
||||
backgroundImage: 'linear-gradient(180deg, #FFFFFF 0%, rgba(246,247,249,0.00) 100%)',
|
||||
display: 'flex',
|
||||
transition: 'all 0.3s',
|
||||
}}
|
||||
>
|
||||
<TokenPanelPro
|
||||
aliasOpen={aliasOpen.value}
|
||||
onAliasOpenChange={open => (aliasOpen.value = open)}
|
||||
theme={theme.value}
|
||||
style={{ flex: 1 }}
|
||||
selectedTokens={selectedTokens.value}
|
||||
onTokenSelect={handleTokenSelect}
|
||||
infoFollowPrimary={infoFollowPrimary.value}
|
||||
onInfoFollowPrimaryChange={onInfoFollowPrimaryChange}
|
||||
/>
|
||||
</div>
|
||||
<ComponentDemoPro
|
||||
theme={theme.value}
|
||||
components={antdComponents}
|
||||
activeComponents={relatedComponents.value}
|
||||
selectedTokens={computedSelectedTokens.value}
|
||||
style={{ flex: 1, overflow: 'auto' }}
|
||||
componentDrawer
|
||||
/>
|
||||
</div>,
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default ThemeEditor;
|
|
@ -1,240 +0,0 @@
|
|||
import type { PropType } from 'vue';
|
||||
import { defineComponent, toRefs, computed } from 'vue';
|
||||
import makeStyle from './utils/makeStyle';
|
||||
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||
import { Button, Dropdown, Menu } from 'ant-design-vue';
|
||||
import { CloseOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||
import type { Theme } from './interface';
|
||||
|
||||
interface ThemeItem extends Theme {
|
||||
icon?: any;
|
||||
closable?: boolean;
|
||||
fixed?: boolean;
|
||||
}
|
||||
|
||||
export type ThemeSelectProps = {
|
||||
onEnabledThemeChange: (themes: string[]) => void;
|
||||
onShownThemeChange: (
|
||||
themes: string[],
|
||||
selectTheme: string,
|
||||
info: { type: 'select' | 'deselect' },
|
||||
) => void;
|
||||
enabledThemes: string[];
|
||||
shownThemes: string[];
|
||||
themes: ThemeItem[];
|
||||
showAddTheme?: boolean;
|
||||
};
|
||||
|
||||
const useStyle = makeStyle('ThemeSelect', token => ({
|
||||
'.previewer-theme-select': {
|
||||
padding: `${token.paddingXXS}px ${token.paddingXS}px`,
|
||||
borderRadius: 4,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.02)',
|
||||
height: token.controlHeight,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
overflow: 'hidden',
|
||||
|
||||
[`${token.rootCls}-btn.previewer-theme-select-add-btn`]: {
|
||||
minWidth: 0,
|
||||
width: 16,
|
||||
height: 16,
|
||||
fontSize: 8,
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginInlineStart: token.marginSM,
|
||||
boxShadow: 'none',
|
||||
},
|
||||
|
||||
'.previewer-theme-select-tag': {
|
||||
height: 22,
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
boxSizing: 'border-box',
|
||||
borderRadius: 4,
|
||||
backgroundColor: token.colorBgContainer,
|
||||
border: `${token.lineWidth}px ${token.lineType} ${token.colorBorder}`,
|
||||
paddingInline: 10,
|
||||
fontSize: token.fontSizeSM,
|
||||
position: 'relative',
|
||||
cursor: 'pointer',
|
||||
// transition: `all ${token.motionDurationMid}`,
|
||||
|
||||
'&:not(:last-child)': {
|
||||
marginInlineEnd: token.marginXS,
|
||||
},
|
||||
|
||||
'&.previewer-theme-select-tag-active': {
|
||||
border: `${token.lineWidth}px ${token.lineType} ${token['blue-1']}`,
|
||||
backgroundColor: 'rgba(22,119,255,0.10)',
|
||||
color: token.colorPrimary,
|
||||
|
||||
'&::after': {
|
||||
content: '""',
|
||||
borderStartEndRadius: 2,
|
||||
position: 'absolute',
|
||||
insetInlineEnd: 2,
|
||||
top: 2,
|
||||
width: 6,
|
||||
height: 6,
|
||||
background: `linear-gradient(to right top, transparent, transparent 50%, ${token.colorPrimary} 50%, ${token.colorPrimary} 100%)`,
|
||||
},
|
||||
},
|
||||
|
||||
'.previewer-theme-select-tag-close-btn': {
|
||||
position: 'absolute',
|
||||
top: -2,
|
||||
insetInlineEnd: -2,
|
||||
width: 12,
|
||||
height: 12,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
background: token.colorBgContainer,
|
||||
boxShadow:
|
||||
'0 2px 8px -2px rgba(0,0,0,0.05), 0 1px 4px -1px rgba(25,15,15,0.07), 0 0 1px 0 rgba(0,0,0,0.08)',
|
||||
borderRadius: '50%',
|
||||
opacity: 0,
|
||||
pointerEvents: 'none',
|
||||
zIndex: 2,
|
||||
color: token.colorIcon,
|
||||
|
||||
'> .anticon': {
|
||||
fontSize: 6,
|
||||
},
|
||||
},
|
||||
|
||||
'&:hover': {
|
||||
'.previewer-theme-select-tag-close-btn': {
|
||||
opacity: 1,
|
||||
pointerEvents: 'initial',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
'.previewer-theme-select-dropdown': {
|
||||
'.previewer-theme-select-dropdown-title': {
|
||||
[`${token.rootCls}-dropdown-menu-item-group-title`]: {
|
||||
fontSize: token.fontSizeSM,
|
||||
paddingBottom: token.padding,
|
||||
paddingTop: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const ThemeSelect = defineComponent({
|
||||
name: 'ThemeSelect',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
onEnabledThemeChange: { type: Function as PropType<(themes: string[]) => void> },
|
||||
onShownThemeChange: {
|
||||
type: Function as PropType<
|
||||
(themes: string[], selectTheme: string, info: { type: 'select' | 'deselect' }) => void
|
||||
>,
|
||||
},
|
||||
enabledThemes: { type: Array as PropType<string[]> },
|
||||
shownThemes: { type: Array as PropType<string[]> },
|
||||
themes: { type: Array as PropType<ThemeItem[]> },
|
||||
showAddTheme: { type: Boolean },
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const { enabledThemes, shownThemes, themes, showAddTheme } = toRefs(props);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle();
|
||||
|
||||
const dropdownItems = computed(() => [
|
||||
{
|
||||
disabled: true,
|
||||
label: '添加主题即可预览',
|
||||
className: 'previewer-theme-select-dropdown-title',
|
||||
type: 'group',
|
||||
key: 'add-theme-to-preview',
|
||||
},
|
||||
...themes.value
|
||||
.filter(theme => !shownThemes.value.includes(theme.key))
|
||||
.map(theme => ({
|
||||
icon: theme.icon,
|
||||
value: theme.key,
|
||||
label: theme.name,
|
||||
key: theme.key,
|
||||
onClick: () => {
|
||||
props.onShownThemeChange([...shownThemes.value, theme.key], theme.key, {
|
||||
type: 'select',
|
||||
});
|
||||
},
|
||||
})),
|
||||
]);
|
||||
|
||||
const shownThemeEntities = computed(() =>
|
||||
themes.value.filter(theme => shownThemes.value.includes(theme.key)),
|
||||
);
|
||||
|
||||
return () => {
|
||||
return wrapSSR(
|
||||
<div {...attrs} class={classNames('previewer-theme-select', hashId.value, attrs.class)}>
|
||||
{shownThemeEntities.value.map(theme => (
|
||||
<span
|
||||
onClick={() => {
|
||||
if (theme.fixed) {
|
||||
return;
|
||||
}
|
||||
props.onEnabledThemeChange(
|
||||
enabledThemes.value.includes(theme.key)
|
||||
? enabledThemes.value.filter(item => item !== theme.key)
|
||||
: [...enabledThemes.value, theme.key],
|
||||
);
|
||||
}}
|
||||
key={theme.key}
|
||||
class={classNames('previewer-theme-select-tag', {
|
||||
'previewer-theme-select-tag-active': enabledThemes.value.includes(theme.key),
|
||||
})}
|
||||
>
|
||||
{theme.name}
|
||||
{theme.closable && (
|
||||
<span
|
||||
class="previewer-theme-select-tag-close-btn"
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
props.onEnabledThemeChange(
|
||||
enabledThemes.value.filter(item => item !== theme.key),
|
||||
);
|
||||
props.onShownThemeChange(
|
||||
shownThemes.value.filter(item => item !== theme.key),
|
||||
theme.key,
|
||||
{ type: 'deselect' },
|
||||
);
|
||||
}}
|
||||
>
|
||||
<CloseOutlined />
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
))}
|
||||
{showAddTheme.value && (
|
||||
<Dropdown
|
||||
placement="bottomRight"
|
||||
trigger={['click']}
|
||||
overlayClassName={classNames('previewer-theme-select-dropdown', hashId.value)}
|
||||
v-slots={{
|
||||
overlay: () => <Menu items={dropdownItems.value} />,
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="primary"
|
||||
shape="circle"
|
||||
class="previewer-theme-select-add-btn"
|
||||
icon={<PlusOutlined />}
|
||||
/>
|
||||
</Dropdown>
|
||||
)}
|
||||
</div>,
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default ThemeSelect;
|
|
@ -1,250 +0,0 @@
|
|||
import { Button, Popover, Input, InputNumber } from 'ant-design-vue';
|
||||
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent, toRefs, computed, ref, watch } from 'vue';
|
||||
import { debounce } from 'lodash';
|
||||
import ColorPanel from './ColorPanel';
|
||||
import ColorPreview from './ColorPreview';
|
||||
import type { MutableTheme } from './interface';
|
||||
import { useInjectLocaleContext } from './locale';
|
||||
import isColor from './utils/isColor';
|
||||
import makeStyle from './utils/makeStyle';
|
||||
|
||||
const useStyle = makeStyle('TokenInput', token => ({
|
||||
'.previewer-token-input': {
|
||||
[`${token.rootCls}-input-group-addon, ${token.rootCls}-input-number-group-addon`]: {
|
||||
border: '0 !important',
|
||||
color: `rgba(0, 0, 0, 0.25) !important`,
|
||||
fontSize: `${token.fontSizeSM}px !important`,
|
||||
padding: '0 !important',
|
||||
backgroundColor: 'transparent !important',
|
||||
|
||||
'&:first-child': {
|
||||
paddingInlineStart: 0,
|
||||
},
|
||||
|
||||
'&:last-child': {
|
||||
paddingInlineEnd: 0,
|
||||
},
|
||||
},
|
||||
|
||||
[`${token.rootCls}-input-group-wrapper, ${token.rootCls}-input-number-group-wrapper`]: {
|
||||
padding: 0,
|
||||
height: 24,
|
||||
width: '100%',
|
||||
|
||||
input: {
|
||||
fontSize: token.fontSizeSM,
|
||||
lineHeight: token.lineHeightSM,
|
||||
padding: `2px ${token.paddingXS}px`,
|
||||
height: 24,
|
||||
},
|
||||
},
|
||||
|
||||
[`${token.rootCls}-input-group-wrapper ${token.rootCls}-input, ${token.rootCls}-input-number-group-wrapper ${token.rootCls}-input-number`]:
|
||||
{
|
||||
background: 'white',
|
||||
borderRadius: `${token.borderRadiusLG}px !important`,
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
},
|
||||
|
||||
'&&-light': {
|
||||
[`${token.rootCls}-input-group-addon, ${token.rootCls}-input-number-group-addon`]: {
|
||||
backgroundColor: token.colorBgContainer,
|
||||
},
|
||||
|
||||
[`${token.rootCls}-input-group-wrapper ${token.rootCls}-input,
|
||||
${token.rootCls}-input-number-group-wrapper ${token.rootCls}-input-number-input`]: {
|
||||
background: token.colorFillAlter,
|
||||
},
|
||||
},
|
||||
|
||||
'&&-readonly': {
|
||||
input: {
|
||||
cursor: 'text',
|
||||
color: token.colorText,
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export type TokenInputProps = {
|
||||
theme?: MutableTheme;
|
||||
value?: string | number;
|
||||
onChange?: (value: string | number) => void;
|
||||
light?: boolean;
|
||||
readonly?: boolean;
|
||||
onReset?: () => void;
|
||||
canReset?: boolean;
|
||||
hideTheme?: boolean;
|
||||
};
|
||||
|
||||
const TokenInput = defineComponent({
|
||||
name: 'TokenInput',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
theme: { type: Object as PropType<MutableTheme> },
|
||||
value: { type: [String, Number] },
|
||||
onChange: { type: Function as PropType<(value: string | number) => void> },
|
||||
light: { type: Boolean },
|
||||
readonly: { type: Boolean },
|
||||
onReset: { type: Function as PropType<() => void> },
|
||||
canReset: { type: Boolean },
|
||||
hideTheme: { type: Boolean },
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const { value, theme, light, readonly, canReset: customCanReset, hideTheme } = toRefs(props);
|
||||
|
||||
const valueRef = ref<number | string>(value.value || '');
|
||||
|
||||
const tokenValue = ref<string | number>(value.value || '');
|
||||
|
||||
const canReset = computed(() => customCanReset.value ?? valueRef.value !== tokenValue.value);
|
||||
|
||||
const locale = useInjectLocaleContext();
|
||||
|
||||
const [wrapSSR, hashId] = useStyle();
|
||||
|
||||
watch(
|
||||
value,
|
||||
val => {
|
||||
if (val !== undefined) {
|
||||
tokenValue.value = val;
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
const debouncedOnChange = debounce((newValue: number | string) => {
|
||||
props.onChange?.(newValue);
|
||||
}, 500);
|
||||
|
||||
const handleTokenChange = (newValue: number | string) => {
|
||||
if (!readonly.value) {
|
||||
tokenValue.value = newValue;
|
||||
debouncedOnChange(newValue);
|
||||
}
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
if (props.onReset) {
|
||||
props.onReset();
|
||||
} else {
|
||||
handleTokenChange(valueRef.value);
|
||||
}
|
||||
};
|
||||
|
||||
return () => {
|
||||
const addonAfter = !readonly.value && (
|
||||
<span
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
minWidth: hideTheme.value ? '' : '80px',
|
||||
}}
|
||||
>
|
||||
{canReset.value || hideTheme.value ? (
|
||||
<Button
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
}}
|
||||
onClick={handleReset}
|
||||
type="link"
|
||||
size="small"
|
||||
disabled={!canReset.value}
|
||||
>
|
||||
{locale.value.reset}
|
||||
</Button>
|
||||
) : (
|
||||
<span style={{ padding: '0 8px' }}>{theme.value?.name}</span>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
|
||||
let inputNode;
|
||||
if (typeof valueRef.value === 'string' && isColor(valueRef.value)) {
|
||||
inputNode = (
|
||||
<Input
|
||||
bordered={false}
|
||||
addonAfter={addonAfter}
|
||||
value={String(tokenValue.value)}
|
||||
disabled={readonly.value}
|
||||
addonBefore={
|
||||
<Popover
|
||||
trigger="click"
|
||||
placement="bottomRight"
|
||||
arrow-point-at-center
|
||||
overlayInnerStyle={{ padding: 0 }}
|
||||
v-slots={{
|
||||
content: () => (
|
||||
<ColorPanel
|
||||
alpha
|
||||
color={String(tokenValue.value)}
|
||||
style={{ border: 'none' }}
|
||||
onChange={(v: string) => {
|
||||
handleTokenChange(v);
|
||||
}}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<ColorPreview
|
||||
color={String(tokenValue.value)}
|
||||
dark={theme.value?.key === 'dark'}
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
marginInlineEnd: '8px',
|
||||
verticalAlign: 'top',
|
||||
}}
|
||||
/>
|
||||
</Popover>
|
||||
}
|
||||
onChange={e => {
|
||||
handleTokenChange(e.target.value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
} else if (typeof valueRef.value === 'number') {
|
||||
inputNode = (
|
||||
<InputNumber
|
||||
addonAfter={addonAfter}
|
||||
bordered={false}
|
||||
value={tokenValue.value}
|
||||
disabled={readonly.value}
|
||||
onChange={newValue => {
|
||||
handleTokenChange(Number(newValue));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
inputNode = (
|
||||
<Input
|
||||
addonAfter={addonAfter}
|
||||
bordered={false}
|
||||
value={String(tokenValue.value)}
|
||||
disabled={readonly.value}
|
||||
onChange={e => {
|
||||
handleTokenChange(
|
||||
typeof value.value === 'number' ? Number(e.target.value) : e.target.value,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return wrapSSR(
|
||||
<div
|
||||
{...attrs}
|
||||
class={classNames('previewer-token-input', hashId.value, attrs.class, {
|
||||
'previewer-token-input-light': light.value,
|
||||
'previewer-token-input-readonly': readonly.value,
|
||||
})}
|
||||
>
|
||||
{inputNode}
|
||||
</div>,
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default TokenInput;
|
|
@ -1,24 +0,0 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import { Alert, Space } from 'ant-design-vue';
|
||||
import type { ComponentDemo } from '../../interface';
|
||||
|
||||
const Demo = defineComponent({
|
||||
setup() {
|
||||
return () => (
|
||||
<Space direction={'vertical'}>
|
||||
<Alert message="Success Tips" type="success" showIcon />
|
||||
<Alert message="Informational Notes" type="info" showIcon />
|
||||
<Alert message="Warning" type="warning" showIcon closable />
|
||||
<Alert message="Error" type="error" showIcon />
|
||||
</Space>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const componentDemo: ComponentDemo = {
|
||||
demo: <Demo />,
|
||||
tokens: ['colorIconHover', 'colorIcon', 'colorText'],
|
||||
key: 'alert',
|
||||
};
|
||||
|
||||
export default componentDemo;
|
|
@ -1,28 +0,0 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import { Alert, Space } from 'ant-design-vue';
|
||||
import type { ComponentDemo } from '../../interface';
|
||||
|
||||
const Demo = defineComponent({
|
||||
setup() {
|
||||
return () => (
|
||||
<Space direction={'vertical'}>
|
||||
<Alert message="Error" type="error" showIcon />
|
||||
|
||||
<Alert
|
||||
message="Error"
|
||||
description="This is an error message about copywriting."
|
||||
type="error"
|
||||
showIcon
|
||||
/>
|
||||
</Space>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const componentDemo: ComponentDemo = {
|
||||
demo: <Demo />,
|
||||
tokens: ['colorErrorBg', 'colorErrorBorder', 'colorError'],
|
||||
key: 'error',
|
||||
};
|
||||
|
||||
export default componentDemo;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue