├── .DS_Store ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jsLibraryMappings.xml ├── lin-ui-vue.iml ├── modules.xml ├── prettier.xml └── vcs.xml ├── .prettierignore ├── .prettierrc ├── README.md ├── commitlint.config.js ├── package-lock.json ├── package.json ├── packages ├── .DS_Store ├── cli │ ├── .eslintrc.js │ ├── .prettierrc │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── commands │ │ │ ├── build.ts │ │ │ ├── compile.ts │ │ │ ├── create.ts │ │ │ └── dev.ts │ │ ├── config │ │ │ └── vite.config.ts │ │ ├── constant │ │ │ └── index.ts │ │ ├── generate │ │ │ ├── generateAppConfig.ts │ │ │ ├── generateEntry.ts │ │ │ └── generateTypes.ts │ │ ├── index.ts │ │ ├── module.d.ts │ │ └── utils │ │ │ ├── component.ts │ │ │ ├── glob.ts │ │ │ ├── index.ts │ │ │ └── logger.ts │ ├── template │ │ └── component │ │ │ ├── component.less.ejs │ │ │ ├── component.vue.ejs │ │ │ ├── docs │ │ │ └── README.ejs │ │ │ ├── example │ │ │ └── index.ejs │ │ │ ├── index.ejs │ │ │ └── props.ejs │ └── tsconfig.json ├── eslint-config │ ├── index.js │ └── package.json ├── icons │ ├── .pnpm-debug.log │ ├── babel.config.json │ ├── components │ │ ├── Icon.jsx │ │ └── icon.less │ ├── example │ │ ├── App.vue │ │ ├── components │ │ │ └── IconDemo.tsx │ │ ├── env.d.ts │ │ ├── index.html │ │ └── main.js │ ├── gulpfile.ts │ ├── package.json │ ├── scripts │ │ ├── example.js │ │ └── generateComponents.ts │ ├── src │ │ ├── asn │ │ │ ├── AccountBookFilled.ts │ │ │ ├── AccountBookOutlined.ts │ │ │ ├── AccountBookTwoTone.ts │ │ │ ├── AlertFilled.ts │ │ │ ├── AlertOutlined.ts │ │ │ ├── AlertTwoTone.ts │ │ │ ├── ApiFilled.ts │ │ │ ├── ApiOutlined.ts │ │ │ ├── ApiTwoTone.ts │ │ │ ├── BookFilled.ts │ │ │ ├── BookOutlined.ts │ │ │ └── BookTwoTone.ts │ │ ├── components │ │ │ ├── AccountBookFilled.jsx │ │ │ ├── AccountBookOutlined.jsx │ │ │ ├── AccountBookTwoTone.jsx │ │ │ ├── AlertFilled.jsx │ │ │ ├── AlertOutlined.jsx │ │ │ ├── AlertTwoTone.jsx │ │ │ ├── ApiFilled.jsx │ │ │ ├── ApiOutlined.jsx │ │ │ ├── ApiTwoTone.jsx │ │ │ ├── BookFilled.jsx │ │ │ ├── BookOutlined.jsx │ │ │ ├── BookTwoTone.jsx │ │ │ └── index.jsx │ │ ├── index.js │ │ └── types.ts │ ├── svg │ │ ├── filled │ │ │ ├── account-book.svg │ │ │ ├── alert.svg │ │ │ ├── api.svg │ │ │ └── book.svg │ │ ├── outlined │ │ │ ├── account-book.svg │ │ │ ├── alert.svg │ │ │ ├── api.svg │ │ │ └── book.svg │ │ └── twotone │ │ │ ├── account-book.svg │ │ │ ├── alert.svg │ │ │ ├── api.svg │ │ │ └── book.svg │ ├── tasks │ │ ├── clean.ts │ │ ├── generateIcons.ts │ │ ├── templates │ │ │ └── icon.ts.ejs │ │ └── utils │ │ │ ├── createTransformStream.ts │ │ │ ├── svg2VNode.ts │ │ │ ├── twoTone.ts │ │ │ ├── useTemplate.ts │ │ │ └── utils.ts │ └── tsconfig.json ├── markdown-to-vue │ ├── index.js │ └── package.json └── ui │ ├── .gitignore │ ├── .lin-ui-vue │ └── components.json │ ├── .vscode │ └── extensions.json │ ├── README.md │ ├── babel.config.json │ ├── gulpfile.ts │ ├── index.ts │ ├── package.json │ ├── shims-md.d.ts │ ├── shims-vue.d.ts │ ├── site │ ├── docs │ │ ├── Event.md │ │ ├── Question.md │ │ └── Start.md │ ├── index.html │ ├── mobile.html │ ├── mobile │ │ ├── App.vue │ │ ├── components │ │ │ └── Index.vue │ │ ├── env.d.ts │ │ ├── main.ts │ │ ├── public │ │ │ └── favicon.ico │ │ ├── route.ts │ │ └── routes │ │ │ └── index.ts │ └── pc │ │ ├── App.vue │ │ ├── assets │ │ └── images │ │ │ ├── bottom-logo.png │ │ │ ├── favicon.ico │ │ │ ├── h1-Icon.jpg │ │ │ ├── h2-icon1.png │ │ │ ├── h2-icon2.png │ │ │ ├── h2-icon3.png │ │ │ ├── h2-icon4.png │ │ │ ├── left-logo.png │ │ │ └── logo.png │ │ ├── components │ │ ├── AppHeader.vue │ │ ├── AppLayout.vue │ │ ├── AppMain.vue │ │ ├── AppMobile.vue │ │ └── AppSidebar.vue │ │ ├── main.ts │ │ ├── menu.json │ │ ├── pages │ │ └── index │ │ │ └── index.vue │ │ ├── route.ts │ │ ├── routes │ │ └── index.ts │ │ └── style │ │ ├── hljs.scss │ │ └── index.scss │ ├── src │ ├── avatar │ │ ├── Avatar.vue │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ └── index.vue │ │ ├── index.ts │ │ └── props.ts │ ├── button │ │ ├── Button.vue │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ └── index.vue │ │ ├── index.ts │ │ ├── props.ts │ │ └── utils │ │ │ └── index.ts │ ├── cell │ │ ├── Cell.vue │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ └── index.vue │ │ ├── index.ts │ │ └── props.ts │ ├── col │ │ ├── Col.vue │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ └── index.vue │ │ ├── index.ts │ │ ├── props.ts │ │ └── provider.ts │ ├── config-provider │ │ ├── ConfigProvider.vue │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ └── index.vue │ │ ├── index.ts │ │ ├── props.ts │ │ └── provideGlobalConfig.ts │ ├── icon │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ └── index.vue │ │ ├── icon.vue │ │ └── index.ts │ ├── image │ │ ├── Image.vue │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ └── index.vue │ │ ├── index.ts │ │ └── props.ts │ ├── lazy │ │ ├── Lazy.ts │ │ ├── constant.ts │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ ├── imageError.vue │ │ │ └── index.vue │ │ ├── imageManger.ts │ │ ├── index.ts │ │ └── types.ts │ ├── locale │ │ ├── en-US.ts │ │ ├── index.ts │ │ └── zh-CN.ts │ ├── row │ │ ├── Row.vue │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ └── index.vue │ │ ├── index.ts │ │ ├── props.ts │ │ └── provider.ts │ ├── tag │ │ ├── Tag.vue │ │ ├── docs │ │ │ └── README.md │ │ ├── example │ │ │ └── index.vue │ │ ├── index.ts │ │ └── props.ts │ ├── theme │ │ ├── Cell.less │ │ ├── button.less │ │ ├── card.less │ │ ├── col.less │ │ ├── config-provider.less │ │ ├── css-variables.less │ │ ├── example │ │ │ └── index.vue │ │ ├── image.less │ │ ├── index.less │ │ ├── lazy.less │ │ ├── row.less │ │ ├── tag.less │ │ └── var.less │ └── utils │ │ ├── components.ts │ │ ├── hooks │ │ ├── useChildren.ts │ │ └── useParent.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── types │ ├── button.d.ts │ ├── global.d.ts │ ├── index.d.ts │ └── linComponent.d.ts ├── pnpm-lock.yaml └── pnpm-workspace.yaml /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/.DS_Store -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /lib 2 | /dist/** -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['@lin-ui-vue'], 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | lib/ 4 | es/ -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 15 | 16 | 23 | 24 | 27 | 28 | 35 | 36 | 43 | 44 | 51 | 52 | 57 | 58 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/lin-ui-vue.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/prettier.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | dist/ 3 | 4 | **/package.json 5 | *.md 6 | 7 | pnpm-lock.yaml 8 | pnpm-workspace.yaml 9 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "printWidth": 80, 4 | "semi": false 5 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Lin-UI-Vue 2 | 3 | TODO 4 | 1. 国际化 5 | 2. Icon 6 | 3. 完善 Doc、Demo 7 | 4. commit 校验 8 | 9 | 10 | ## Components 11 | - [ ] Button 12 | - [ ] Icon // TODO 13 | - [ ] Tag 14 | - [ ] Image 15 | - [ ] Row 16 | - [ ] Col 17 | - [ ] Overlay 18 | - [ ] Loading 19 | - [ ] Notify 20 | - [ ] Popup 21 | - [ ] Toast 22 | - [ ] Cell 23 | - [ ] Progress 24 | - [ ] Circle 25 | - [ ] CountTo 26 | - [ ] Steps 27 | - [ ] Divider 28 | - [ ] Empty 29 | - [ ] Badge -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'type-enum': [ 5 | 2, 6 | 'always', 7 | ['feat', 'fix', 'refactor', 'test', 'build', 'docs', 'style', 'revert'], 8 | ], 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lin-ui-vue", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "lin-ui-vue", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lin-ui-vue", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "prepare": "husky install" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/TaleLin/lin-ui-vue.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/TaleLin/lin-ui-vue/issues" 19 | }, 20 | "homepage": "https://github.com/TaleLin/lin-ui-vue#readme", 21 | "devDependencies": { 22 | "@commitlint/cli": "^17.0.3", 23 | "@commitlint/config-conventional": "^17.0.3", 24 | "@lin-ui-vue/eslint-config": "workspace:*", 25 | "eslint": "^8.17.0", 26 | "husky": "^8.0.0", 27 | "lint-staged": "^13.0.3", 28 | "prettier": "^2.7.0", 29 | "typescript": "^4.7.3" 30 | }, 31 | "lint-staged": { 32 | "*.js": "eslint" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/.DS_Store -------------------------------------------------------------------------------- /packages/cli/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['@lin-ui-vue'], 4 | } 5 | -------------------------------------------------------------------------------- /packages/cli/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "printWidth": 80, 4 | "semi": false 5 | } -------------------------------------------------------------------------------- /packages/cli/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lin-ui-vue/cli", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@lin-ui-vue/cli", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "typescript": "^4.7.3" 13 | } 14 | }, 15 | "node_modules/typescript": { 16 | "version": "4.7.3", 17 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", 18 | "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", 19 | "dev": true, 20 | "bin": { 21 | "tsc": "bin/tsc", 22 | "tsserver": "bin/tsserver" 23 | }, 24 | "engines": { 25 | "node": ">=4.2.0" 26 | } 27 | } 28 | }, 29 | "dependencies": { 30 | "typescript": { 31 | "version": "4.7.3", 32 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", 33 | "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", 34 | "dev": true 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lin-ui-vue/cli", 3 | "version": "0.0.1", 4 | "description": "", 5 | "scripts": { 6 | "dev": "tsc --watch" 7 | }, 8 | "bin": { 9 | "lin-ui-cli": "./lib/index.js" 10 | }, 11 | "files": [ 12 | "lib", 13 | "tsconfig.json" 14 | ], 15 | "keywords": [], 16 | "author": "", 17 | "license": "ISC", 18 | "devDependencies": { 19 | "@types/ejs": "^3.1.1", 20 | "@types/fs-extra": "^9.0.13", 21 | "@types/glob": "^7.2.0", 22 | "@types/gulp": "^4.0.9", 23 | "@types/inquirer": "^8.2.1", 24 | "@types/node": "^17.0.41", 25 | "rollup": "^2.75.7", 26 | "rollup-plugin-vue": "^6.0.0", 27 | "typescript": "^4.7.3", 28 | "vue-tsc": "^0.34.7" 29 | }, 30 | "dependencies": { 31 | "@lin-ui-vue/eslint-config": "workspace:*", 32 | "@lin-ui-vue/markdown-to-vue": "workspace:*", 33 | "@vitejs/plugin-vue": "^2.3.3", 34 | "@vitejs/plugin-vue-jsx": "^1.3.10", 35 | "@vue/compiler-sfc": "^3.2.37", 36 | "chalk": "^4.1.0", 37 | "chokidar": "^3.5.3", 38 | "commander": "^9.3.0", 39 | "ejs": "^3.1.8", 40 | "fs-extra": "^10.1.0", 41 | "glob": "^8.0.3", 42 | "gray-matter": "^4.0.3", 43 | "gulp": "^4.0.2", 44 | "gulp-cli": "^2.3.0", 45 | "inquirer": "^8.2.4", 46 | "ora": "^6.1.0", 47 | "rollup-plugin-typescript2": "^0.32.1", 48 | "semver": "^7.3.7", 49 | "vite": "^2.9.9", 50 | "vue": "^3.2.25" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /packages/cli/src/commands/build.ts: -------------------------------------------------------------------------------- 1 | import { build } from 'vite' 2 | import { viteBuildConfig } from '../config/vite.config' 3 | import { generateTypes, generateReference } from '../generate/generateTypes' 4 | 5 | export async function buildApp() { 6 | await generateTypes() 7 | await build(viteBuildConfig) 8 | await generateReference('dist') 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/src/commands/compile.ts: -------------------------------------------------------------------------------- 1 | import { rollup } from 'rollup' 2 | import { resolve } from 'path' 3 | import vuePlugin from 'rollup-plugin-vue' 4 | import typescript from 'rollup-plugin-typescript2' 5 | import { readdirSync } from 'fs-extra' 6 | import { isTS, isSFC, isDir, replaceExt } from '../utils/index' 7 | import { CWD, UI_DOCS_DIR, UI_SRC_DIR, UI_EXAMPLE_DIR } from '../constant/index' 8 | 9 | function getComponentEntry() { 10 | const moduleDirs = readdirSync(UI_SRC_DIR) 11 | 12 | const res = moduleDirs.map((fileName: string) => { 13 | const file = resolve(UI_SRC_DIR, fileName) 14 | return isDir(file) ? compileDir(file) : null 15 | }) 16 | 17 | const input = res 18 | .flat(Infinity) 19 | .map((item) => item.replace(`${UI_SRC_DIR}/`, '')) 20 | 21 | return input.reduce((prev, current) => { 22 | prev[replaceExt(current, '')] = resolve(UI_SRC_DIR, current) 23 | return prev 24 | }, {}) 25 | } 26 | function compileDir(dir: string): any { 27 | const dirs = readdirSync(dir).filter( 28 | (item) => ![UI_DOCS_DIR, UI_EXAMPLE_DIR].includes(item) 29 | ) 30 | return dirs 31 | .map((fileName: string) => { 32 | const file = resolve(dir, fileName) 33 | return compileFile(file) 34 | }) 35 | .filter((_) => _) 36 | } 37 | 38 | export function compileFile(file: string): any { 39 | if (isSFC(file)) return file 40 | if (isTS(file)) return file 41 | if (isDir(file)) return compileDir(file) 42 | 43 | return null 44 | } 45 | 46 | async function build() { 47 | const componentEntry = getComponentEntry() 48 | 49 | const bundle = await rollup({ 50 | input: { 51 | index: resolve(CWD, 'index.ts'), 52 | ...componentEntry, 53 | }, 54 | plugins: [vuePlugin(), typescript()], 55 | external: ['vue'], 56 | }) 57 | await bundle.write({ 58 | dir: 'lib', 59 | format: 'cjs', 60 | exports: 'named', 61 | }) 62 | await bundle.write({ 63 | dir: 'es', 64 | format: 'esm', 65 | exports: 'named', 66 | }) 67 | } 68 | 69 | export async function compile() { 70 | await build() 71 | } 72 | -------------------------------------------------------------------------------- /packages/cli/src/commands/create.ts: -------------------------------------------------------------------------------- 1 | import ejs from 'ejs' 2 | import fs from 'fs-extra' 3 | import { resolve } from 'path' 4 | import inquirer from 'inquirer' 5 | import { UI_COMPONENTS_DIR } from '../constant/index' 6 | import { addComponent } from '../utils/component' 7 | import { bigCamel } from '../utils' 8 | import { generateUIDoc } from '../generate/generateAppConfig' 9 | import { 10 | ComponentTemplateEjs, 11 | ComponentLessEjs, 12 | ComponentIndexEjs, 13 | ComponentPropsEjs, 14 | ComponentDocsEjs, 15 | ComponentExampleEjs, 16 | ComponentDir, 17 | } from '../constant' 18 | import { generateEntry } from '../generate/generateEntry' 19 | import logger from '../utils/logger' 20 | 21 | function generateComponentVue(name: string, outputPath: string) { 22 | const res = fs.readFileSync(ComponentTemplateEjs) 23 | const content = ejs.render(res.toString(), { 24 | name, 25 | bigCamelName: bigCamel(name), 26 | }) 27 | fs.writeFileSync(resolve(outputPath, `${bigCamel(name)}.vue`), content) 28 | } 29 | 30 | function generateComponentLess(name: string, outputPath: string) { 31 | const res = fs.readFileSync(ComponentLessEjs) 32 | const content = ejs.render(res.toString(), { name }) 33 | fs.writeFileSync(resolve(UI_COMPONENTS_DIR, `theme/${name}.less`), content) 34 | } 35 | 36 | function generateComponentIndex(name: string, outputPath: string) { 37 | const res = fs.readFileSync(ComponentIndexEjs) 38 | const content = ejs.render(res.toString(), { 39 | name, 40 | bigCamelName: bigCamel(name), 41 | }) 42 | fs.writeFileSync(resolve(outputPath, `index.ts`), content) 43 | } 44 | 45 | function generateComponentProps(name: string, outputPath: string) { 46 | const res = fs.readFileSync(ComponentPropsEjs) 47 | const content = ejs.render(res.toString()) 48 | fs.writeFileSync(resolve(outputPath, `props.ts`), content) 49 | } 50 | 51 | function generateComponentDocs( 52 | name: string, 53 | cnName: string, 54 | outputPath: string 55 | ) { 56 | const res = fs.readFileSync(ComponentDocsEjs) 57 | const content = ejs.render(res.toString(), { name, cnName }) 58 | fs.ensureDirSync(resolve(outputPath, 'docs')) 59 | fs.writeFileSync(resolve(outputPath, `docs/README.md`), content) 60 | } 61 | 62 | function generateComponentExample(name: string, outputPath: string) { 63 | const res = fs.readFileSync(ComponentExampleEjs) 64 | const content = ejs.render(res.toString(), { name }) 65 | fs.ensureDirSync(resolve(outputPath, 'example')) 66 | fs.writeFileSync(resolve(outputPath, `example/index.vue`), content) 67 | } 68 | 69 | function appendComponentList(name: string) { 70 | addComponent(name) 71 | } 72 | 73 | function generateLessEntry(name: string) { 74 | const less = fs 75 | .readFileSync(resolve(UI_COMPONENTS_DIR, 'theme/index.less')) 76 | .toString() 77 | const appendLess = `@import './${name}.less';` 78 | if (less.includes(appendLess)) { 79 | return 80 | } 81 | fs.writeFileSync( 82 | resolve(UI_COMPONENTS_DIR, 'theme/index.less'), 83 | `${less.toString()}\n${appendLess}` 84 | ) 85 | } 86 | 87 | export async function create(name: string, cnName: string) { 88 | name = name.replace(name.charAt(0), name.charAt(0).toLowerCase()) // confirm name smallCamel 89 | const outputPath = ComponentDir(name) 90 | 91 | if (fs.pathExistsSync(outputPath)) { 92 | const { cover } = await inquirer.prompt([ 93 | { 94 | type: 'confirm', 95 | name: 'cover', 96 | message: '该组件文件目录已存在,是否要覆盖?', 97 | default: false, 98 | }, 99 | ]) 100 | if (!cover) { 101 | process.exit(1) 102 | } 103 | const { confirm } = await inquirer.prompt([ 104 | { 105 | type: 'confirm', 106 | name: 'confirm', 107 | message: '覆盖组件将重置为初始化组件模板,是否确定要覆盖?', 108 | default: false, 109 | }, 110 | ]) 111 | if (!confirm) { 112 | process.exit(1) 113 | } 114 | 115 | fs.emptyDirSync(outputPath) 116 | } 117 | 118 | if (!cnName) { 119 | const { inputCnName } = await inquirer.prompt([ 120 | { 121 | type: 'input', 122 | name: 'inputCnName', 123 | message: '请输入组件的中文名', 124 | default: '', 125 | validate(value) { 126 | return !!value 127 | }, 128 | }, 129 | ]) 130 | cnName = inputCnName 131 | } 132 | 133 | generateLessEntry(name) 134 | 135 | fs.ensureDirSync(outputPath) 136 | generateComponentVue(name, outputPath) 137 | generateComponentLess(name, outputPath) 138 | generateComponentIndex(name, outputPath) 139 | generateComponentProps(name, outputPath) 140 | generateComponentDocs(name, cnName, outputPath) 141 | generateComponentExample(name, outputPath) 142 | appendComponentList(name) 143 | generateUIDoc() 144 | generateEntry() 145 | generateLessEntry(name) 146 | 147 | logger.success(`组件 ${name} 创建成功!`) 148 | logger.success(`组件 ${name} 文件目录: src/${name}`) 149 | logger.success(`|- docs/ # 组件文档`) 150 | logger.success(`|- demo/ # 组件使用案例`) 151 | logger.success(`|- ${name}.vue/ # Vue 组件`) 152 | logger.success(`|- index.ts/ # 组件入口文件`) 153 | } 154 | -------------------------------------------------------------------------------- /packages/cli/src/commands/dev.ts: -------------------------------------------------------------------------------- 1 | import { createServer, ViteDevServer } from 'vite' 2 | import { ensureUIConfig } from '../utils/component' 3 | import { generateUIDoc } from '../generate/generateAppConfig' 4 | import { generateEntry } from '../generate/generateEntry' 5 | import { viteConfig } from '../config/vite.config' 6 | 7 | let server: ViteDevServer 8 | 9 | async function startServer(cmd: { simple: boolean }) { 10 | const { simple } = cmd 11 | server && (await server.close()) 12 | 13 | if (!simple) { 14 | ensureUIConfig() 15 | await generateUIDoc() 16 | await generateEntry() 17 | } 18 | 19 | server = await createServer(viteConfig) 20 | 21 | await server.listen() 22 | server.printUrls() 23 | } 24 | 25 | export async function dev(cmd: { simple: boolean }) { 26 | process.env.NODE_ENV = 'development' 27 | await startServer(cmd) 28 | } 29 | -------------------------------------------------------------------------------- /packages/cli/src/config/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import path from 'path' 3 | import md from '@lin-ui-vue/markdown-to-vue' 4 | import vueJsx from '@vitejs/plugin-vue-jsx' 5 | 6 | export const viteConfig = { 7 | root: path.resolve(__dirname, '../../../ui/site'), 8 | // configFile: false, 9 | plugins: [ 10 | vue({ 11 | include: [/\.vue$/, /\.md$/], 12 | }), 13 | vueJsx(), 14 | md(), 15 | ], 16 | server: { force: true, port: 9527 }, 17 | } 18 | 19 | export const viteBuildConfig = { 20 | root: path.resolve(__dirname, '../../../ui/site'), 21 | publicDir: 'false', 22 | plugins: [ 23 | vue({ 24 | include: [/\.vue$/, /\.md$/], 25 | }), 26 | vueJsx(), 27 | md(), 28 | ], 29 | build: { 30 | // base: './', 31 | outDir: path.resolve(__dirname, '../../../ui/dist'), 32 | // brotliSize: false, 33 | emptyOutDir: true, 34 | cssTarget: 'chrome61', 35 | rollupOptions: { 36 | external: ['vue'], 37 | output: { 38 | globals: { 39 | vue: 'vue', 40 | }, 41 | }, 42 | }, 43 | lib: { 44 | entry: path.resolve(process.cwd(), 'index.ts'), 45 | name: '@lin-ui-vue/ui', // umd的变量名 46 | fileName: (format: string) => `index.${format}.js`, // 输出文件名 47 | }, 48 | }, 49 | } 50 | -------------------------------------------------------------------------------- /packages/cli/src/constant/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | 3 | export const UI_NAME = 'lin-ui-vue' 4 | 5 | export const CWD = process.cwd() 6 | 7 | export const UI_CONFIG_DIR = resolve(CWD, `.${UI_NAME}`) 8 | 9 | export const EJS = resolve(__dirname, '../../template') 10 | 11 | export const ComponentTemplateEjs = resolve(EJS, 'component/component.vue.ejs') 12 | 13 | export const ComponentLessEjs = resolve(EJS, 'component/component.less.ejs') 14 | 15 | export const ComponentIndexEjs = resolve(EJS, 'component/index.ejs') 16 | 17 | export const ComponentPropsEjs = resolve(EJS, 'component/props.ejs') 18 | 19 | export const ComponentExampleEjs = resolve(EJS, 'component/example/index.ejs') 20 | 21 | export const ComponentDocsEjs = resolve(EJS, 'component/docs/README.ejs') 22 | 23 | export const ComponentDir = (componentName: string) => 24 | resolve(CWD, `src/${componentName}`) 25 | 26 | export const UI_TYPES_DIR = resolve(CWD, 'types') 27 | export const UI_PACKAGE_JSON = resolve(CWD, 'package.json') 28 | 29 | export const UI_SRC_DIR = resolve(CWD, 'src') 30 | export const UI_LIB_DIR = resolve(CWD, 'lib') 31 | export const UI_ES_DIR = resolve(CWD, 'es') 32 | export const UI_EXAMPLE_DIR = 'example' 33 | export const UI_DOCS_DIR = 'docs' 34 | 35 | export const UI_BASE_DOC_DIR = resolve(CWD, 'site/docs') 36 | export const UI_COMPONENTS_DIR = resolve(CWD, 'src') 37 | -------------------------------------------------------------------------------- /packages/cli/src/generate/generateAppConfig.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import matter from 'gray-matter' 3 | import fs, { pathExistsSync } from 'fs-extra' 4 | import { UI_COMPONENTS_DIR, UI_BASE_DOC_DIR, CWD } from '../constant/index' 5 | import globSync from '../utils/glob' 6 | import { isComponentDir } from '../utils/component' 7 | 8 | export async function getBaseDoc() { 9 | const files = await globSync(`${UI_BASE_DOC_DIR}/*.md`) 10 | return files 11 | } 12 | 13 | export async function getComponentsDoc() { 14 | const files = await globSync(`${UI_COMPONENTS_DIR}/**/*.md`) 15 | return files 16 | } 17 | 18 | function getRouteConfig(docPath: string) { 19 | const docContent = fs.readFileSync(docPath).toString() 20 | const { data } = matter(docContent) 21 | let { routePath } = data 22 | if (!routePath) { 23 | const [, _] = docPath.match(/\/docs\/([-\w]+)\.md/) || [] 24 | routePath = `/${_}` 25 | } 26 | 27 | return { 28 | path: `${routePath.toLowerCase()}`, 29 | meta: { 30 | parent: data.parent, 31 | }, 32 | } 33 | } 34 | 35 | function getMenuConfig(docPath: string) { 36 | const docContent = fs.readFileSync(docPath).toString() 37 | const { data } = matter(docContent) 38 | return data 39 | } 40 | 41 | function generatePCRoutes(routes: string[]) { 42 | const baseDocsRoutes = routes.map((docPath) => { 43 | const { path, meta } = getRouteConfig(docPath) 44 | return ` 45 | { 46 | path: '${path}', 47 | // eslint-disable-next-line prettier/prettier 48 | component: () => import('${docPath}'), 49 | meta: { 50 | parent: '${meta.parent}', 51 | }, 52 | }` 53 | }) 54 | 55 | const source = `export default [${baseDocsRoutes}, 56 | ] 57 | ` 58 | const configPath = resolve(process.cwd(), 'site/pc/route.ts') 59 | fs.outputFileSync(configPath, source) 60 | } 61 | 62 | function generateMobileRoutes() { 63 | const dirs = fs 64 | .readdirSync(UI_COMPONENTS_DIR) 65 | .filter((dir) => isComponentDir(dir)) 66 | 67 | const componentDocsRoutes: string[] = [] 68 | 69 | dirs.forEach((dir) => { 70 | const path = resolve(UI_COMPONENTS_DIR, `${dir}/example/index.vue`) 71 | if (pathExistsSync(path)) { 72 | componentDocsRoutes.push(`{ 73 | path: '/${dir}', 74 | // eslint-disable-next-line prettier/prettier 75 | component: () => import('${path}') 76 | }`) 77 | } 78 | }) 79 | 80 | const source = `export default [ 81 | ${componentDocsRoutes.join(',\n ')}, 82 | ] 83 | ` 84 | const configPath = resolve(process.cwd(), 'site/mobile/route.ts') 85 | fs.outputFileSync(configPath, source) 86 | } 87 | 88 | function formatMenuGroup(list: any[]) { 89 | const menuGroup: Record = {} 90 | for (let i = 0; i < list.length; i++) { 91 | const { parent } = list[i] 92 | if (parent) { 93 | if (!menuGroup[parent]) { 94 | menuGroup[parent] = [] 95 | } 96 | menuGroup[parent].push(list[i]) 97 | } 98 | } 99 | // eslint-disable-next-line no-restricted-syntax, guard-for-in 100 | for (const key in menuGroup) { 101 | menuGroup[key] = menuGroup[key].sort((a, b) => a.order - b.order) 102 | } 103 | return menuGroup 104 | } 105 | 106 | function generateAppMenu(docs: string[]) { 107 | const menuList = docs.map((item) => { 108 | const { title, order, routePath, parent } = getMenuConfig(item) 109 | return { 110 | title, 111 | order, 112 | routePath, 113 | parent, 114 | } 115 | }) 116 | const configPath = resolve(CWD, 'site/pc/menu.json') 117 | fs.writeJSONSync(configPath, formatMenuGroup(menuList), { spaces: 2 }) 118 | } 119 | 120 | export async function generateUIDoc() { 121 | const baseDocFile = await getBaseDoc() 122 | const componentsDocFile = await getComponentsDoc() 123 | 124 | generatePCRoutes([...baseDocFile, ...componentsDocFile]) 125 | generateAppMenu([...baseDocFile, ...componentsDocFile]) 126 | generateMobileRoutes() 127 | } 128 | -------------------------------------------------------------------------------- /packages/cli/src/generate/generateEntry.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs-extra' 2 | import path from 'path' 3 | import { UI_COMPONENTS_DIR } from '../constant/index' 4 | import { bigCamel } from '../utils/index' 5 | import { isComponentDir } from '../utils/component' 6 | 7 | export function generateEntry() { 8 | const importComponents: string[] = [] 9 | const components: string[] = [] 10 | let dirs = fs.readdirSync(UI_COMPONENTS_DIR) 11 | dirs = dirs.filter((item) => isComponentDir(item)) 12 | dirs.forEach((dir) => { 13 | const componentName = bigCamel(dir) 14 | components.push(componentName) 15 | importComponents.push(`import ${componentName} from './src/${dir}/index'`) 16 | }) 17 | 18 | const componentsArr = ` 19 | // eslint-disable-next-line prettier/prettier 20 | const components = [ 21 | ${components.join(',\n ')} 22 | ]` 23 | 24 | const install = ` 25 | function install(app: any) { 26 | components.forEach((component) => { 27 | app.use(component) 28 | }) 29 | }` 30 | 31 | const entryContent = `${importComponents.join('\n')} 32 | ${componentsArr} 33 | ${install} 34 | 35 | export default { 36 | install, 37 | ${components.join(',\n ')}, 38 | } 39 | ` 40 | 41 | fs.writeFileSync( 42 | path.resolve(process.cwd(), 'index.ts'), 43 | entryContent, 44 | 'utf-8' 45 | ) 46 | } 47 | -------------------------------------------------------------------------------- /packages/cli/src/generate/generateTypes.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs-extra' 2 | import path from 'path' 3 | import { CWD, UI_TYPES_DIR, UI_PACKAGE_JSON } from '../constant/index' 4 | import { bigCamel } from '../utils' 5 | 6 | export function generateReference(moduleDir: string) { 7 | const outputDir = path.resolve(CWD, moduleDir) 8 | fs.writeFileSync( 9 | path.resolve(outputDir, 'index.d.ts'), 10 | `export * from '${path.relative(outputDir, UI_TYPES_DIR)}'\n` 11 | ) 12 | } 13 | 14 | export async function generateTypes() { 15 | const { name } = require(UI_PACKAGE_JSON) 16 | fs.ensureDirSync(UI_TYPES_DIR) 17 | 18 | const dir = await fs.readdir(UI_TYPES_DIR) 19 | const ignoreEntryDir = dir.filter( 20 | (filename) => filename !== 'index.d.ts' && filename !== 'global.d.ts' 21 | ) 22 | const exports: string[] = [] 23 | const declares: string[] = [] 24 | 25 | ignoreEntryDir.forEach((filename) => { 26 | const componentName = filename.slice(0, filename.indexOf('.d.ts')) 27 | 28 | exports.push(`export * from './${componentName}'`) 29 | 30 | if (!componentName.startsWith('lin')) { 31 | declares.push( 32 | `${bigCamel('lin')}${bigCamel( 33 | componentName 34 | )}: typeof import('${name}')['_${bigCamel(componentName)}Component']` 35 | ) 36 | } 37 | }) 38 | 39 | const template = `\ 40 | import type { App } from 'vue' 41 | 42 | export const install: (app: App) => void 43 | 44 | ${exports.join('\n')} 45 | ` 46 | 47 | const globalTemplate = `\ 48 | declare module 'vue' { 49 | export interface GlobalComponents { 50 | ${declares.join('\n ')} 51 | } 52 | } 53 | 54 | export {} 55 | ` 56 | fs.writeFileSync(path.resolve(UI_TYPES_DIR, 'index.d.ts'), template) 57 | fs.writeFileSync(path.resolve(UI_TYPES_DIR, 'global.d.ts'), globalTemplate) 58 | } 59 | -------------------------------------------------------------------------------- /packages/cli/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { Command } from 'commander' 3 | import { dev } from './commands/dev' 4 | import { create } from './commands/create' 5 | import { buildApp } from './commands/build' 6 | import { compile } from './commands/compile' 7 | 8 | const program = new Command() 9 | 10 | program 11 | // eslint-disable-next-line global-require 12 | .version(`lin-vue-cli ${require('../package.json').version}`) 13 | .usage(' [options]') 14 | 15 | program 16 | .command('dev') 17 | .description('Run dev') 18 | .option('-s,--simple', 'only start sever, not create config ') 19 | .action(dev) 20 | 21 | program 22 | .command('create [cnName]') 23 | .option('-s,--simple', 'only start sever, not create config ') 24 | .description('Create Component') 25 | .action(create) 26 | 27 | program.command('build').description('Run build').action(buildApp) 28 | 29 | program.command('compile').description('Run compile').action(compile) 30 | 31 | program.parse() 32 | -------------------------------------------------------------------------------- /packages/cli/src/module.d.ts: -------------------------------------------------------------------------------- 1 | // declare module 'inquirer' 2 | // declare module '@babel/helper-plugin-utils' 3 | declare module '@lin-ui-vue/markdown-to-vue' 4 | // declare module 'conventional-changelog' 5 | -------------------------------------------------------------------------------- /packages/cli/src/utils/component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | pathExistsSync, 3 | ensureDirSync, 4 | readdirSync, 5 | writeJSONSync, 6 | readJSONSync, 7 | } from 'fs-extra' 8 | import { resolve } from 'path' 9 | import { UI_CONFIG_DIR, UI_SRC_DIR } from '../constant' 10 | 11 | const componentsPath = resolve(UI_CONFIG_DIR, 'components.json') 12 | 13 | export const ensureUIConfig = () => { 14 | if (!pathExistsSync(UI_CONFIG_DIR)) { 15 | ensureDirSync(UI_CONFIG_DIR) 16 | } 17 | if (!pathExistsSync(componentsPath)) { 18 | cacheComponentList() 19 | } 20 | } 21 | 22 | export const cacheComponentList = () => { 23 | const filterDirs = ['theme', 'utils'] 24 | const list = readdirSync(UI_SRC_DIR).filter( 25 | (item) => !filterDirs.includes(item) 26 | ) 27 | writeJSONSync(componentsPath, list, { spaces: 2 }) 28 | } 29 | 30 | export const getComponentList = () => { 31 | const list = readJSONSync(componentsPath) 32 | return list 33 | } 34 | 35 | export const isComponentDir = (dir: string) => { 36 | return getComponentList().includes(dir) 37 | } 38 | 39 | export const addComponent = (name: string) => { 40 | ensureUIConfig() 41 | if (isComponentDir(name)) { 42 | return 43 | } 44 | const list = getComponentList() 45 | writeJSONSync(componentsPath, [...list, name], { spaces: 2 }) 46 | } 47 | -------------------------------------------------------------------------------- /packages/cli/src/utils/glob.ts: -------------------------------------------------------------------------------- 1 | import glob from 'glob' 2 | 3 | export default function (pattern: string): Promise { 4 | return new Promise((resolve, reject) => { 5 | glob(pattern, (error, files) => { 6 | if (error) { 7 | reject(error) 8 | } else { 9 | resolve(files) 10 | } 11 | }) 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /packages/cli/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | appendFileSync, 3 | lstatSync, 4 | pathExistsSync, 5 | readFileSync, 6 | } from 'fs-extra' 7 | import { extname } from 'path' 8 | 9 | export const replaceExt = (file: string, ext: string): string => 10 | file.replace(extname(file), ext) 11 | 12 | export function smallCamel(str: string, separator: '-' | '_' = '-') { 13 | const reg = new RegExp(`${separator}([a-z])`, 'g') 14 | return str.replace(reg, (p, m) => m.toUpperCase()) 15 | } 16 | 17 | export function bigCamel(str: string, separator: '-' | '_' = '-') { 18 | const s = smallCamel(str, separator) 19 | return s.replace(s.charAt(0), s.charAt(0).toUpperCase()) 20 | } 21 | 22 | export const isDir = (file: string): boolean => 23 | pathExistsSync(file) && lstatSync(file).isDirectory() 24 | 25 | export const isFileType = (file: string, ext: 'less' | 'ts' | 'vue') => { 26 | return pathExistsSync(file) && extname(file) === `.${ext}` 27 | } 28 | 29 | export const isSFC = (file: string): boolean => isFileType(file, 'vue') 30 | 31 | export const isTS = (file: string): boolean => isFileType(file, 'ts') 32 | 33 | export const isLess = (file: string): boolean => isFileType(file, 'less') 34 | 35 | export function smartAppendFileSync(file: string, code: string) { 36 | if (pathExistsSync(file)) { 37 | const content = readFileSync(file, 'utf-8') 38 | 39 | if (!content.includes(code)) { 40 | appendFileSync(file, code) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/cli/src/utils/logger.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk' 2 | 3 | export default { 4 | info(text: string) { 5 | console.log(text) 6 | }, 7 | success(text: string) { 8 | console.log(chalk.hex('#00c48f')(text)) 9 | }, 10 | warning(text: string) { 11 | console.log(chalk.hex('#ff9800')(text)) 12 | }, 13 | error(text: string) { 14 | console.log(chalk.hex('#F2242E')(text)) 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /packages/cli/template/component/component.less.ejs: -------------------------------------------------------------------------------- 1 | .lin-<%=name %>{} -------------------------------------------------------------------------------- /packages/cli/template/component/component.vue.ejs: -------------------------------------------------------------------------------- 1 | 4 | 5 | 23 | -------------------------------------------------------------------------------- /packages/cli/template/component/docs/README.ejs: -------------------------------------------------------------------------------- 1 | --- 2 | title: <%=name %> <%=cnName %> 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/<%=name %>' 7 | --- 8 | 9 | # <%=name %> <%=cnName %> 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | ### Title-1 13 | 14 | 使用介绍 15 | 16 | ```html 17 | 22 | ``` -------------------------------------------------------------------------------- /packages/cli/template/component/example/index.ejs: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/cli/template/component/index.ejs: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import <%=bigCamelName %> from './<%=bigCamelName %>.vue' 3 | 4 | <%=bigCamelName %>.install = function (app: App) { 5 | app.component(<%=bigCamelName %>.name, <%=bigCamelName %>) 6 | } 7 | 8 | export default <%=bigCamelName %> 9 | -------------------------------------------------------------------------------- /packages/cli/template/component/props.ejs: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue' 2 | 3 | export const propsDefine = {} 4 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./lib", 4 | "target": "es5", 5 | "strict": true, 6 | "downlevelIteration": true, 7 | "declaration": true, 8 | "skipLibCheck": true, 9 | "esModuleInterop": true, 10 | "jsx": "preserve", 11 | "lib": ["esnext", "dom"] 12 | }, 13 | "include": ["src/**/*"] 14 | } -------------------------------------------------------------------------------- /packages/eslint-config/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true, 6 | }, 7 | parser: 'vue-eslint-parser', 8 | extends: [ 9 | 'plugin:vue/vue3-recommended', 10 | 'airbnb-base', 11 | 'plugin:@typescript-eslint/recommended', 12 | 'plugin:prettier/recommended', 13 | ], 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | parser: '@typescript-eslint/parser', 17 | sourceType: 'module', 18 | extraFileExtensions: ['.vue'], 19 | }, 20 | plugins: ['@typescript-eslint', 'prettier'], 21 | rules: { 22 | 'no-shadow': 'off', 23 | 'no-console': 'off', 24 | 'no-plusplus': 'off', 25 | 'func-names': 'off', 26 | 'max-classes-per-file': 'off', 27 | 'import/prefer-default-export': 'off', 28 | 'import/extensions': 'off', 29 | 'import/no-unresolved': 'off', 30 | 'import/no-absolute-path': 'off', 31 | 'import/no-extraneous-dependencies': 'off', 32 | 'no-unused-expressions': 'off', 33 | '@typescript-eslint/no-var-requires': 'off', 34 | 'vue/multi-word-component-names': 'off', 35 | '@typescript-eslint/no-empty-interface': 'off', 36 | 'no-param-reassign': 'off', 37 | 'no-underscore-dangle': 'off', 38 | 'import/no-dynamic-require': 'off', 39 | 'global-require': 'off', 40 | 'no-use-before-define': 'off', 41 | }, 42 | } 43 | -------------------------------------------------------------------------------- /packages/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lin-ui-vue/eslint-config", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@typescript-eslint/eslint-plugin": "^5.28.0", 14 | "@typescript-eslint/parser": "^5.28.0", 15 | "eslint-config-airbnb-base": "^15.0.0", 16 | "eslint-config-prettier": "^8.5.0", 17 | "eslint-plugin-import": "^2.26.0", 18 | "eslint-plugin-prettier": "^4.0.0", 19 | "eslint-plugin-vue": "^9.1.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/icons/.pnpm-debug.log: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /packages/icons/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": "current" 8 | } 9 | } 10 | ], 11 | "@babel/preset-typescript" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/icons/components/Icon.jsx: -------------------------------------------------------------------------------- 1 | import { h, defineComponent } from 'vue' 2 | import './icon.less' 3 | 4 | const generateVNode = (node, key) => { 5 | return h( 6 | node.tag, 7 | { key, ...node.attrs }, 8 | (node.children || []).map((child, index) => 9 | generateVNode(child, `${key}-${child.tag}- ${index}`) 10 | ) 11 | ) 12 | } 13 | 14 | const Icon = defineComponent({ 15 | props: { 16 | icon: { 17 | type: Object, 18 | default: () => null, 19 | }, 20 | primaryColor: { 21 | type: String, 22 | default: '#4D82FF', 23 | }, 24 | secondColor: { 25 | type: String, 26 | default: '#e6f7ff', 27 | }, 28 | }, 29 | render({ icon, primaryColor, secondColor }) { 30 | let { vNode } = icon 31 | 32 | if (typeof vNode === 'function') { 33 | vNode = vNode(primaryColor, secondColor) 34 | } 35 | 36 | const { attrs } = vNode 37 | const renderVNode = { 38 | ...vNode, 39 | attrs: { ...attrs, fill: 'currentColor', width: '1em', height: '1em' }, 40 | } 41 | return ( 42 | 43 | {icon && generateVNode(renderVNode, icon.name)} 44 | 45 | ) 46 | }, 47 | }) 48 | 49 | export default Icon 50 | -------------------------------------------------------------------------------- /packages/icons/components/icon.less: -------------------------------------------------------------------------------- 1 | .lin-icon { 2 | display: inline-block; 3 | line-height: 0; 4 | font-size: 32px; 5 | svg { 6 | display: inline-block; 7 | } 8 | } -------------------------------------------------------------------------------- /packages/icons/example/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | 22 | -------------------------------------------------------------------------------- /packages/icons/example/components/IconDemo.tsx: -------------------------------------------------------------------------------- 1 | import { h, defineComponent } from 'vue' 2 | import AccountBookFilled from '../../src/components/AccountBookFilled.jsx' 3 | import AccountBookOutlined from '../../src/components/AccountBookOutlined.jsx' 4 | import AccountBookTwoTone from '../../src/components/AccountBookTwoTone.jsx' 5 | import AlertFilled from '../../src/components/AlertFilled.jsx' 6 | import AlertOutlined from '../../src/components/AlertOutlined.jsx' 7 | import AlertTwoTone from '../../src/components/AlertTwoTone.jsx' 8 | import ApiFilled from '../../src/components/ApiFilled.jsx' 9 | import ApiOutlined from '../../src/components/ApiOutlined.jsx' 10 | import ApiTwoTone from '../../src/components/ApiTwoTone.jsx' 11 | import BookFilled from '../../src/components/BookFilled.jsx' 12 | import BookOutlined from '../../src/components/BookOutlined.jsx' 13 | import BookTwoTone from '../../src/components/BookTwoTone.jsx' 14 | 15 | const IconDemo = defineComponent({ 16 | render() { 17 | return ( 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | ) 33 | }, 34 | }) 35 | export default IconDemo 36 | -------------------------------------------------------------------------------- /packages/icons/example/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 6 | const component: DefineComponent<{}, {}, any> 7 | export default component 8 | } 9 | -------------------------------------------------------------------------------- /packages/icons/example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/icons/example/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | const app = createApp(App) 5 | 6 | app.mount('#app') 7 | -------------------------------------------------------------------------------- /packages/icons/gulpfile.ts: -------------------------------------------------------------------------------- 1 | import { series, parallel } from 'gulp' 2 | import { clean } from './tasks/clean' 3 | import { generateIcons } from './tasks/generateIcons' 4 | 5 | export default series( 6 | clean(['src/asn']), 7 | parallel( 8 | generateIcons({ 9 | theme: 'filled', 10 | from: ['svg/filled/*.svg'], 11 | toDir: 'src/asn', 12 | }), 13 | generateIcons({ 14 | theme: 'outlined', 15 | from: ['svg/outlined/*.svg'], 16 | toDir: 'src/asn', 17 | }), 18 | generateIcons({ 19 | theme: 'twoTone', 20 | from: ['svg/twoTone/*.svg'], 21 | toDir: 'src/asn', 22 | }) 23 | ) 24 | ) 25 | -------------------------------------------------------------------------------- /packages/icons/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lin-ui-vue/icons", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "node ./scripts/example.js", 9 | "generate": "gulp --require ts-node/register/transpile-only", 10 | "generate:components": "ts-node ./scripts/generateComponents.ts" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@types/gulp": "^4.0.9", 17 | "@types/gulp-rename": "^2.0.1", 18 | "@types/lodash.template": "^4.5.1", 19 | "@types/node": "^17.0.41", 20 | "@types/ramda": "^0.28.14", 21 | "@types/rgrove__parse-xml": "^1.1.2", 22 | "@types/through2": "^2.0.36", 23 | "@vitejs/plugin-vue": "^2.3.3", 24 | "@vitejs/plugin-vue-jsx": "^1.3.10", 25 | "vite": "^2.9.9", 26 | "vue": "^3.2.25" 27 | }, 28 | "devDependencies": { 29 | "@babel/core": "^7.18.5", 30 | "@babel/preset-env": "^7.18.2", 31 | "@babel/preset-typescript": "^7.17.12", 32 | "@rgrove/parse-xml": "^2.0.2", 33 | "@types/fs-extra": "^9.0.13", 34 | "@types/glob": "^7.2.0", 35 | "del": "^6.1.1", 36 | "fs-extra": "^10.1.0", 37 | "glob": "^8.0.3", 38 | "gulp": "^4.0.2", 39 | "gulp-rename": "^2.0.0", 40 | "lodash.template": "^4.5.0", 41 | "ramda": "^0.27.0", 42 | "through2": "^4.0.2", 43 | "ts-node": "^10.8.1", 44 | "typescript": "^4.7.3" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/icons/scripts/example.js: -------------------------------------------------------------------------------- 1 | const { createServer } = require('vite') 2 | const vue = require('@vitejs/plugin-vue') 3 | const vueJsx = require('@vitejs/plugin-vue-jsx') 4 | const path = require('path') 5 | 6 | let server 7 | const viteConfig = { 8 | root: path.resolve(__dirname, '../example'), 9 | plugins: [ 10 | vue({ 11 | include: [/\.vue$/], 12 | }), 13 | vueJsx(), 14 | ], 15 | server: { force: true, port: 4538 }, 16 | } 17 | 18 | async function startServer() { 19 | server && (await server.close()) 20 | 21 | server = await createServer(viteConfig) 22 | 23 | await server.listen() 24 | server.printUrls() 25 | } 26 | 27 | async function dev() { 28 | process.env.NODE_ENV = 'development' 29 | await startServer() 30 | } 31 | 32 | dev() 33 | -------------------------------------------------------------------------------- /packages/icons/scripts/generateComponents.ts: -------------------------------------------------------------------------------- 1 | import glob from 'glob' 2 | import path from 'path' 3 | import fs from 'fs-extra' 4 | import { bigCamel } from '../tasks/utils/utils' 5 | 6 | const globSync = function (pattern: string): Promise { 7 | return new Promise((resolve, reject) => { 8 | glob(pattern, (error, files) => { 9 | if (error) { 10 | reject(error) 11 | } else { 12 | resolve(files) 13 | } 14 | }) 15 | }) 16 | } 17 | 18 | const vNodePath = path.resolve(__dirname, '../src/asn') 19 | const componentPath = path.resolve(__dirname, '../src/components') 20 | 21 | const generateIconDemo = (file: string[]) => { 22 | const iconList: string[] = [] 23 | const importList: string[] = [] 24 | 25 | file.forEach((item) => { 26 | const [, fileName] = item.match(/\/asn\/([-\w]+)\.ts/) || [] 27 | iconList.push(`<${fileName}>`) 28 | importList.push( 29 | `import ${fileName} from '../../src/components/${fileName}.jsx'` 30 | ) 31 | }) 32 | 33 | const template = `import { h, defineComponent } from 'vue' 34 | ${importList.join('\n')} 35 | 36 | const IconDemo = defineComponent({ 37 | render() { 38 | return ( 39 |
40 | ${iconList.join('\n ')} 41 |
42 | ) 43 | }, 44 | }) 45 | export default IconDemo 46 | ` 47 | const demoPath = path.resolve(__dirname, '../example/components') 48 | fs.emptyDirSync(demoPath) 49 | fs.outputFileSync(path.resolve(demoPath, 'IconDemo.tsx'), template) 50 | } 51 | 52 | const generateEntry = (components: string[]) => { 53 | const importList: string[] = [] 54 | const componentList: string[] = [] 55 | components.forEach((item) => { 56 | const name = bigCamel(item) 57 | importList.push(`import ${name} from './components/${item}'`) 58 | componentList.push(name) 59 | }) 60 | const template = `${importList.join('\n')} 61 | 62 | // eslint-disable-next-line prettier/prettier 63 | const components = [\n ${componentList.join(',\n ')},\n] 64 | const install = function (app) { 65 | components.forEach((component) => { 66 | app.component(component.name, component) 67 | }) 68 | } 69 | export default { 70 | install, 71 | ...components, 72 | } 73 | ` 74 | fs.outputFileSync(path.resolve(__dirname, `../src/index.js`), template) 75 | } 76 | 77 | const generateComponents = async () => { 78 | const file = await globSync(`${vNodePath}/*.ts`) 79 | const svgComponents: string[] = [] 80 | 81 | file.forEach((item) => { 82 | const [, fileName] = item.match(/\/asn\/([-\w]+)\.ts/) || [] 83 | 84 | svgComponents.push(fileName) 85 | 86 | const template = `import { defineComponent } from 'vue' 87 | import VueIcon from '../../components/Icon' 88 | import ${fileName}VNode from '../asn/${fileName}' 89 | 90 | const ${fileName} = defineComponent({ 91 | name: '${fileName}', 92 | components: { VueIcon }, 93 | render() { 94 | return 95 | }, 96 | }) 97 | export default ${fileName} 98 | ` 99 | const indexTemplate = `import ${fileName} from './${fileName}.jsx' 100 | 101 | ${fileName}.install = function (app) { 102 | app.component(${fileName}.name, ${fileName}) 103 | } 104 | export default ${fileName} 105 | ` 106 | 107 | fs.outputFileSync( 108 | path.resolve(vNodePath, `${componentPath}/${fileName}.jsx`), 109 | template 110 | ) 111 | 112 | fs.outputFileSync( 113 | path.resolve(vNodePath, `${componentPath}/index.jsx`), 114 | indexTemplate 115 | ) 116 | }) 117 | 118 | generateIconDemo(file) 119 | 120 | generateEntry(svgComponents) 121 | } 122 | 123 | generateComponents() 124 | -------------------------------------------------------------------------------- /packages/icons/src/asn/AccountBookFilled.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const AccountBookFilled: IconDefinition = {"vNode":{"tag":"svg","attrs":{"viewBox":"0 0 1024 1024"},"children":[{"tag":"path","attrs":{"d":"M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zM648.3 426.8l-87.7 161.1h45.7c5.5 0 10 4.5 10 10v21.3c0 5.5-4.5 10-10 10h-63.4v29.7h63.4c5.5 0 10 4.5 10 10v21.3c0 5.5-4.5 10-10 10h-63.4V752c0 5.5-4.5 10-10 10h-41.3c-5.5 0-10-4.5-10-10v-51.8h-63.1c-5.5 0-10-4.5-10-10v-21.3c0-5.5 4.5-10 10-10h63.1v-29.7h-63.1c-5.5 0-10-4.5-10-10v-21.3c0-5.5 4.5-10 10-10h45.2l-88-161.1c-2.6-4.8-.9-10.9 4-13.6 1.5-.8 3.1-1.2 4.8-1.2h46c3.8 0 7.2 2.1 8.9 5.5l72.9 144.3 73.2-144.3a10 10 0 0 1 8.9-5.5h45c5.5 0 10 4.5 10 10 .1 1.7-.3 3.3-1.1 4.8z"}}]},"name":"account-book","theme":"filled"}; 5 | 6 | export default AccountBookFilled; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/AccountBookOutlined.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const AccountBookOutlined: IconDefinition = {"vNode":{"tag":"svg","attrs":{"class":"icon","viewBox":"0 0 1024 1024","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v584zM639.5 414h-45c-3 0-5.8 1.7-7.1 4.4L514 563.8h-2.8l-73.4-145.4a8 8 0 0 0-7.1-4.4h-46c-1.3 0-2.7.3-3.8 1-3.9 2.1-5.3 7-3.2 10.9l89.3 164h-48.6c-4.4 0-8 3.6-8 8v21.3c0 4.4 3.6 8 8 8h65.1v33.7h-65.1c-4.4 0-8 3.6-8 8v21.3c0 4.4 3.6 8 8 8h65.1V752c0 4.4 3.6 8 8 8h41.3c4.4 0 8-3.6 8-8v-53.8h65.4c4.4 0 8-3.6 8-8v-21.3c0-4.4-3.6-8-8-8h-65.4v-33.7h65.4c4.4 0 8-3.6 8-8v-21.3c0-4.4-3.6-8-8-8h-49.1l89.3-164.1c.6-1.2 1-2.5 1-3.8.1-4.4-3.4-8-7.9-8z"}}]},"name":"account-book","theme":"outlined"}; 5 | 6 | export default AccountBookOutlined; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/AccountBookTwoTone.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const AccountBookTwoTone: IconDefinition = {"vNode":function render(primaryColor, secondaryColor) { return {"tag":"svg","attrs":{"viewBox":"0 0 1024 1024","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M712 304c0 4.4-3.6 8-8 8h-56c-4.4 0-8-3.6-8-8v-48H384v48c0 4.4-3.6 8-8 8h-56c-4.4 0-8-3.6-8-8v-48H184v584h656V256H712v48zm-65.6 121.8l-89.3 164.1h49.1c4.4 0 8 3.6 8 8v21.3c0 4.4-3.6 8-8 8h-65.4v33.7h65.4c4.4 0 8 3.6 8 8v21.3c0 4.4-3.6 8-8 8h-65.4V752c0 4.4-3.6 8-8 8h-41.3c-4.4 0-8-3.6-8-8v-53.8h-65.1c-4.4 0-8-3.6-8-8v-21.3c0-4.4 3.6-8 8-8h65.1v-33.7h-65.1c-4.4 0-8-3.6-8-8v-21.3c0-4.4 3.6-8 8-8H467l-89.3-164c-2.1-3.9-.7-8.8 3.2-10.9 1.1-.7 2.5-1 3.8-1h46a8 8 0 0 1 7.1 4.4l73.4 145.4h2.8l73.4-145.4c1.3-2.7 4.1-4.4 7.1-4.4h45c4.5 0 8 3.6 7.9 8 0 1.3-.4 2.6-1 3.8z","fill":secondaryColor}},{"tag":"path","attrs":{"d":"M639.5 414h-45c-3 0-5.8 1.7-7.1 4.4L514 563.8h-2.8l-73.4-145.4a8 8 0 0 0-7.1-4.4h-46c-1.3 0-2.7.3-3.8 1-3.9 2.1-5.3 7-3.2 10.9l89.3 164h-48.6c-4.4 0-8 3.6-8 8v21.3c0 4.4 3.6 8 8 8h65.1v33.7h-65.1c-4.4 0-8 3.6-8 8v21.3c0 4.4 3.6 8 8 8h65.1V752c0 4.4 3.6 8 8 8h41.3c4.4 0 8-3.6 8-8v-53.8h65.4c4.4 0 8-3.6 8-8v-21.3c0-4.4-3.6-8-8-8h-65.4v-33.7h65.4c4.4 0 8-3.6 8-8v-21.3c0-4.4-3.6-8-8-8h-49.1l89.3-164.1c.6-1.2 1-2.5 1-3.8.1-4.4-3.4-8-7.9-8z","fill":primaryColor}},{"tag":"path","attrs":{"d":"M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v584z","fill":primaryColor}}]}; },"name":"account-book","theme":"twoTone"}; 5 | 6 | export default AccountBookTwoTone; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/AlertFilled.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const AlertFilled: IconDefinition = {"vNode":{"tag":"svg","attrs":{"viewBox":"0 0 1024 1024"},"children":[{"tag":"path","attrs":{"d":"M512 244c176.18 0 319 142.82 319 319v233a32 32 0 0 1-32 32H225a32 32 0 0 1-32-32V563c0-176.18 142.82-319 319-319zM484 68h56a8 8 0 0 1 8 8v96a8 8 0 0 1-8 8h-56a8 8 0 0 1-8-8V76a8 8 0 0 1 8-8zM177.25 191.66a8 8 0 0 1 11.32 0l67.88 67.88a8 8 0 0 1 0 11.31l-39.6 39.6a8 8 0 0 1-11.31 0l-67.88-67.88a8 8 0 0 1 0-11.31l39.6-39.6zm669.6 0l39.6 39.6a8 8 0 0 1 0 11.3l-67.88 67.9a8 8 0 0 1-11.32 0l-39.6-39.6a8 8 0 0 1 0-11.32l67.89-67.88a8 8 0 0 1 11.31 0zM192 892h640a32 32 0 0 1 32 32v24a8 8 0 0 1-8 8H168a8 8 0 0 1-8-8v-24a32 32 0 0 1 32-32zm148-317v253h64V575h-64z"}}]},"name":"alert","theme":"filled"}; 5 | 6 | export default AlertFilled; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/AlertOutlined.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const AlertOutlined: IconDefinition = {"vNode":{"tag":"svg","attrs":{"class":"icon","viewBox":"0 0 1024 1024","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M193 796c0 17.7 14.3 32 32 32h574c17.7 0 32-14.3 32-32V563c0-176.2-142.8-319-319-319S193 386.8 193 563v233zm72-233c0-136.4 110.6-247 247-247s247 110.6 247 247v193H404V585c0-5.5-4.5-10-10-10h-44c-5.5 0-10 4.5-10 10v171h-75V563zm-48.1-252.5l39.6-39.6c3.1-3.1 3.1-8.2 0-11.3l-67.9-67.9a8.03 8.03 0 0 0-11.3 0l-39.6 39.6a8.03 8.03 0 0 0 0 11.3l67.9 67.9c3.1 3.1 8.1 3.1 11.3 0zm669.6-79.2l-39.6-39.6a8.03 8.03 0 0 0-11.3 0l-67.9 67.9a8.03 8.03 0 0 0 0 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l67.9-67.9c3.1-3.2 3.1-8.2 0-11.3zM832 892H192c-17.7 0-32 14.3-32 32v24c0 4.4 3.6 8 8 8h688c4.4 0 8-3.6 8-8v-24c0-17.7-14.3-32-32-32zM484 180h56c4.4 0 8-3.6 8-8V76c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v96c0 4.4 3.6 8 8 8z"}}]},"name":"alert","theme":"outlined"}; 5 | 6 | export default AlertOutlined; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/AlertTwoTone.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const AlertTwoTone: IconDefinition = {"vNode":function render(primaryColor, secondaryColor) { return {"tag":"svg","attrs":{"viewBox":"0 0 1024 1024","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M340 585c0-5.5 4.5-10 10-10h44c5.5 0 10 4.5 10 10v171h355V563c0-136.4-110.6-247-247-247S265 426.6 265 563v193h75V585z","fill":secondaryColor}},{"tag":"path","attrs":{"d":"M216.9 310.5l39.6-39.6c3.1-3.1 3.1-8.2 0-11.3l-67.9-67.9a8.03 8.03 0 0 0-11.3 0l-39.6 39.6a8.03 8.03 0 0 0 0 11.3l67.9 67.9c3.1 3.1 8.1 3.1 11.3 0zm669.6-79.2l-39.6-39.6a8.03 8.03 0 0 0-11.3 0l-67.9 67.9a8.03 8.03 0 0 0 0 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l67.9-67.9c3.1-3.2 3.1-8.2 0-11.3zM484 180h56c4.4 0 8-3.6 8-8V76c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v96c0 4.4 3.6 8 8 8zm348 712H192c-17.7 0-32 14.3-32 32v24c0 4.4 3.6 8 8 8h688c4.4 0 8-3.6 8-8v-24c0-17.7-14.3-32-32-32zm-639-96c0 17.7 14.3 32 32 32h574c17.7 0 32-14.3 32-32V563c0-176.2-142.8-319-319-319S193 386.8 193 563v233zm72-233c0-136.4 110.6-247 247-247s247 110.6 247 247v193H404V585c0-5.5-4.5-10-10-10h-44c-5.5 0-10 4.5-10 10v171h-75V563z","fill":primaryColor}}]}; },"name":"alert","theme":"twoTone"}; 5 | 6 | export default AlertTwoTone; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/ApiFilled.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const ApiFilled: IconDefinition = {"vNode":{"tag":"svg","attrs":{"class":"icon","viewBox":"0 0 1024 1024","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M917.7 148.8l-42.4-42.4c-1.6-1.6-3.6-2.3-5.7-2.3s-4.1.8-5.7 2.3l-76.1 76.1a199.27 199.27 0 0 0-112.1-34.3c-51.2 0-102.4 19.5-141.5 58.6L432.3 308.7a8.03 8.03 0 0 0 0 11.3L704 591.7c1.6 1.6 3.6 2.3 5.7 2.3 2 0 4.1-.8 5.7-2.3l101.9-101.9c68.9-69 77-175.7 24.3-253.5l76.1-76.1c3.1-3.2 3.1-8.3 0-11.4zM578.9 546.7a8.03 8.03 0 0 0-11.3 0L501 613.3 410.7 523l66.7-66.7c3.1-3.1 3.1-8.2 0-11.3L441 408.6a8.03 8.03 0 0 0-11.3 0L363 475.3l-43-43a7.85 7.85 0 0 0-5.7-2.3c-2 0-4.1.8-5.7 2.3L206.8 534.2c-68.9 68.9-77 175.7-24.3 253.5l-76.1 76.1a8.03 8.03 0 0 0 0 11.3l42.4 42.4c1.6 1.6 3.6 2.3 5.7 2.3s4.1-.8 5.7-2.3l76.1-76.1c33.7 22.9 72.9 34.3 112.1 34.3 51.2 0 102.4-19.5 141.5-58.6l101.9-101.9c3.1-3.1 3.1-8.2 0-11.3l-43-43 66.7-66.7c3.1-3.1 3.1-8.2 0-11.3l-36.6-36.2z"}}]},"name":"api","theme":"filled"}; 5 | 6 | export default ApiFilled; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/ApiOutlined.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const ApiOutlined: IconDefinition = {"vNode":{"tag":"svg","attrs":{"class":"icon","viewBox":"0 0 1024 1024","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M917.7 148.8l-42.4-42.4c-1.6-1.6-3.6-2.3-5.7-2.3s-4.1.8-5.7 2.3l-76.1 76.1a199.27 199.27 0 0 0-112.1-34.3c-51.2 0-102.4 19.5-141.5 58.6L432.3 308.7a8.03 8.03 0 0 0 0 11.3L704 591.7c1.6 1.6 3.6 2.3 5.7 2.3 2 0 4.1-.8 5.7-2.3l101.9-101.9c68.9-69 77-175.7 24.3-253.5l76.1-76.1c3.1-3.2 3.1-8.3 0-11.4zM769.1 441.7l-59.4 59.4-186.8-186.8 59.4-59.4c24.9-24.9 58.1-38.7 93.4-38.7 35.3 0 68.4 13.7 93.4 38.7 24.9 24.9 38.7 58.1 38.7 93.4 0 35.3-13.8 68.4-38.7 93.4zm-190.2 105a8.03 8.03 0 0 0-11.3 0L501 613.3 410.7 523l66.7-66.7c3.1-3.1 3.1-8.2 0-11.3L441 408.6a8.03 8.03 0 0 0-11.3 0L363 475.3l-43-43a7.85 7.85 0 0 0-5.7-2.3c-2 0-4.1.8-5.7 2.3L206.8 534.2c-68.9 69-77 175.7-24.3 253.5l-76.1 76.1a8.03 8.03 0 0 0 0 11.3l42.4 42.4c1.6 1.6 3.6 2.3 5.7 2.3s4.1-.8 5.7-2.3l76.1-76.1c33.7 22.9 72.9 34.3 112.1 34.3 51.2 0 102.4-19.5 141.5-58.6l101.9-101.9c3.1-3.1 3.1-8.2 0-11.3l-43-43 66.7-66.7c3.1-3.1 3.1-8.2 0-11.3l-36.6-36.2zM441.7 769.1a131.32 131.32 0 0 1-93.4 38.7c-35.3 0-68.4-13.7-93.4-38.7a131.32 131.32 0 0 1-38.7-93.4c0-35.3 13.7-68.4 38.7-93.4l59.4-59.4 186.8 186.8-59.4 59.4z"}}]},"name":"api","theme":"outlined"}; 5 | 6 | export default ApiOutlined; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/ApiTwoTone.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const ApiTwoTone: IconDefinition = {"vNode":function render(primaryColor, secondaryColor) { return {"tag":"svg","attrs":{"viewBox":"0 0 1024 1024","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M148.2 674.6zm106.7-92.3c-25 25-38.7 58.1-38.7 93.4s13.8 68.5 38.7 93.4c25 25 58.1 38.7 93.4 38.7 35.3 0 68.5-13.8 93.4-38.7l59.4-59.4-186.8-186.8-59.4 59.4zm420.8-366.1c-35.3 0-68.5 13.8-93.4 38.7l-59.4 59.4 186.8 186.8 59.4-59.4c24.9-25 38.7-58.1 38.7-93.4s-13.8-68.5-38.7-93.4c-25-25-58.1-38.7-93.4-38.7z","fill":secondaryColor}},{"tag":"path","attrs":{"d":"M578.9 546.7a8.03 8.03 0 0 0-11.3 0L501 613.3 410.7 523l66.7-66.7c3.1-3.1 3.1-8.2 0-11.3L441 408.6a8.03 8.03 0 0 0-11.3 0L363 475.3l-43-43a7.85 7.85 0 0 0-5.7-2.3c-2 0-4.1.8-5.7 2.3L206.8 534.2a199.45 199.45 0 0 0-58.6 140.4c-.2 39.5 11.2 79.1 34.3 113.1l-76.1 76.1a8.03 8.03 0 0 0 0 11.3l42.4 42.4c1.6 1.6 3.6 2.3 5.7 2.3s4.1-.8 5.7-2.3l76.1-76.1c33.7 22.9 72.9 34.3 112.1 34.3 51.2 0 102.4-19.5 141.5-58.6l101.9-101.9c3.1-3.1 3.1-8.2 0-11.3l-43-43 66.7-66.7c3.1-3.1 3.1-8.2 0-11.3l-36.6-36.2zM441.7 769.1a131.32 131.32 0 0 1-93.4 38.7c-35.3 0-68.4-13.7-93.4-38.7-24.9-24.9-38.7-58.1-38.7-93.4s13.7-68.4 38.7-93.4l59.4-59.4 186.8 186.8-59.4 59.4zm476-620.3l-42.4-42.4c-1.6-1.6-3.6-2.3-5.7-2.3s-4.1.8-5.7 2.3l-76.1 76.1a199.27 199.27 0 0 0-112.1-34.3c-51.2 0-102.4 19.5-141.5 58.6L432.3 308.7a8.03 8.03 0 0 0 0 11.3L704 591.7c1.6 1.6 3.6 2.3 5.7 2.3 2 0 4.1-.8 5.7-2.3l101.9-101.9c68.9-69 77-175.7 24.3-253.5l76.1-76.1c3.1-3.2 3.1-8.3 0-11.4zM769.1 441.7l-59.4 59.4-186.8-186.8 59.4-59.4c24.9-24.9 58.1-38.7 93.4-38.7s68.4 13.7 93.4 38.7c24.9 24.9 38.7 58.1 38.7 93.4s-13.8 68.4-38.7 93.4z","fill":primaryColor}}]}; },"name":"api","theme":"twoTone"}; 5 | 6 | export default ApiTwoTone; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/BookFilled.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const BookFilled: IconDefinition = {"vNode":{"tag":"svg","attrs":{"class":"icon","height":"200","p-id":"1216","t":"1655436274346","version":"1.1","viewBox":"0 0 1024 1024","width":"200","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M487.04 68.693333c12.586667-5.333333 26.581333-6.101333 39.552-2.389333l6.4 2.261333L859.648 204.8c20.906667 8.746667 34.858667 28.501333 36.266667 50.773333l0.042666 5.632-8.832 271.317334a363.477333 363.477333 0 0 1-60.970666 189.824l-8.32 11.946666-7.338667 10.112a454.741333 454.741333 0 0 1-123.562667 116.266667l-14.634666 8.96-140.288 82.218667a59.392 59.392 0 0 1-55.168 2.56l-5.717334-3.072-135.936-82.730667a455.125333 455.125333 0 0 1-121.770666-108.202667l-9.856-13.098666-9.472-13.013334a345.984 345.984 0 0 1-65.792-188.672L128 531.114667V259.328c0-21.76 11.989333-41.557333 30.848-51.797333l5.290667-2.56 322.901333-136.32zM512 277.333333a149.333333 149.333333 0 0 0-50.261333 290.005334l7.594666 2.474666V704l0.298667 4.992a42.666667 42.666667 0 0 0 84.736 0L554.666667 704v-134.186667A149.418667 149.418667 0 0 0 512 277.333333z","p-id":"1217"}}]},"name":"book","theme":"filled"}; 5 | 6 | export default BookFilled; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/BookOutlined.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const BookOutlined: IconDefinition = {"vNode":{"tag":"svg","attrs":{"class":"icon","viewBox":"0 0 1024 1024","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M832 64H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32zm-260 72h96v209.9L621.5 312 572 347.4V136zm220 752H232V136h280v296.9c0 3.3 1 6.6 3 9.3a15.9 15.9 0 0 0 22.3 3.7l83.8-59.9 81.4 59.4c2.7 2 6 3.1 9.4 3.1 8.8 0 16-7.2 16-16V136h64v752z"}}]},"name":"book","theme":"outlined"}; 5 | 6 | export default BookOutlined; 7 | -------------------------------------------------------------------------------- /packages/icons/src/asn/BookTwoTone.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const BookTwoTone: IconDefinition = {"vNode":function render(primaryColor, secondaryColor) { return {"tag":"svg","attrs":{"viewBox":"0 0 1024 1024","xmlns":"http://www.w3.org/2000/svg"},"children":[{"tag":"path","attrs":{"d":"M832 64H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32zm-260 72h96v209.9L621.5 312 572 347.4V136zM232 888V136h280v296.9c0 3.3 1 6.6 3 9.3a15.9 15.9 0 0 0 22.3 3.7l83.8-59.9 81.4 59.4c2.7 2 6 3.1 9.4 3.1 8.8 0 16-7.2 16-16V136h64v752H232z","fill":primaryColor}},{"tag":"path","attrs":{"d":"M668 345.9V136h-96v211.4l49.5-35.4z","fill":secondaryColor}},{"tag":"path","attrs":{"d":"M727.9 136v296.5c0 8.8-7.2 16-16 16-3.4 0-6.7-1.1-9.4-3.1L621.1 386l-83.8 59.9a15.9 15.9 0 0 1-22.3-3.7c-2-2.7-3-6-3-9.3V136H232v752h559.9V136h-64z","fill":secondaryColor}}]}; },"name":"book","theme":"twoTone"}; 5 | 6 | export default BookTwoTone; 7 | -------------------------------------------------------------------------------- /packages/icons/src/components/AccountBookFilled.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import AccountBookFilledVNode from '../asn/AccountBookFilled' 4 | 5 | const AccountBookFilled = defineComponent({ 6 | name: 'AccountBookFilled', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default AccountBookFilled 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/AccountBookOutlined.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import AccountBookOutlinedVNode from '../asn/AccountBookOutlined' 4 | 5 | const AccountBookOutlined = defineComponent({ 6 | name: 'AccountBookOutlined', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default AccountBookOutlined 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/AccountBookTwoTone.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import AccountBookTwoToneVNode from '../asn/AccountBookTwoTone' 4 | 5 | const AccountBookTwoTone = defineComponent({ 6 | name: 'AccountBookTwoTone', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default AccountBookTwoTone 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/AlertFilled.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import AlertFilledVNode from '../asn/AlertFilled' 4 | 5 | const AlertFilled = defineComponent({ 6 | name: 'AlertFilled', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default AlertFilled 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/AlertOutlined.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import AlertOutlinedVNode from '../asn/AlertOutlined' 4 | 5 | const AlertOutlined = defineComponent({ 6 | name: 'AlertOutlined', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default AlertOutlined 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/AlertTwoTone.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import AlertTwoToneVNode from '../asn/AlertTwoTone' 4 | 5 | const AlertTwoTone = defineComponent({ 6 | name: 'AlertTwoTone', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default AlertTwoTone 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/ApiFilled.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import ApiFilledVNode from '../asn/ApiFilled' 4 | 5 | const ApiFilled = defineComponent({ 6 | name: 'ApiFilled', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default ApiFilled 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/ApiOutlined.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import ApiOutlinedVNode from '../asn/ApiOutlined' 4 | 5 | const ApiOutlined = defineComponent({ 6 | name: 'ApiOutlined', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default ApiOutlined 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/ApiTwoTone.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import ApiTwoToneVNode from '../asn/ApiTwoTone' 4 | 5 | const ApiTwoTone = defineComponent({ 6 | name: 'ApiTwoTone', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default ApiTwoTone 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/BookFilled.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import BookFilledVNode from '../asn/BookFilled' 4 | 5 | const BookFilled = defineComponent({ 6 | name: 'BookFilled', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default BookFilled 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/BookOutlined.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import BookOutlinedVNode from '../asn/BookOutlined' 4 | 5 | const BookOutlined = defineComponent({ 6 | name: 'BookOutlined', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default BookOutlined 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/BookTwoTone.jsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import VueIcon from '../../components/Icon' 3 | import BookTwoToneVNode from '../asn/BookTwoTone' 4 | 5 | const BookTwoTone = defineComponent({ 6 | name: 'BookTwoTone', 7 | components: { VueIcon }, 8 | render() { 9 | return 10 | }, 11 | }) 12 | export default BookTwoTone 13 | -------------------------------------------------------------------------------- /packages/icons/src/components/index.jsx: -------------------------------------------------------------------------------- 1 | import BookTwoTone from './BookTwoTone.jsx' 2 | 3 | BookTwoTone.install = function (app) { 4 | app.component(BookTwoTone.name, BookTwoTone) 5 | } 6 | export default BookTwoTone 7 | -------------------------------------------------------------------------------- /packages/icons/src/index.js: -------------------------------------------------------------------------------- 1 | import AccountBookFilled from './components/AccountBookFilled' 2 | import AccountBookOutlined from './components/AccountBookOutlined' 3 | import AccountBookTwoTone from './components/AccountBookTwoTone' 4 | import AlertFilled from './components/AlertFilled' 5 | import AlertOutlined from './components/AlertOutlined' 6 | import AlertTwoTone from './components/AlertTwoTone' 7 | import ApiFilled from './components/ApiFilled' 8 | import ApiOutlined from './components/ApiOutlined' 9 | import ApiTwoTone from './components/ApiTwoTone' 10 | import BookFilled from './components/BookFilled' 11 | import BookOutlined from './components/BookOutlined' 12 | import BookTwoTone from './components/BookTwoTone' 13 | 14 | // eslint-disable-next-line prettier/prettier 15 | const components = [ 16 | AccountBookFilled, 17 | AccountBookOutlined, 18 | AccountBookTwoTone, 19 | AlertFilled, 20 | AlertOutlined, 21 | AlertTwoTone, 22 | ApiFilled, 23 | ApiOutlined, 24 | ApiTwoTone, 25 | BookFilled, 26 | BookOutlined, 27 | BookTwoTone, 28 | ] 29 | const install = function (app) { 30 | components.forEach((component) => { 31 | app.component(component.name, component) 32 | }) 33 | } 34 | export default { 35 | install, 36 | ...components, 37 | } 38 | -------------------------------------------------------------------------------- /packages/icons/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface AbstractNode { 2 | tag: string 3 | attrs: { 4 | [key: string]: string 5 | } 6 | children?: AbstractNode[] 7 | } 8 | 9 | export interface IconDefinition { 10 | name: string 11 | theme: ThemeType 12 | vNode: 13 | | ((primaryColor: string, secondaryColor: string) => AbstractNode) 14 | | AbstractNode 15 | } 16 | 17 | export type ThemeType = 'filled' | 'outlined' | 'twoTone' 18 | -------------------------------------------------------------------------------- /packages/icons/svg/filled/account-book.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/icons/svg/filled/alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/icons/svg/filled/api.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/icons/svg/filled/book.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/icons/svg/outlined/account-book.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/icons/svg/outlined/alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/icons/svg/outlined/api.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/icons/svg/outlined/book.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/icons/svg/twotone/account-book.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/icons/svg/twotone/alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/icons/svg/twotone/api.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/icons/svg/twotone/book.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/icons/tasks/clean.ts: -------------------------------------------------------------------------------- 1 | import del from 'del' 2 | 3 | export const clean = (dirs: any) => { 4 | return function CleanDirectories() { 5 | return del(dirs) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/icons/tasks/generateIcons.ts: -------------------------------------------------------------------------------- 1 | import { src, dest } from 'gulp' 2 | 3 | import rename from 'gulp-rename' 4 | 5 | import { svg2VNode } from './utils/svg2VNode' 6 | 7 | import { useTemplate } from './utils/useTemplate' 8 | import { bigCamel } from './utils/utils' 9 | 10 | export const generateIcons = ({ theme, from, toDir }: any) => { 11 | return function GenerateIcons() { 12 | return src(from) 13 | .pipe(svg2VNode({ theme })) 14 | .pipe(useTemplate(theme)) 15 | .pipe( 16 | rename((file) => { 17 | if (file.basename) { 18 | const name = `${file.basename}-${theme}` 19 | file.basename = `${bigCamel(name)}` 20 | file.extname = '.ts' 21 | } 22 | }) 23 | ) 24 | .pipe(dest(toDir)) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/icons/tasks/templates/icon.ts.ejs: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | import { IconDefinition } from '../types' 3 | 4 | const <%= identifier %>: IconDefinition = <%= content %>; 5 | 6 | export default <%= identifier %>; 7 | -------------------------------------------------------------------------------- /packages/icons/tasks/utils/createTransformStream.ts: -------------------------------------------------------------------------------- 1 | import through from 'through2' 2 | 3 | export const createTransformStream = function (fn: any) { 4 | return through.obj((chunk, enc, done) => { 5 | if (chunk.isBuffer() && typeof fn === 'function') { 6 | const original = chunk.contents.toString(enc) 7 | 8 | try { 9 | const result = fn(original, chunk) 10 | chunk.contents = Buffer.from(result) 11 | done(null, chunk) 12 | } catch (error) { 13 | done(error, null) 14 | } 15 | } else { 16 | done(null, chunk) 17 | } 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /packages/icons/tasks/utils/svg2VNode.ts: -------------------------------------------------------------------------------- 1 | import parseXML from '@rgrove/parse-xml' 2 | import { 3 | applyTo, 4 | pipe, 5 | path as pathGet, 6 | clone, 7 | filter, 8 | where, 9 | equals, 10 | map, 11 | gt as greaterThan, 12 | dissoc as deleteProp, 13 | unless, 14 | both, 15 | length, 16 | __, 17 | objOf, 18 | assoc, 19 | call, 20 | prop, 21 | evolve, 22 | toPairs, 23 | compose, 24 | ap, 25 | toUpper, 26 | join, 27 | toLower, 28 | apply, 29 | flip, 30 | replace, 31 | zipWith, 32 | } from 'ramda' 33 | 34 | import { createTransformStream } from './createTransformStream' 35 | import { twoToneIcon } from './twoTone' 36 | 37 | const element2VNode: any = ({ theme, name }: any) => { 38 | return (svgElement: any) => { 39 | const { name: tag, attributes, children } = svgElement 40 | 41 | if (theme === 'twoTone' && tag === 'path') { 42 | attributes.fill = attributes.fill || '#333' 43 | } 44 | 45 | const res = applyTo({ 46 | tag, 47 | attrs: clone(attributes), 48 | children: applyTo(children)( 49 | pipe(filter(where({ type: equals('element') })), (value) => { 50 | return map(element2VNode({ theme, name }), value) 51 | }) 52 | ), 53 | })( 54 | unless( 55 | where({ 56 | children: both(Array.isArray, pipe(length, greaterThan(__, 0))), 57 | }), 58 | deleteProp('children') 59 | ) 60 | ) 61 | return res 62 | } 63 | } 64 | 65 | export const svg2VNode = function ({ theme }: any) { 66 | return createTransformStream((svgContent: any, { stem: name }: any) => { 67 | const res = applyTo(svgContent)( 68 | pipe( 69 | parseXML, 70 | pipe(pathGet(['children', 0])), 71 | element2VNode({ theme, name }), 72 | pipe(objOf('vNode'), assoc('name', name), assoc('theme', theme)) 73 | ) 74 | ) 75 | if (theme === 'twoTone') { 76 | return twoToneIcon(res) 77 | } 78 | 79 | return JSON.stringify(res) 80 | }) 81 | } 82 | -------------------------------------------------------------------------------- /packages/icons/tasks/utils/twoTone.ts: -------------------------------------------------------------------------------- 1 | import { 2 | pipe, 3 | clone, 4 | zipWith, 5 | call, 6 | assoc, 7 | prop, 8 | ap, 9 | map, 10 | join, 11 | toLower, 12 | toUpper, 13 | applyTo, 14 | evolve, 15 | toPairs, 16 | compose, 17 | replace, 18 | apply, 19 | flip, 20 | } from 'ramda' 21 | 22 | const __PLACEHOLDER__ = 'TWOTONE_ICON_FUNCTION_HOLDER' 23 | const __PRIMARY_COLOR__ = 'primaryColor' 24 | const __SECONDARY_COLOR__ = 'secondaryColor' 25 | 26 | const getRegExpFromColors = pipe( 27 | ap([toUpper, toLower]), 28 | map((color) => `("${color}")`), 29 | join('|'), 30 | (content) => new RegExp(content, 'g') 31 | ) 32 | 33 | const colorsReplacer: any = applyTo({ 34 | [__PRIMARY_COLOR__]: ['#333', '#333333'], 35 | [__SECONDARY_COLOR__]: ['#E6E6E6', '#D9D9D9', '#D8D8D8'], 36 | })( 37 | pipe( 38 | evolve({ 39 | [__PRIMARY_COLOR__]: getRegExpFromColors, 40 | [__SECONDARY_COLOR__]: getRegExpFromColors, 41 | }), 42 | toPairs, 43 | map(compose(apply, flip)(replace)), 44 | apply(pipe) 45 | ) 46 | ) 47 | 48 | const duplicate = (n: T): [T, T] => [clone(n), clone(n)] 49 | 50 | export const twoToneIcon = pipe( 51 | duplicate, 52 | zipWith(call as any, [ 53 | pipe(assoc('vNode', __PLACEHOLDER__), JSON.stringify), 54 | pipe(prop('vNode'), JSON.stringify, colorsReplacer, (content) => { 55 | return `function render(${__PRIMARY_COLOR__}, ${__SECONDARY_COLOR__}) { return ${content}; }` 56 | }), 57 | ]), 58 | ([hasPlaceholderContent, iconFunctionContent]) => 59 | replace( 60 | `"${__PLACEHOLDER__}"`, 61 | iconFunctionContent as any, 62 | hasPlaceholderContent as any 63 | ) 64 | ) 65 | -------------------------------------------------------------------------------- /packages/icons/tasks/utils/useTemplate.ts: -------------------------------------------------------------------------------- 1 | import template from 'lodash.template' 2 | 3 | import { readFileSync } from 'fs' 4 | import { resolve } from 'path' 5 | import { createTransformStream } from './createTransformStream' 6 | import { bigCamel } from './utils' 7 | 8 | const iconTemplate = readFileSync( 9 | resolve(__dirname, '../templates/icon.ts.ejs'), 10 | 'utf8' 11 | ) 12 | 13 | const compiled = template(iconTemplate) 14 | 15 | export const useTemplate = (theme: string) => { 16 | return createTransformStream((content: any, { stem: name, path }: any) => { 17 | return compiled({ identifier: bigCamel(`${name}-${theme}`), content }) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /packages/icons/tasks/utils/utils.ts: -------------------------------------------------------------------------------- 1 | export function smallCamel(str: string, separator: '-' | '_' = '-') { 2 | const reg = new RegExp(`${separator}([a-z])`, 'g') 3 | return str.replace(reg, (p, m) => m.toUpperCase()) 4 | } 5 | 6 | export function bigCamel(str: string, separator: '-' | '_' = '-') { 7 | const s = smallCamel(str, separator) 8 | return s.replace(s.charAt(0), s.charAt(0).toUpperCase()) 9 | } 10 | -------------------------------------------------------------------------------- /packages/icons/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "esnext", 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "jsx": "preserve", 10 | "skipLibCheck": true, 11 | "allowJs": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/markdown-to-vue/index.js: -------------------------------------------------------------------------------- 1 | const markdown = require('markdown-it') 2 | const markdownContainer = require('markdown-it-container') 3 | const hljs = require('highlight.js') 4 | const matter = require('gray-matter') 5 | 6 | function splitCard(html) { 7 | const hGroup = html 8 | .replace(/

14 | fragment.includes('${fragment}` 16 | : fragment 17 | ) 18 | .join('') 19 | 20 | return cardGroup.replace(//g, '') 21 | } 22 | 23 | function highlight(str, lang) { 24 | if (lang && hljs.getLanguage(lang)) { 25 | return `
${
 26 |       hljs.highlight(str, { language: lang, ignoreIllegals: true }).value
 27 |     }
` 28 | } 29 | return '' 30 | } 31 | 32 | function markdownToVue(source, id, options) { 33 | const { data, content: contentSource } = matter(source) 34 | const md = markdown({ 35 | html: true, 36 | typographer: true, 37 | highlight, 38 | }) 39 | const customBlock = ['info', 'error', 'warning', 'tips'] 40 | const defaultCustomBlockTitle = { 41 | info: '消息', 42 | error: '错误', 43 | warning: '警告', 44 | tips: '提示', 45 | } 46 | customBlock.forEach((item) => { 47 | md.use(markdownContainer, item, { 48 | render(tokens, idx) { 49 | const reg = new RegExp(`^${item}\\s+(.*)$`) 50 | const m = tokens[idx].info.trim().match(reg) || [ 51 | null, 52 | defaultCustomBlockTitle[item], 53 | ] 54 | 55 | if (tokens[idx].nesting === 1) { 56 | return ( 57 | `
` + 58 | `
${md.utils.escapeHtml( 59 | m[1] 60 | )}
\n` 61 | ) 62 | } 63 | return '
\n' 64 | }, 65 | }) 66 | }) 67 | 68 | const res = md.render(contentSource) 69 | 70 | const templateString = splitCard(res) 71 | 72 | return ` 73 | 74 | 75 | 81 | ` 82 | } 83 | 84 | function MarkdownVitePlugin(options) { 85 | return { 86 | name: 'lin-markdown-to-vue-vite-plugin', 87 | enforce: 'pre', 88 | transform(source, id) { 89 | if (!/\.md$/.test(id)) { 90 | return undefined 91 | } 92 | try { 93 | return markdownToVue(source, id, options) 94 | } catch (e) { 95 | this.error(e) 96 | return undefined 97 | } 98 | }, 99 | async handleHotUpdate(ctx) { 100 | if (!/\.md$/.test(ctx.file)) return 101 | 102 | const readSource = ctx.read 103 | ctx.read = async function () { 104 | return markdownToVue(await readSource(), options) 105 | } 106 | }, 107 | } 108 | } 109 | 110 | module.exports = MarkdownVitePlugin 111 | -------------------------------------------------------------------------------- /packages/markdown-to-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lin-ui-vue/markdown-to-vue", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "fs-extra": "^10.1.0", 14 | "gray-matter": "^4.0.3", 15 | "highlight.js": "^11.5.1", 16 | "markdown-it": "^13.0.1", 17 | "markdown-it-container": "^3.0.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/ui/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/ui/.lin-ui-vue/components.json: -------------------------------------------------------------------------------- 1 | [ 2 | "avatar", 3 | "button", 4 | "icon", 5 | "tag", 6 | "config-provider", 7 | "card", 8 | "image", 9 | "lazy", 10 | "row", 11 | "col", 12 | "Cell" 13 | ] 14 | -------------------------------------------------------------------------------- /packages/ui/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/ui/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + TypeScript + Vite 2 | 3 | This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 ` 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/ui/site/mobile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite mobile 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/ui/site/mobile/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/ui/site/mobile/components/Index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/ui/site/mobile/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 6 | const component: DefineComponent<{}, {}, any> 7 | export default component 8 | } 9 | -------------------------------------------------------------------------------- /packages/ui/site/mobile/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import LinIcon from '@lin-ui-vue/icons' 3 | import router from './routes/index' 4 | import App from './App.vue' 5 | import LinUI from '../../index' 6 | import '../../src/theme/index.less' 7 | 8 | const app = createApp(App) 9 | 10 | app.use(router).use(LinUI).use(LinIcon).mount('#app') 11 | -------------------------------------------------------------------------------- /packages/ui/site/mobile/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/mobile/public/favicon.ico -------------------------------------------------------------------------------- /packages/ui/site/mobile/route.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | path: '/avatar', 4 | // eslint-disable-next-line prettier/prettier 5 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/avatar/example/index.vue') 6 | }, 7 | { 8 | path: '/button', 9 | // eslint-disable-next-line prettier/prettier 10 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/button/example/index.vue') 11 | }, 12 | { 13 | path: '/col', 14 | // eslint-disable-next-line prettier/prettier 15 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/col/example/index.vue') 16 | }, 17 | { 18 | path: '/config-provider', 19 | // eslint-disable-next-line prettier/prettier 20 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/config-provider/example/index.vue') 21 | }, 22 | { 23 | path: '/icon', 24 | // eslint-disable-next-line prettier/prettier 25 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/icon/example/index.vue') 26 | }, 27 | { 28 | path: '/image', 29 | // eslint-disable-next-line prettier/prettier 30 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/image/example/index.vue') 31 | }, 32 | { 33 | path: '/lazy', 34 | // eslint-disable-next-line prettier/prettier 35 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/lazy/example/index.vue') 36 | }, 37 | { 38 | path: '/row', 39 | // eslint-disable-next-line prettier/prettier 40 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/row/example/index.vue') 41 | }, 42 | { 43 | path: '/tag', 44 | // eslint-disable-next-line prettier/prettier 45 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/tag/example/index.vue') 46 | }, 47 | ] 48 | -------------------------------------------------------------------------------- /packages/ui/site/mobile/routes/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory } from 'vue-router' 2 | import routes from '../route' 3 | 4 | const router = createRouter({ 5 | history: createWebHashHistory(), 6 | scrollBehavior: () => { 7 | return { top: 0 } 8 | }, 9 | routes: [ 10 | { 11 | path: '/', 12 | component: import('../components/Index.vue'), 13 | }, 14 | ...routes, 15 | ], 16 | }) 17 | 18 | export default router 19 | -------------------------------------------------------------------------------- /packages/ui/site/pc/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 19 | -------------------------------------------------------------------------------- /packages/ui/site/pc/assets/images/bottom-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/pc/assets/images/bottom-logo.png -------------------------------------------------------------------------------- /packages/ui/site/pc/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/pc/assets/images/favicon.ico -------------------------------------------------------------------------------- /packages/ui/site/pc/assets/images/h1-Icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/pc/assets/images/h1-Icon.jpg -------------------------------------------------------------------------------- /packages/ui/site/pc/assets/images/h2-icon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/pc/assets/images/h2-icon1.png -------------------------------------------------------------------------------- /packages/ui/site/pc/assets/images/h2-icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/pc/assets/images/h2-icon2.png -------------------------------------------------------------------------------- /packages/ui/site/pc/assets/images/h2-icon3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/pc/assets/images/h2-icon3.png -------------------------------------------------------------------------------- /packages/ui/site/pc/assets/images/h2-icon4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/pc/assets/images/h2-icon4.png -------------------------------------------------------------------------------- /packages/ui/site/pc/assets/images/left-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/pc/assets/images/left-logo.png -------------------------------------------------------------------------------- /packages/ui/site/pc/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaleLin/lin-ui-vue/4d52738874b9861567c1cfd5e7609a676020b542/packages/ui/site/pc/assets/images/logo.png -------------------------------------------------------------------------------- /packages/ui/site/pc/components/AppHeader.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 21 | 55 | -------------------------------------------------------------------------------- /packages/ui/site/pc/components/AppLayout.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 30 | 40 | -------------------------------------------------------------------------------- /packages/ui/site/pc/components/AppMain.vue: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | -------------------------------------------------------------------------------- /packages/ui/site/pc/components/AppMobile.vue: -------------------------------------------------------------------------------- 1 | 4 | 11 | 21 | -------------------------------------------------------------------------------- /packages/ui/site/pc/components/AppSidebar.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 52 | 109 | -------------------------------------------------------------------------------- /packages/ui/site/pc/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp, render, h } from 'vue' 2 | import App from './App.vue' 3 | import router from './routes/index' 4 | import './style/hljs.scss' 5 | import './style/index.scss' 6 | import '../../src/theme/index.less' 7 | 8 | const app = createApp(App) 9 | 10 | app.use(router).mount('#app') 11 | -------------------------------------------------------------------------------- /packages/ui/site/pc/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "入门": [ 3 | { 4 | "title": "事件", 5 | "order": 1, 6 | "routePath": "/event", 7 | "parent": "入门" 8 | }, 9 | { 10 | "title": "快速开始", 11 | "order": 2, 12 | "routePath": "/start", 13 | "parent": "入门" 14 | }, 15 | { 16 | "title": "常见问题", 17 | "order": 3, 18 | "routePath": "/question", 19 | "parent": "入门" 20 | } 21 | ], 22 | "基础": [ 23 | { 24 | "title": "avatar avatar", 25 | "order": 1, 26 | "routePath": "/avatar", 27 | "parent": "基础" 28 | }, 29 | { 30 | "title": "按钮 Button", 31 | "order": 1, 32 | "routePath": "/button", 33 | "parent": "基础" 34 | }, 35 | { 36 | "title": "Cell 单元格", 37 | "order": 1, 38 | "routePath": "/Cell", 39 | "parent": "基础" 40 | }, 41 | { 42 | "title": "col Col", 43 | "order": 1, 44 | "routePath": "/col", 45 | "parent": "基础" 46 | }, 47 | { 48 | "title": "config-provider config-provider", 49 | "order": 1, 50 | "routePath": "/config-provider", 51 | "parent": "基础" 52 | }, 53 | { 54 | "title": "image 图片", 55 | "order": 1, 56 | "routePath": "/image", 57 | "parent": "基础" 58 | }, 59 | { 60 | "title": "lazy 懒加载", 61 | "order": 1, 62 | "routePath": "/lazy", 63 | "parent": "基础" 64 | }, 65 | { 66 | "title": "row Row", 67 | "order": 1, 68 | "routePath": "/row", 69 | "parent": "基础" 70 | }, 71 | { 72 | "title": "tag tag", 73 | "order": 1, 74 | "routePath": "/tag", 75 | "parent": "基础" 76 | }, 77 | { 78 | "title": "图标 Icon", 79 | "order": 2, 80 | "routePath": "/icon", 81 | "parent": "基础" 82 | } 83 | ] 84 | } 85 | -------------------------------------------------------------------------------- /packages/ui/site/pc/pages/index/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 22 | -------------------------------------------------------------------------------- /packages/ui/site/pc/route.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | path: '/event', 4 | // eslint-disable-next-line prettier/prettier 5 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/site/docs/Event.md'), 6 | meta: { 7 | parent: '入门', 8 | }, 9 | }, 10 | { 11 | path: '/question', 12 | // eslint-disable-next-line prettier/prettier 13 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/site/docs/Question.md'), 14 | meta: { 15 | parent: '入门', 16 | }, 17 | }, 18 | { 19 | path: '/start', 20 | // eslint-disable-next-line prettier/prettier 21 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/site/docs/Start.md'), 22 | meta: { 23 | parent: '入门', 24 | }, 25 | }, 26 | { 27 | path: '/avatar', 28 | // eslint-disable-next-line prettier/prettier 29 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/avatar/docs/README.md'), 30 | meta: { 31 | parent: '基础', 32 | }, 33 | }, 34 | { 35 | path: '/button', 36 | // eslint-disable-next-line prettier/prettier 37 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/button/docs/README.md'), 38 | meta: { 39 | parent: '基础', 40 | }, 41 | }, 42 | { 43 | path: '/cell', 44 | // eslint-disable-next-line prettier/prettier 45 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/cell/docs/README.md'), 46 | meta: { 47 | parent: '基础', 48 | }, 49 | }, 50 | { 51 | path: '/col', 52 | // eslint-disable-next-line prettier/prettier 53 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/col/docs/README.md'), 54 | meta: { 55 | parent: '基础', 56 | }, 57 | }, 58 | { 59 | path: '/config-provider', 60 | // eslint-disable-next-line prettier/prettier 61 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/config-provider/docs/README.md'), 62 | meta: { 63 | parent: '基础', 64 | }, 65 | }, 66 | { 67 | path: '/icon', 68 | // eslint-disable-next-line prettier/prettier 69 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/icon/docs/README.md'), 70 | meta: { 71 | parent: '基础', 72 | }, 73 | }, 74 | { 75 | path: '/image', 76 | // eslint-disable-next-line prettier/prettier 77 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/image/docs/README.md'), 78 | meta: { 79 | parent: '基础', 80 | }, 81 | }, 82 | { 83 | path: '/lazy', 84 | // eslint-disable-next-line prettier/prettier 85 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/lazy/docs/README.md'), 86 | meta: { 87 | parent: '基础', 88 | }, 89 | }, 90 | { 91 | path: '/row', 92 | // eslint-disable-next-line prettier/prettier 93 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/row/docs/README.md'), 94 | meta: { 95 | parent: '基础', 96 | }, 97 | }, 98 | { 99 | path: '/tag', 100 | // eslint-disable-next-line prettier/prettier 101 | component: () => import('/Users/daipengpeng/works/Lin/lin-ui-vue/packages/ui/src/tag/docs/README.md'), 102 | meta: { 103 | parent: '基础', 104 | }, 105 | }, 106 | ] 107 | -------------------------------------------------------------------------------- /packages/ui/site/pc/routes/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory } from 'vue-router' 2 | import routes from '../route' 3 | 4 | const router = createRouter({ 5 | history: createWebHashHistory(), 6 | scrollBehavior: () => ({ top: 0 }), 7 | routes: [ 8 | { 9 | path: '/', 10 | component: import('../components/AppLayout.vue'), 11 | children: [...routes], 12 | }, 13 | { 14 | path: '/index', 15 | component: import('../pages/index/index.vue'), 16 | }, 17 | ], 18 | }) 19 | 20 | export default router 21 | -------------------------------------------------------------------------------- /packages/ui/site/pc/style/hljs.scss: -------------------------------------------------------------------------------- 1 | .lin-ui-doc { 2 | .hljs { 3 | display: block; 4 | overflow-x: auto; 5 | background: #e9f0f8; 6 | border-radius: 6px; 7 | } 8 | 9 | .hljs code { 10 | padding: 10px 20px; 11 | display: block; 12 | font-size: 14px; 13 | color: #333; 14 | line-height: 30px; 15 | } 16 | 17 | .hljs-tag { 18 | color: #6a46d1 19 | } 20 | 21 | .hljs-attr { 22 | color: #6a46d1 23 | } 24 | 25 | .hljs-string { 26 | color: #7ec699; 27 | } 28 | 29 | 30 | .hljs-keyword { 31 | color: #6a46d1; 32 | font-style: italic 33 | } 34 | 35 | .hljs-function { 36 | color: #333 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /packages/ui/site/pc/style/index.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | .h1-icon { 4 | padding-left: 30px; 5 | position: relative; 6 | &::after { 7 | content: " "; 8 | display: block; 9 | width: 30px; 10 | height: 30px; 11 | background-image: url(../assets/images/h1-Icon.jpg); 12 | position: absolute; 13 | top: 50%; 14 | left: 0; 15 | margin-top: -15px; 16 | } 17 | } 18 | 19 | blockquote { 20 | font-size: 1rem; 21 | color: #999; 22 | border-left: 4px solid #dfe2e5; 23 | margin-left: 0; 24 | padding-left: 12px; 25 | } 26 | 27 | .lin-doc-card { 28 | margin-top: 20px; 29 | h3 { 30 | border-bottom: 1px solid #eaecef; 31 | line-height: 30px; 32 | padding-bottom: 5px; 33 | color: #45526b; 34 | font-size: 24px; 35 | font-weight: 500; 36 | } 37 | code { 38 | color: #3683d6; 39 | background: #e4f1ff; 40 | padding: 0 4px; 41 | font-size: 14px; 42 | line-height: 14px; 43 | margin: 0 4px; 44 | } 45 | } 46 | 47 | .custom-block{ 48 | margin: 20px 0; 49 | border-left-width: 4px; 50 | border-left-style: solid; 51 | padding: 0 30px; 52 | .custom-block-title { 53 | padding: 14px 0; 54 | font-weight: lighter; 55 | } 56 | .custom-block-content { 57 | padding-bottom: 14px; 58 | } 59 | &.warning { 60 | background: rgba(255,229,100,.3); 61 | border-color: #e7c000; 62 | } 63 | &.tips { 64 | background: #eff7ff; 65 | border-color: #3683d6; 66 | } 67 | &.info { 68 | background: #f4f4f5; 69 | border-color: #909399; 70 | } 71 | &.error { 72 | background: #FEF4F4; 73 | border-color: #f4506c; 74 | } 75 | } -------------------------------------------------------------------------------- /packages/ui/src/avatar/Avatar.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 23 | -------------------------------------------------------------------------------- /packages/ui/src/avatar/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: avatar avatar 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/avatar' 7 | --- 8 | 9 | # avatar 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | ### Title-1 13 | 14 | 使用介绍 15 | 16 | ```html 17 | 22 | ``` -------------------------------------------------------------------------------- /packages/ui/src/avatar/example/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/ui/src/avatar/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import Avatar from './Avatar.vue' 3 | 4 | Avatar.install = function (app: App) { 5 | app.component(Avatar.name, Avatar) 6 | } 7 | 8 | export default Avatar 9 | -------------------------------------------------------------------------------- /packages/ui/src/avatar/props.ts: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue' 2 | 3 | export const props = {} 4 | -------------------------------------------------------------------------------- /packages/ui/src/button/Button.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 40 | -------------------------------------------------------------------------------- /packages/ui/src/button/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 按钮 Button 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/button' 7 | --- 8 | 9 | # 按钮 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | > 常用的操作按钮 13 | 14 | ### 主题色按钮 15 | 16 | 通过设置`type`属性为`default`、success、error、warning来创建不同样式的Button,样式默认为default。 17 | 18 | ```html 19 | 27 | ``` 28 | ::: warning 29 | **使用 Lin UI 务必勾选`Es6 转 ES5`和`使用 npm 模块`选项** 30 | ::: 31 | 32 | ::: error 33 | WARNING 2222 34 | ::: 35 | 36 | ::: info 37 | 友情提示 38 | WARNING 2222 39 | ::: -------------------------------------------------------------------------------- /packages/ui/src/button/example/index.vue: -------------------------------------------------------------------------------- 1 | 92 | 93 | 98 | 105 | -------------------------------------------------------------------------------- /packages/ui/src/button/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import Button from './Button.vue' 3 | 4 | Button.install = function (app: App) { 5 | app.component(Button.name, Button) 6 | } 7 | 8 | export const _ButtonComponent = Button 9 | 10 | export default Button 11 | -------------------------------------------------------------------------------- /packages/ui/src/button/props.ts: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue' 2 | 3 | function typeValidator(type: string): boolean { 4 | return ['default', 'primary', 'success', 'warning', 'error'].includes(type) 5 | } 6 | 7 | function sizeValidator(size: string): boolean { 8 | return ['normal', 'mini', 'small', 'large'].includes(size) 9 | } 10 | 11 | function shapeValidator(shape: string): boolean { 12 | return ['square', 'circle', 'semicircle', 'round'].includes(shape) 13 | } 14 | 15 | export const props = { 16 | type: { 17 | type: String as PropType< 18 | 'default' | 'primary' | 'warning' | 'error' | 'success' 19 | >, 20 | default: 'default', 21 | validator: typeValidator, 22 | }, 23 | size: { 24 | type: String as PropType<'normal' | 'mini' | 'small' | 'large'>, 25 | default: 'normal', 26 | validator: sizeValidator, 27 | }, 28 | disabled: { 29 | type: Boolean, 30 | default: false, 31 | }, 32 | text: { 33 | type: Boolean, 34 | default: false, 35 | }, 36 | plain: { 37 | type: Boolean, 38 | default: false, 39 | }, 40 | shape: { 41 | type: String as PropType<'square' | 'circle' | 'semicircle' | 'round'>, 42 | default: 'square', 43 | validator: shapeValidator, 44 | }, 45 | block: { 46 | type: Boolean, 47 | default: false, 48 | }, 49 | } 50 | -------------------------------------------------------------------------------- /packages/ui/src/button/utils/index.ts: -------------------------------------------------------------------------------- 1 | export interface A { 2 | name: string 3 | } 4 | -------------------------------------------------------------------------------- /packages/ui/src/cell/Cell.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 23 | -------------------------------------------------------------------------------- /packages/ui/src/cell/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cell 单元格 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/Cell' 7 | --- 8 | 9 | # Cell 单元格 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | ### Title-1 13 | 14 | 使用介绍 15 | 16 | ```html 17 | 22 | ``` -------------------------------------------------------------------------------- /packages/ui/src/cell/example/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/ui/src/cell/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import Cell from './Cell.vue' 3 | 4 | Cell.install = function (app: App) { 5 | app.component(Cell.name, Cell) 6 | } 7 | 8 | export default Cell 9 | -------------------------------------------------------------------------------- /packages/ui/src/cell/props.ts: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue' 2 | 3 | export const propsDefine = { 4 | title: { 5 | type: [Number, String], 6 | default: '', 7 | }, 8 | value: { 9 | type: [Number, String], 10 | default: '', 11 | }, 12 | label: { 13 | type: [Number, String], 14 | default: '', 15 | }, 16 | isLink: { 17 | type: Boolean, 18 | default: false, 19 | }, 20 | url: { 21 | type: String, 22 | }, 23 | to: { 24 | type: [String, Object], 25 | }, 26 | } 27 | -------------------------------------------------------------------------------- /packages/ui/src/col/Col.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 53 | -------------------------------------------------------------------------------- /packages/ui/src/col/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: col Col 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/col' 7 | --- 8 | 9 | # col Col 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | ### Title-1 13 | 14 | 使用介绍 15 | 16 | ```html 17 | 22 | ``` -------------------------------------------------------------------------------- /packages/ui/src/col/example/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/ui/src/col/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import Col from './Col.vue' 3 | 4 | Col.install = function (app: App) { 5 | app.component(Col.name, Col) 6 | } 7 | 8 | export default Col 9 | -------------------------------------------------------------------------------- /packages/ui/src/col/props.ts: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue' 2 | 3 | export const propsDefine = { 4 | span: { 5 | type: [Number, String], 6 | }, 7 | offset: { 8 | type: [Number, String], 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /packages/ui/src/col/provider.ts: -------------------------------------------------------------------------------- 1 | import { ROW_BIND_COL_KEY, ProvideValue } from '../row/provider' 2 | import useParent from '../utils/hooks/useParent' 3 | 4 | export default function useRow() { 5 | const { parent, index } = useParent(ROW_BIND_COL_KEY) 6 | const spaces = parent?.spaces 7 | 8 | return { 9 | spaces, 10 | index, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/ui/src/config-provider/ConfigProvider.vue: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /packages/ui/src/config-provider/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: config-provider config-provider 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/config-provider' 7 | --- 8 | 9 | # config-provider 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | ### Title-1 13 | 14 | 使用介绍 15 | 16 | ```html 17 | 22 | ``` -------------------------------------------------------------------------------- /packages/ui/src/config-provider/example/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/ui/src/config-provider/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import ConfigProvider from './ConfigProvider.vue' 3 | 4 | ConfigProvider.install = function (app: App) { 5 | app.component(ConfigProvider.name, ConfigProvider) 6 | } 7 | 8 | export default ConfigProvider 9 | -------------------------------------------------------------------------------- /packages/ui/src/config-provider/props.ts: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue' 2 | 3 | export const props = { 4 | size: { 5 | type: String, 6 | default: '', 7 | }, 8 | locale: { 9 | type: String, 10 | default: 'zh_CN', 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /packages/ui/src/config-provider/provideGlobalConfig.ts: -------------------------------------------------------------------------------- 1 | import { provide } from 'vue' 2 | 3 | export function provideGlobalConfig(config: Record) { 4 | // eslint-disable-next-line no-restricted-syntax 5 | for (const key in config) { 6 | if (Object.prototype.hasOwnProperty.call(config, key)) { 7 | provide(key, config[key]) 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/ui/src/icon/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 图标 Icon 3 | level: 2 4 | order: 2 5 | parent: 基础 6 | routePath: '/icon' 7 | --- 8 | 9 | # 按钮 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | > 常用的操作按钮 13 | 14 | ### 主题色按钮 15 | 16 | 通过设置`type`属性为`default`、success、error、warning来创建不同样式的Button,样式默认为default。 17 | 18 | ```html 19 | import AccountFilled from '@lin-ui-vue/icons' 20 | 25 | ``` -------------------------------------------------------------------------------- /packages/ui/src/icon/example/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/ui/src/icon/icon.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /packages/ui/src/icon/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import Icon from './icon.vue' 3 | 4 | Icon.install = function (app: App) { 5 | app.component(Icon.name, Icon) 6 | } 7 | 8 | export default Icon 9 | -------------------------------------------------------------------------------- /packages/ui/src/image/Image.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 52 | -------------------------------------------------------------------------------- /packages/ui/src/image/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: image 图片 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/image' 7 | --- 8 | 9 | # image 图片 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | ### Title-1 13 | 14 | 使用介绍 15 | 16 | ```html 17 | 22 | ``` -------------------------------------------------------------------------------- /packages/ui/src/image/example/index.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | 56 | 57 | 62 | -------------------------------------------------------------------------------- /packages/ui/src/image/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import Image from './Image.vue' 3 | 4 | Image.install = function (app: App) { 5 | app.component(Image.name, Image) 6 | } 7 | 8 | export default Image 9 | -------------------------------------------------------------------------------- /packages/ui/src/image/props.ts: -------------------------------------------------------------------------------- 1 | import type { PropType, DefineComponent } from 'vue' 2 | import { pixelPropValidator } from '../utils' 3 | 4 | const fitValidator = (fit: string): boolean => { 5 | return ['fill', 'contain', 'cover', 'none', 'scale-down'].includes(fit) 6 | } 7 | 8 | export const propsDefine = { 9 | src: { 10 | type: String, 11 | default: '', 12 | }, 13 | alt: { 14 | type: String, 15 | }, 16 | fit: { 17 | type: String as PropType< 18 | 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' 19 | >, 20 | default: 'fill', 21 | validator: fitValidator, 22 | }, 23 | position: { 24 | type: String as PropType< 25 | 'left' | 'right' | 'center' | 'top' | 'bottom' | string 26 | >, 27 | }, 28 | width: { 29 | type: [Number, String], 30 | validator: pixelPropValidator('width'), 31 | }, 32 | height: { 33 | type: [Number, String], 34 | validator: pixelPropValidator('height'), 35 | }, 36 | radius: { 37 | type: [Number, String], 38 | default: 0, 39 | validator: pixelPropValidator('radius'), 40 | }, 41 | round: { 42 | type: Boolean, 43 | default: false, 44 | }, 45 | lazy: { 46 | type: Boolean, 47 | default: false, 48 | }, 49 | lazyError: { 50 | type: String, 51 | }, 52 | lazyLoading: { 53 | type: String, 54 | }, 55 | } 56 | -------------------------------------------------------------------------------- /packages/ui/src/lazy/Lazy.ts: -------------------------------------------------------------------------------- 1 | import type { DirectiveBinding } from 'vue' 2 | import { LazyOptions, State, GlobalLazyOptions, StateOptions } from './types' 3 | import ImageManager, { loadImage } from './imageManger' 4 | import { DEFAULT_LOADING, DEFAULT_ERROR } from './constant' 5 | 6 | class Lazy { 7 | loading: NonNullable = '' 8 | 9 | error: NonNullable = '' 10 | 11 | cache: Set = new Set([]) 12 | 13 | managerQueue: ImageManager[] = [] 14 | 15 | observer?: IntersectionObserver 16 | 17 | constructor(options?: GlobalLazyOptions) { 18 | Promise.all([ 19 | this.initGlobalLoading(options?.loading || DEFAULT_LOADING), 20 | this.initGlobalError(options?.error || DEFAULT_ERROR), 21 | ]).then(() => { 22 | this.managerQueue = [] 23 | this.cache = new Set([]) 24 | this.init() 25 | }) 26 | } 27 | 28 | async initGlobalLoading(loading: StateOptions) { 29 | if (typeof loading === 'string') { 30 | this.loading = (await this.checkImage(loading)) || DEFAULT_LOADING 31 | } else { 32 | this.loading = loading 33 | } 34 | } 35 | 36 | async initGlobalError(error: StateOptions) { 37 | if (typeof error === 'string') { 38 | this.error = (await this.checkImage(error)) || DEFAULT_ERROR 39 | } else { 40 | this.error = error 41 | } 42 | } 43 | 44 | init() { 45 | this.observer = new IntersectionObserver( 46 | (entries) => { 47 | entries.forEach((entry) => { 48 | if (entry.isIntersecting) { 49 | const manager = this.managerQueue.find( 50 | (manager) => manager.el === entry.target 51 | ) 52 | if (manager) { 53 | if (manager.state === State.LOADED) { 54 | this.removeManager(manager) 55 | return 56 | } 57 | manager.load() 58 | } 59 | } 60 | }) 61 | }, 62 | { 63 | rootMargin: '0px', 64 | threshold: 0, 65 | } 66 | ) 67 | } 68 | 69 | async mounted( 70 | el: HTMLElement, 71 | binding: DirectiveBinding 72 | ) { 73 | const arg = binding.arg === undefined ? 'image' : 'background' 74 | const { src, error, loading } = await this.formatValue(binding.value) 75 | const manager = new ImageManager({ 76 | el, 77 | src, 78 | arg, 79 | error, 80 | loading, 81 | }) 82 | this.managerQueue.push(manager) 83 | this.observer?.observe(el) 84 | } 85 | 86 | async update( 87 | el: HTMLElement, 88 | binding: DirectiveBinding 89 | ) { 90 | const { src, error, loading } = await this.formatValue(binding.value) 91 | const manager = this.managerQueue.find((manager) => { 92 | return manager.el === el 93 | }) 94 | if (manager) { 95 | manager.update({ 96 | src, 97 | error, 98 | loading, 99 | }) 100 | } 101 | } 102 | 103 | unmount(el: HTMLElement): void { 104 | const manager = this.managerQueue.find((manager) => { 105 | return manager.el === el 106 | }) 107 | if (manager) { 108 | this.removeManager(manager) 109 | } 110 | } 111 | 112 | removeManager(manger: ImageManager) { 113 | const index = this.managerQueue.indexOf(manger) 114 | if (index > -1) { 115 | this.managerQueue.slice(index, 1) 116 | } 117 | this.observer?.unobserve(manger.el) 118 | } 119 | 120 | async formatValue(value: string | LazyOptions) { 121 | if (typeof value === 'string') { 122 | value = { 123 | src: value, 124 | error: this.error, 125 | loading: this.loading, 126 | } 127 | } 128 | 129 | let { error = this.error, loading = this.loading } = value 130 | if (typeof error === 'string') { 131 | error = (await this.checkImage(error)) || this.error 132 | } 133 | 134 | if (typeof loading === 'string') { 135 | loading = (await this.checkImage(loading)) || this.loading 136 | } 137 | 138 | return { 139 | src: value.src, 140 | loading, 141 | error, 142 | } 143 | } 144 | 145 | async checkImage(src: string) { 146 | if (this.cache.has(src)) { 147 | return src 148 | } 149 | try { 150 | await loadImage(src) 151 | this.cache.add(src) 152 | return src 153 | } catch (error) { 154 | return null 155 | } 156 | } 157 | } 158 | 159 | export default Lazy 160 | -------------------------------------------------------------------------------- /packages/ui/src/lazy/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lazy 懒加载 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/lazy' 7 | --- 8 | 9 | # lazy 懒加载 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | ### Title-1 13 | 14 | 使用介绍 15 | 16 | ```html 17 | 22 | ``` -------------------------------------------------------------------------------- /packages/ui/src/lazy/example/imageError.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 21 | -------------------------------------------------------------------------------- /packages/ui/src/lazy/example/index.vue: -------------------------------------------------------------------------------- 1 | 52 | 53 | 112 | 120 | -------------------------------------------------------------------------------- /packages/ui/src/lazy/imageManger.ts: -------------------------------------------------------------------------------- 1 | import { render, h } from 'vue' 2 | import { State, ImageManagerOptions, LazyOptions, StateOptions } from './types' 3 | 4 | export type LazyHTMLElement = HTMLElement & { _lazy: ImageManger } 5 | 6 | export function loadImage(src: string) { 7 | return new Promise((resolve, reject) => { 8 | const image = new Image() 9 | image.src = src 10 | 11 | image.onload = () => { 12 | resolve() 13 | } 14 | image.onerror = (e) => { 15 | reject(e) 16 | } 17 | }) 18 | } 19 | 20 | export default class ImageManger { 21 | el: LazyHTMLElement 22 | 23 | src: string 24 | 25 | arg: 'background' | 'image' 26 | 27 | error: StateOptions 28 | 29 | loading: StateOptions 30 | 31 | state: State 32 | 33 | constructor(options: ImageManagerOptions) { 34 | const el = options.el as LazyHTMLElement 35 | el._lazy = this 36 | this.el = el 37 | this.src = options.src 38 | this.error = options.error 39 | this.loading = options.loading 40 | this.state = State.LOADING 41 | this.arg = options.arg || 'image' 42 | 43 | this.renderLoading() 44 | } 45 | 46 | load() { 47 | if (this.state === State.LOADING) { 48 | this.loadImage() 49 | } 50 | } 51 | 52 | reload() { 53 | this.state = State.LOADING 54 | this.load() 55 | } 56 | 57 | update({ error, loading, src }: Required) { 58 | this.error = error 59 | this.loading = loading 60 | if (src === this.src) { 61 | this.state === State.ERROR && this.removeError() 62 | this.state === State.LOADING && this.removeLoading() 63 | } else { 64 | this.src = src 65 | this.state = State.LOADING 66 | this.load() 67 | } 68 | } 69 | 70 | render(src: StateOptions) { 71 | if (typeof src === 'string') { 72 | this.arg === 'image' && this.el.setAttribute('src', src) 73 | if (this.arg === 'background') { 74 | this.el.style.backgroundImage = `url(${src})` 75 | } 76 | } 77 | } 78 | 79 | renderError() { 80 | if (typeof this.error === 'string') { 81 | this.render(this.error) 82 | } else { 83 | const { component: errorComponent, props } = this.error 84 | const container = 85 | this.arg === 'image' ? (this.el.parentElement as HTMLElement) : this.el 86 | render( 87 | h('div', { class: 'lin-lazy-error' }, h(errorComponent, props)), 88 | container 89 | ) 90 | this.arg === 'image' && (this.el.style.display = 'none') 91 | } 92 | } 93 | 94 | renderLoading() { 95 | if (typeof this.loading === 'string') { 96 | this.render(this.loading) 97 | } else { 98 | const { component: errorComponent, props } = this.loading 99 | const container = 100 | this.arg === 'image' ? (this.el.parentElement as HTMLElement) : this.el 101 | render( 102 | h('div', { class: 'lin-lazy-loading' }, h(errorComponent, props)), 103 | container 104 | ) 105 | this.arg === 'image' && (this.el.style.display = 'none') 106 | } 107 | } 108 | 109 | removeLoading() { 110 | const children = this.el.parentElement?.children 111 | if (!children) return 112 | let loadingEl = null 113 | for (let i = 0; i < children.length; i++) { 114 | if (children[i].className === 'lin-lazy-loading') { 115 | loadingEl = children[i] 116 | } 117 | } 118 | loadingEl && loadingEl.remove() 119 | } 120 | 121 | removeError() { 122 | const children = this.el.parentElement?.children 123 | if (!children) return 124 | let errorEl = null 125 | for (let i = 0; i < children.length; i++) { 126 | if (children[i].className === 'lin-lazy-error') { 127 | errorEl = children[i] 128 | } 129 | } 130 | errorEl && errorEl.remove() 131 | } 132 | 133 | async loadImage() { 134 | try { 135 | await loadImage(this.src) 136 | this.render(this.src) 137 | this.state = State.LOADED 138 | this.el._lazy.state = State.LOADED 139 | this.removeError() 140 | this.el.style.display = 'block' 141 | this.removeLoading() 142 | } catch (error) { 143 | this.state = State.ERROR 144 | this.el._lazy.state = State.ERROR 145 | this.removeLoading() 146 | this.renderError() 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /packages/ui/src/lazy/index.ts: -------------------------------------------------------------------------------- 1 | import type { App, Directive, Plugin } from 'vue' 2 | import LazyDirective from './Lazy' 3 | 4 | const Lazy: Directive & Plugin = { 5 | install(app: App) { 6 | const lazy = new LazyDirective() 7 | 8 | app.directive('lin-lazy', { 9 | mounted: lazy.mounted.bind(lazy), 10 | updated: lazy.update.bind(lazy), 11 | unmounted: lazy.unmount.bind(lazy), 12 | }) 13 | }, 14 | } 15 | 16 | export default Lazy 17 | -------------------------------------------------------------------------------- /packages/ui/src/lazy/types.ts: -------------------------------------------------------------------------------- 1 | import type { DefineComponent } from 'vue' 2 | 3 | export type StateOptions = 4 | | string 5 | | { 6 | component: DefineComponent 7 | props: Record 8 | } 9 | 10 | export interface GlobalLazyOptions { 11 | error?: StateOptions 12 | loading?: StateOptions 13 | } 14 | 15 | export interface LazyOptions extends GlobalLazyOptions { 16 | src: string 17 | } 18 | 19 | export enum State { 20 | LOADING, 21 | LOADED, 22 | ERROR, 23 | } 24 | 25 | export interface ImageManagerOptions extends Required { 26 | el: HTMLElement 27 | arg?: 'background' | 'image' 28 | } 29 | -------------------------------------------------------------------------------- /packages/ui/src/locale/en-US.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | title: 'title', 3 | } 4 | -------------------------------------------------------------------------------- /packages/ui/src/locale/index.ts: -------------------------------------------------------------------------------- 1 | import zhCN from './zh-CN' 2 | import enUS from './en-US' 3 | 4 | export default { 5 | zhCN, 6 | enUS, 7 | } 8 | -------------------------------------------------------------------------------- /packages/ui/src/locale/zh-CN.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | title: '标题', 3 | } 4 | -------------------------------------------------------------------------------- /packages/ui/src/row/Row.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 73 | -------------------------------------------------------------------------------- /packages/ui/src/row/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: row Row 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/row' 7 | --- 8 | 9 | # row Row 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | ### Title-1 13 | 14 | 使用介绍 15 | 16 | ```html 17 | 22 | ``` -------------------------------------------------------------------------------- /packages/ui/src/row/example/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /packages/ui/src/row/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import Row from './Row.vue' 3 | 4 | Row.install = function (app: App) { 5 | app.component(Row.name, Row) 6 | } 7 | 8 | export default Row 9 | -------------------------------------------------------------------------------- /packages/ui/src/row/props.ts: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue' 2 | 3 | export const propsDefine = { 4 | gutter: { 5 | type: [String, Number], 6 | default: 0, 7 | }, 8 | justify: { 9 | type: String as PropType< 10 | | 'flex-start' 11 | | 'flex-end' 12 | | 'center' 13 | | 'end' 14 | | 'start' 15 | | 'space-between' 16 | | 'space-around' 17 | >, 18 | default: 'start', 19 | }, 20 | align: { 21 | type: String as PropType<'flex-start' | 'flex-end' | 'center'>, 22 | default: 'flex-start', 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /packages/ui/src/row/provider.ts: -------------------------------------------------------------------------------- 1 | import type { ComputedRef } from 'vue' 2 | import useChildren from '../utils/hooks/useChildren' 3 | 4 | export const ROW_BIND_COL_KEY = Symbol('ROW_BIND_COL_KEY') 5 | export const ROW_COUNT_COL_KEY = Symbol('ROW_COUNT_COL_KEY') 6 | 7 | export interface ProvideValue { 8 | spaces: ComputedRef<{ left?: number; right: number }[]> 9 | } 10 | 11 | export function useCols() { 12 | const { linkChildren, children } = useChildren(ROW_BIND_COL_KEY) 13 | 14 | return { 15 | cols: children, 16 | bindCols: linkChildren, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/ui/src/tag/Tag.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 43 | -------------------------------------------------------------------------------- /packages/ui/src/tag/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: tag tag 3 | level: 2 4 | order: 1 5 | parent: 基础 6 | routePath: '/tag' 7 | --- 8 | 9 | # tag 10 | Lin UI 致力于给小程序开发者提供愉悦的开发体验。 11 | 12 | ### Title-1 13 | 14 | 使用介绍 15 | 16 | ```html 17 | 22 | ``` -------------------------------------------------------------------------------- /packages/ui/src/tag/example/index.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 55 | 60 | -------------------------------------------------------------------------------- /packages/ui/src/tag/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import Tag from './Tag.vue' 3 | 4 | Tag.install = function (app: App) { 5 | app.component(Tag.name, Tag) 6 | } 7 | 8 | export default Tag 9 | -------------------------------------------------------------------------------- /packages/ui/src/tag/props.ts: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue' 2 | 3 | function typeValidator(type: string): boolean { 4 | return ['default', 'primary', 'success', 'warning', 'error'].includes(type) 5 | } 6 | 7 | function sizeValidator(size: string): boolean { 8 | return ['normal', 'mini', 'small', 'large'].includes(size) 9 | } 10 | 11 | function effectValidator(effect: string): boolean { 12 | return ['dark', 'light', 'plain'].includes(effect) 13 | } 14 | 15 | export const props = { 16 | type: { 17 | type: String as PropType< 18 | 'default' | 'primary' | 'warning' | 'error' | 'success' 19 | >, 20 | default: 'default', 21 | validator: typeValidator, 22 | }, 23 | size: { 24 | type: String as PropType<'normal' | 'mini' | 'small' | 'large'>, 25 | default: 'normal', 26 | validator: sizeValidator, 27 | }, 28 | closeable: { 29 | type: Boolean, 30 | default: false, 31 | }, 32 | effect: { 33 | type: String as PropType<'dark' | 'light' | 'plain'>, 34 | validator: effectValidator, 35 | }, 36 | round: { 37 | type: [Boolean, String], 38 | default: false, 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /packages/ui/src/theme/Cell.less: -------------------------------------------------------------------------------- 1 | .lin-Cell{} -------------------------------------------------------------------------------- /packages/ui/src/theme/card.less: -------------------------------------------------------------------------------- 1 | 2 | .lin-card{} -------------------------------------------------------------------------------- /packages/ui/src/theme/col.less: -------------------------------------------------------------------------------- 1 | .generate-col(@i) when (@i =< 24) { 2 | .lin-col--span-@{i} { 3 | flex: 0 0 @i * (100% / 24); 4 | } 5 | 6 | .lin-col--offset-@{i} { 7 | margin-left: @i * (100% / 24); 8 | } 9 | 10 | .generate-col(@i + 1); 11 | } 12 | 13 | .generate-col(1); 14 | 15 | .lin-col{ 16 | display: block; 17 | box-sizing: border-box; 18 | } -------------------------------------------------------------------------------- /packages/ui/src/theme/config-provider.less: -------------------------------------------------------------------------------- 1 | 2 | .lin-config-provider{} -------------------------------------------------------------------------------- /packages/ui/src/theme/css-variables.less: -------------------------------------------------------------------------------- 1 | @import './var.less'; 2 | 3 | :root { 4 | --lin-black: @black; 5 | --lin-white: @white; 6 | --lin-gray-1: @gray-1; 7 | --lin-gray-2: @gray-2; 8 | --lin-gray-3: @gray-3; 9 | --lin-gray-4: @gray-4; 10 | --lin-gray-5: @gray-5; 11 | --lin-gray-6: @gray-6; 12 | --lin-gray-7: @gray-7; 13 | --lin-gray-8: @gray-8; 14 | 15 | --lin-red: @red; 16 | --lin-blue: @blue; 17 | --lin-orange: @orange; 18 | --lin-green: @green; 19 | --lin-red-light: @red-light; 20 | --lin-blue-light: @blue-light; 21 | --lin-orange-light: @orange-light; 22 | --lin-green-light: @green-light; 23 | --lin-red-lightest: @red-lightest; 24 | --lin-blue-lightest: @blue-lightest; 25 | --lin-orange-lightest: @orange-lightest; 26 | --lin-green-lightest: @green-lightest; 27 | 28 | --lin-primary-color: @primary-color; 29 | --lin-success-color: @success-color; 30 | --lin-error-color: @error-color; 31 | --lin-warning-color: @warning-color; 32 | --lin-primary-color-light: @primary-color-light; 33 | --lin-success-color-light: @success-color-light; 34 | --lin-error-color-light: @error-color-light; 35 | --lin-warning-color-light: @warning-color-light; 36 | --lin-primary-color-lightest: @primary-color-lightest; 37 | --lin-success-color-lightest: @success-color-lightest; 38 | --lin-error-color-lightest: @error-color-lightest; 39 | --lin-warning-color-lightest: @warning-color-lightest; 40 | 41 | --lin-text-color: @text-color; 42 | --lin-text-color-2: @text-color-2; 43 | --lin-text-color-3: @text-color-3; 44 | 45 | --lin-padding-base: @padding-base; 46 | --lin-padding-xs: @padding-xs; 47 | --lin-padding-sm: @padding-sm; 48 | --lin-padding-md: @padding-md; 49 | --lin-padding-lg: @padding-lg; 50 | --lin-padding-xl: @padding-xl; 51 | 52 | --lin-font-size-xs: @font-size-xs; 53 | --lin-font-size-sm: @font-size-sm; 54 | --lin-font-size-md: @font-size-md; 55 | --lin-font-size-lg: @font-size-lg; 56 | 57 | --lin-line-height-xs: @line-height-xs; 58 | --lin-line-height-sm: @line-height-sm; 59 | --lin-line-height-md: @line-height-md; 60 | --lin-line-height-lg: @line-height-lg; 61 | 62 | --lin-border-color: @border-color; 63 | --lin-border-width-base: @border-width-base; 64 | --lin-border-radius-sm: @border-radius-sm; 65 | --lin-border-radius-md: @border-radius-md; 66 | --lin-border-radius-lg: @border-radius-lg; 67 | --lin-border-radius-xl: @border-radius-xl; 68 | } 69 | -------------------------------------------------------------------------------- /packages/ui/src/theme/example/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /packages/ui/src/theme/image.less: -------------------------------------------------------------------------------- 1 | .lin-image{ 2 | overflow: hidden; 3 | 4 | &__img { 5 | display: block; 6 | width: 100%; 7 | height: 100%; 8 | } 9 | } -------------------------------------------------------------------------------- /packages/ui/src/theme/index.less: -------------------------------------------------------------------------------- 1 | @import './var.less'; 2 | @import './css-variables.less'; 3 | 4 | @import './button.less'; 5 | @import './tag.less'; 6 | @import './config-provider.less'; 7 | @import './card.less'; 8 | @import './image.less'; 9 | @import './lazy.less'; 10 | @import './row.less'; 11 | @import './col.less'; 12 | @import './Cell.less'; -------------------------------------------------------------------------------- /packages/ui/src/theme/lazy.less: -------------------------------------------------------------------------------- 1 | .lin-lazy{} -------------------------------------------------------------------------------- /packages/ui/src/theme/row.less: -------------------------------------------------------------------------------- 1 | .lin-row{ 2 | display: flex; 3 | flex-wrap: wrap; 4 | } -------------------------------------------------------------------------------- /packages/ui/src/theme/tag.less: -------------------------------------------------------------------------------- 1 | 2 | // type 3 | @tag-default-color: var(--lin-text-color); 4 | @tag-default-background-color: var(--lin-white); 5 | @tag-default-border-color: var(--lin-border-color); 6 | 7 | @tag-primary-dark-color: var(--lin-white); 8 | @tag-primary-light-color: var(--lin-primary-color); 9 | @tag-primary-plain-color: var(--lin-primary-color); 10 | 11 | @tag-success-dark-color: var(--lin-white); 12 | @tag-success-light-color: var(--lin-success-color); 13 | @tag-success-plain-color: var(--lin-success-color); 14 | 15 | @tag-error-dark-color: var(--lin-white); 16 | @tag-error-light-color: var(--lin-error-color); 17 | @tag-error-plain-color: var(--lin-error-color); 18 | 19 | @tag-warning-dark-color: var(--lin-white); 20 | @tag-warning-light-color: var(--lin-warning-color); 21 | @tag-warning-plain-color: var(--lin-warning-color); 22 | 23 | @tag-primary-dark-background-color: var(--lin-primary-color); 24 | @tag-primary-light-background-color: var(--lin-primary-color-lightest); 25 | @tag-primary-plain-background-color: var(--lin-white); 26 | 27 | @tag-success-dark-background-color: var(--lin-success-color); 28 | @tag-success-light-background-color: var(--lin-success-color-lightest); 29 | @tag-success-plain-background-color: var(--lin-white); 30 | 31 | @tag-error-dark-background-color: var(--lin-error-color); 32 | @tag-error-light-background-color: var(--lin-error-color-lightest); 33 | @tag-error-plain-background-color: var(--lin-white); 34 | 35 | @tag-warning-dark-background-color: var(--lin-warning-color); 36 | @tag-warning-light-background-color: var(--lin-warning-color-lightest); 37 | @tag-warning-plain-background-color: var(--lin-white); 38 | 39 | 40 | @tag-primary-dark-border-color: var(--lin-primary-color); 41 | @tag-primary-light-border-color: var(--lin-primary-color-light); 42 | @tag-primary-plain-border-color: var(--lin-primary-color); 43 | 44 | @tag-success-dark-border-color: var(--lin-success-color); 45 | @tag-success-light-border-color: var(--lin-success-color-light); 46 | @tag-success-plain-border-color: var(--lin-success-color); 47 | 48 | @tag-error-dark-border-color: var(--lin-error-color); 49 | @tag-error-light-border-color: var(--lin-error-color-light); 50 | @tag-error-plain-border-color: var(--lin-error-color); 51 | 52 | @tag-warning-dark-border-color: var(--lin-warning-color); 53 | @tag-warning-light-border-color: var(--lin-warning-color-light); 54 | @tag-warning-plain-border-color: var(--lin-warning-color); 55 | 56 | 57 | // size 58 | @tag-large-height: 42px; 59 | @tag-normal-height: 30px; 60 | @tag-small-height: 24px; 61 | @tag-mini-height: 18px; 62 | 63 | @tag-large-font-size: var(--lin-font-size-lg); 64 | @tag-normal-font-size: var(--lin-font-size-md); 65 | @tag-small-font-size: var(--lin-font-size-sm); 66 | @tag-mini-font-size: var(--lin-font-size-xs); 67 | 68 | @tag-large-padding: 0 var(--lin-padding-lg); 69 | @tag-normal-padding: 0 var(--lin-padding-md); 70 | @tag-small-padding: 0 var(--lin-padding-sm); 71 | @tag-mini-padding: 0 var(--lin-padding-xs); 72 | 73 | @tag-border-width: var(--lin-border-width-base); 74 | 75 | 76 | :root { 77 | --lin-tag-default-color: @tag-default-color; 78 | --lin-tag-default-background-color: @tag-default-background-color; 79 | --lin-tag-default-border-color: @tag-default-border-color; 80 | 81 | --lin-tag-primary-dark-color: @tag-primary-dark-color; 82 | --lin-tag-primary-dark-background-color: @tag-primary-dark-background-color; 83 | --lin-tag-primary-dark-border-color: @tag-primary-dark-border-color; 84 | 85 | --lin-tag-success-dark-color: @tag-success-dark-color; 86 | --lin-tag-success-dark-background-color: @tag-success-dark-background-color; 87 | --lin-tag-success-dark-border-color: @tag-success-dark-border-color; 88 | 89 | --lin-tag-error-dark-color: @tag-error-dark-color; 90 | --lin-tag-error-dark-background-color: @tag-error-dark-background-color; 91 | --lin-tag-error-dark-border-color: @tag-error-dark-border-color; 92 | 93 | --lin-tag-warning-dark-color: @tag-warning-dark-color; 94 | --lin-tag-warning-dark-background-color: @tag-warning-dark-background-color; 95 | --lin-tag-warning-dark-border-color: @tag-warning-dark-border-color; 96 | 97 | --lin-tag-primary-light-color: @tag-primary-light-color; 98 | --lin-tag-primary-light-background-color: @tag-primary-light-background-color; 99 | --lin-tag-primary-light-border-color: @tag-primary-light-border-color; 100 | 101 | --lin-tag-success-light-color: @tag-success-light-color; 102 | --lin-tag-success-light-background-color: @tag-success-light-background-color; 103 | --lin-tag-success-light-border-color: @tag-success-light-border-color; 104 | 105 | --lin-tag-error-light-color: @tag-error-light-color; 106 | --lin-tag-error-light-background-color: @tag-error-light-background-color; 107 | --lin-tag-error-light-border-color: @tag-error-light-border-color; 108 | 109 | --lin-tag-warning-light-color: @tag-warning-light-color; 110 | --lin-tag-warning-light-background-color: @tag-warning-light-background-color; 111 | --lin-tag-warning-light-border-color: @tag-warning-light-border-color; 112 | 113 | --lin-tag-primary-plain-color: @tag-primary-plain-color; 114 | --lin-tag-primary-plain-background-color: @tag-primary-plain-background-color; 115 | --lin-tag-primary-plain-border-color: @tag-primary-plain-border-color; 116 | 117 | --lin-tag-success-plain-color: @tag-success-plain-color; 118 | --lin-tag-success-plain-background-color: @tag-success-plain-background-color; 119 | --lin-tag-success-plain-border-color: @tag-success-plain-border-color; 120 | 121 | --lin-tag-error-plain-color: @tag-error-plain-color; 122 | --lin-tag-error-plain-background-color: @tag-error-plain-background-color; 123 | --lin-tag-error-plain-border-color: @tag-error-plain-border-color; 124 | 125 | --lin-tag-warning-plain-color: @tag-warning-plain-color; 126 | --lin-tag-warning-plain-background-color: @tag-warning-plain-background-color; 127 | --lin-tag-warning-plain-border-color: @tag-warning-plain-border-color; 128 | 129 | 130 | //size 131 | --lin-tag-large-height: @tag-large-height; 132 | --lin-tag-large-padding: @tag-large-padding; 133 | --lin-tag-large-font-size: @tag-large-font-size; 134 | 135 | --lin-tag-normal-height: @tag-normal-height; 136 | --lin-tag-normal-padding: @tag-normal-padding; 137 | --lin-tag-normal-font-size: @tag-normal-font-size; 138 | 139 | --lin-tag-small-height: @tag-small-height; 140 | --lin-tag-small-padding: @tag-small-padding; 141 | --lin-tag-small-font-size: @tag-small-font-size; 142 | 143 | --lin-tag-mini-height: @tag-mini-height; 144 | --lin-tag-mini-padding: @tag-mini-padding; 145 | --lin-tag-mini-font-size: @tag-mini-font-size; 146 | 147 | } 148 | 149 | 150 | .lin-tag { 151 | position: relative; 152 | display: inline-flex; 153 | align-items: center; 154 | 155 | &--default { 156 | color: var(--lin-tag-default-color); 157 | background: var(--lin-tag-default-background-color); 158 | border: 1px solid var(--lin-tag-default-border-color); 159 | } 160 | 161 | &--primary { 162 | color: var(--lin-tag-primary-dark-color); 163 | background: var(--lin-tag-primary-dark-background-color); 164 | border: 1px solid var(--lin-tag-primary-dark-border-color); 165 | } 166 | 167 | &--primary&--light { 168 | color: var(--lin-tag-primary-light-color); 169 | background: var(--lin-tag-primary-light-background-color); 170 | border: 1px solid var(--lin-tag-primary-light-border-color); 171 | } 172 | 173 | &--primary&--plain { 174 | color: var(--lin-tag-primary-plain-color); 175 | background: var(--lin-tag-primary-plain-background-color); 176 | border: 1px solid var(--lin-tag-primary-plain-border-color); 177 | } 178 | 179 | &--success { 180 | color: var(--lin-tag-success-dark-color); 181 | background: var(--lin-tag-success-dark-background-color); 182 | border: 1px solid var(--lin-tag-success-dark-border-color); 183 | } 184 | 185 | &--success&--light { 186 | color: var(--lin-tag-success-light-color); 187 | background: var(--lin-tag-success-light-background-color); 188 | border: 1px solid var(--lin-tag-success-light-border-color); 189 | } 190 | 191 | &--success&--plain { 192 | color: var(--lin-tag-success-plain-color); 193 | background: var(--lin-tag-success-plain-background-color); 194 | border: 1px solid var(--lin-tag-success-plain-border-color); 195 | } 196 | 197 | &--error { 198 | color: var(--lin-tag-error-dark-color); 199 | background: var(--lin-tag-error-dark-background-color); 200 | border: 1px solid var(--lin-tag-error-dark-border-color); 201 | } 202 | 203 | &--error&--light { 204 | color: var(--lin-tag-error-light-color); 205 | background: var(--lin-tag-error-light-background-color); 206 | border: 1px solid var(--lin-tag-error-light-border-color); 207 | } 208 | 209 | &--error&--plain { 210 | color: var(--lin-tag-error-plain-color); 211 | background: var(--lin-tag-error-plain-background-color); 212 | border: 1px solid var(--lin-tag-error-plain-border-color); 213 | } 214 | 215 | &--warning { 216 | color: var(--lin-tag-warning-dark-color); 217 | background: var(--lin-tag-warning-dark-background-color); 218 | border: 1px solid var(--lin-tag-warning-dark-border-color); 219 | } 220 | 221 | &--warning&--light { 222 | color: var(--lin-tag-warning-light-color); 223 | background: var(--lin-tag-warning-light-background-color); 224 | border: 1px solid var(--lin-tag-warning-light-border-color); 225 | } 226 | 227 | &--warning&--plain { 228 | color: var(--lin-tag-warning-plain-color); 229 | background: var(--lin-tag-warning-plain-background-color); 230 | border: 1px solid var(--lin-tag-warning-plain-border-color); 231 | } 232 | 233 | &--normal { 234 | height: var(--lin-tag-normal-height); 235 | padding: var(--lin-tag-normal-padding); 236 | font-size: var(--lin-tag-normal-font-size); 237 | &.is-round{ 238 | border-radius: 6px; 239 | } 240 | } 241 | 242 | &--large { 243 | height: var(--lin-tag-large-height); 244 | padding: var(--lin-tag-large-padding); 245 | font-size: var(--lin-tag-large-font-size); 246 | &.is-round{ 247 | border-radius: 10px; 248 | } 249 | } 250 | 251 | &--small { 252 | height: var(--lin-tag-small-height); 253 | padding: var(--lin-tag-small-padding); 254 | font-size: var(--lin-tag-small-font-size); 255 | &.is-round{ 256 | border-radius: 4px; 257 | } 258 | } 259 | 260 | &--mini { 261 | height: var(--lin-tag-mini-height); 262 | padding: var(--lin-tag-mini-padding); 263 | font-size: var(--lin-tag-mini-font-size); 264 | &.is-round{ 265 | border-radius: 4px; 266 | } 267 | } 268 | } -------------------------------------------------------------------------------- /packages/ui/src/theme/var.less: -------------------------------------------------------------------------------- 1 | @black: #000; 2 | @white: #fff; 3 | @gray-1: #f7f8fa; 4 | @gray-2: #f2f3f5; 5 | @gray-3: #ebedf0; 6 | @gray-4: #dcdee0; 7 | @gray-5: #c8c9cc; 8 | @gray-6: #969799; 9 | @gray-7: #646566; 10 | @gray-8: #333333; 11 | 12 | @red: #F2242E; 13 | @red-light: #F8878C; 14 | @red-lightest: #FEF4F4; 15 | @blue: #4D82FF; 16 | @blue-light: #94B4FF; 17 | @blue-lightest: #F2F6FF; 18 | @orange: #FF9305; 19 | @orange-light: #f3d19e; 20 | @orange-lightest: #FFF8EB; 21 | @green: #1BA17D; 22 | @green-light: #77C7B1; 23 | @green-lightest: #EDF8F1; 24 | 25 | @primary-color: var(--lin-blue); 26 | @success-color: var(--lin-green); 27 | @error-color: var(--lin-red); 28 | @warning-color: var(--lin-orange); 29 | @primary-color-light: var(--lin-blue-light); 30 | @success-color-light: var(--lin-green-light); 31 | @error-color-light: var(--lin-red-light); 32 | @warning-color-light: var(--lin-orange-light); 33 | @primary-color-lightest: var(--lin-blue-lightest); 34 | @success-color-lightest: var(--lin-green-lightest); 35 | @error-color-lightest: var(--lin-red-lightest); 36 | @warning-color-lightest: var(--lin-orange-lightest); 37 | 38 | @text-color: var(--lin-gray-8); 39 | @text-color-2: var(--lin-gray-6); 40 | @text-color-3: var(--lin-gray-5); 41 | 42 | 43 | @padding-base: 4px; 44 | @padding-xs: @padding-base * 2; 45 | @padding-sm: @padding-base * 3; 46 | @padding-md: @padding-base * 4; 47 | @padding-lg: @padding-base * 6; 48 | @padding-xl: @padding-base * 8; 49 | 50 | 51 | @font-size-xs: 10px; 52 | @font-size-sm: 12px; 53 | @font-size-md: 14px; 54 | @font-size-lg: 16px; 55 | 56 | 57 | @line-height-xs: 14px; 58 | @line-height-sm: 18px; 59 | @line-height-md: 20px; 60 | @line-height-lg: 22px; 61 | 62 | @border-color: var(--lin-gray-3); 63 | @border-width-base: 1px; 64 | @border-radius-sm: 2px; 65 | @border-radius-md: 4px; 66 | @border-radius-lg: 8px; 67 | @border-radius-xl: 16px; -------------------------------------------------------------------------------- /packages/ui/src/utils/components.ts: -------------------------------------------------------------------------------- 1 | type ClassName = string 2 | type Classes = (ClassName | [boolean, ClassName, ClassName?])[] 3 | 4 | export function createNamespace(name: string) { 5 | const namespace = `lin-${name}` 6 | 7 | const createBEM = (suffix?: string) => { 8 | if (!suffix) { 9 | return namespace 10 | } 11 | if (suffix.startsWith('--') || suffix.startsWith('__')) { 12 | return `${namespace}${suffix}` 13 | } 14 | 15 | return `${namespace}--${suffix}` 16 | } 17 | 18 | const computedClasses = (...classes: Classes): string[] => { 19 | const realClasses: string[] = [] 20 | classes.forEach((item) => { 21 | if (Array.isArray(item)) { 22 | const [condition, trueCls, falseCls = null] = item 23 | const res = condition ? trueCls : falseCls 24 | res && realClasses.push(res) 25 | } else { 26 | realClasses.push(item) 27 | } 28 | }) 29 | return realClasses 30 | } 31 | 32 | return { 33 | b: createBEM, 34 | computedClasses, 35 | } 36 | } 37 | 38 | export function createComponentName(name: string) { 39 | const prefix = 'Lin' 40 | 41 | const camelName = name.charAt(0).toUpperCase() + name.slice(1) 42 | return `${prefix}${camelName}` 43 | } 44 | -------------------------------------------------------------------------------- /packages/ui/src/utils/hooks/useChildren.ts: -------------------------------------------------------------------------------- 1 | import { reactive, provide, ComponentInternalInstance, InjectionKey } from 'vue' 2 | 3 | export type ParentProvide = T & { 4 | link(child: ComponentInternalInstance): void 5 | unlink(child: ComponentInternalInstance): void 6 | children: ComponentInternalInstance[] 7 | } 8 | 9 | export default function useChildren( 10 | key: InjectionKey> 11 | ) { 12 | const children: ComponentInternalInstance[] = reactive([]) 13 | 14 | const linkChildren = (value?: ProvideValue) => { 15 | const link = (child: ComponentInternalInstance) => { 16 | children.push(child) 17 | } 18 | const unlink = (child: ComponentInternalInstance) => { 19 | const index: number = children.indexOf(child) 20 | if (index > -1) { 21 | children.splice(index, 1) 22 | } 23 | } 24 | 25 | provide(key, { 26 | link, 27 | unlink, 28 | children, 29 | ...value, 30 | }) 31 | } 32 | 33 | return { 34 | linkChildren, 35 | children, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/ui/src/utils/hooks/useParent.ts: -------------------------------------------------------------------------------- 1 | import { 2 | getCurrentInstance, 3 | inject, 4 | onUnmounted, 5 | computed, 6 | ref, 7 | ComponentInternalInstance, 8 | InjectionKey, 9 | } from 'vue' 10 | import { ParentProvide } from './useChildren' 11 | 12 | // type ParentProvide = T & { 13 | // link(child: ComponentInternalInstance): void 14 | // unlink(child: ComponentInternalInstance): void 15 | // children: ComponentInternalInstance[] 16 | // } 17 | 18 | export default function useParent(key: InjectionKey>) { 19 | const parent = inject(key, null) 20 | if (parent) { 21 | const instance = getCurrentInstance() as ComponentInternalInstance 22 | const { link, unlink, children } = parent 23 | 24 | const index = computed(() => children.indexOf(instance)) 25 | 26 | link(instance) 27 | 28 | onUnmounted(() => unlink(instance)) 29 | 30 | return { 31 | parent, 32 | index, 33 | } 34 | } 35 | return { 36 | parent, 37 | index: ref(-1), 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/ui/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export const isPixel = (value: any) => { 2 | if (typeof value !== 'string') return false 3 | const reg = /(\d+(\.\d*)?)+(px|rem|vh|vw|em|%)/gi 4 | return reg.test(value) 5 | } 6 | 7 | export const pixelPropValidator = (key: string, canNumber = true) => { 8 | return function (value: any) { 9 | if (canNumber && typeof value === 'number') return true 10 | const isValidate = isPixel(value) 11 | !isValidate && 12 | console.warn( 13 | `prop ${key} 传入值:${value} 不合法; prop ${key} 需要传入像素单位: [em、rem、px、vh、vw、%${ 14 | canNumber ? '、number' : '' 15 | }]` 16 | ) 17 | return isValidate 18 | } 19 | } 20 | 21 | export const formatPixel = (value: any) => { 22 | if (typeof value === 'number') return `${value}px` 23 | return value 24 | } 25 | 26 | export const warn = (component: string | null, content: string) => { 27 | console.warn(`${component ? `lin-${component}` : ''}: ${content}`) 28 | } 29 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "esnext", 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "jsx": "preserve", 10 | "skipLibCheck": true, 11 | "allowJs": true, 12 | "useDefineForClassFields": true, 13 | "sourceMap": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": false, 16 | "lib": ["esnext", "dom"], 17 | "declaration": false, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/ui/types/button.d.ts: -------------------------------------------------------------------------------- 1 | import { Component } from './linComponent' 2 | 3 | export interface ButtonProps {} 4 | 5 | export class Button extends Component { 6 | $props: ButtonProps 7 | } 8 | 9 | export class _ButtonComponent extends Button {} 10 | -------------------------------------------------------------------------------- /packages/ui/types/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'vue' { 2 | export interface GlobalComponents { 3 | LinButton: typeof import('@lin-ui-vue/ui')['_ButtonComponent'] 4 | } 5 | } 6 | 7 | export {} 8 | -------------------------------------------------------------------------------- /packages/ui/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | 3 | export const install: (app: App) => void 4 | 5 | export * from './button' 6 | export * from './linComponent' 7 | -------------------------------------------------------------------------------- /packages/ui/types/linComponent.d.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | 3 | export class Component { 4 | static name: string 5 | 6 | static install(app: App): void 7 | } 8 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/*" 3 | --------------------------------------------------------------------------------