├── .npmrc ├── .prettierignore ├── packages ├── components │ ├── .gitignore │ ├── alert │ │ ├── style │ │ │ └── index.ts │ │ ├── src │ │ │ ├── interface.d.ts │ │ │ └── alert.vue │ │ ├── index.ts │ │ └── __tests__ │ │ │ └── alert.test.ts │ ├── dialog │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── __tests__ │ │ │ └── dialog.test.ts │ │ └── src │ │ │ └── dialog.vue │ ├── progress │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── __test__ │ │ │ └── progress.test.ts │ │ └── src │ │ │ └── progress.vue │ ├── slider │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ └── __tests__ │ │ │ └── slider.test.ts │ ├── upload │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ └── __tests__ │ │ │ └── upload.test.ts │ ├── backtop │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── __tests__ │ │ │ └── backtop.test.ts │ │ └── src │ │ │ └── backtop.vue │ ├── checkbox │ │ ├── style │ │ │ └── index.ts │ │ ├── composables │ │ │ ├── index.ts │ │ │ └── use-checkbox-props.ts │ │ ├── index.ts │ │ ├── src │ │ │ ├── checkbox.type.ts │ │ │ └── checkbox.vue │ │ └── __tests__ │ │ │ └── checkbox.test.ts │ ├── collapse │ │ ├── style │ │ │ └── index.ts │ │ ├── __tests__ │ │ │ └── collapse.test.ts │ │ ├── index.ts │ │ └── src │ │ │ └── collapse.vue │ ├── message │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── __tests__ │ │ │ └── message.test.ts │ │ └── src │ │ │ ├── message.ts │ │ │ └── message.vue │ ├── transfer │ │ ├── style │ │ │ └── index.ts │ │ ├── src │ │ │ ├── composables │ │ │ │ ├── index.ts │ │ │ │ ├── use-component-data.ts │ │ │ │ └── use-check.ts │ │ │ ├── transfer.type.ts │ │ │ ├── transferItem.vue │ │ │ └── transfer.vue │ │ ├── index.ts │ │ └── __tests__ │ │ │ └── transfer.test.ts │ ├── breadcrumb │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── __tests__ │ │ │ └── backtop.test.ts │ │ └── src │ │ │ └── breadcrumb.vue │ ├── date-picker │ │ ├── style │ │ │ └── index.ts │ │ ├── utils.ts │ │ ├── index.ts │ │ └── __tests__ │ │ │ └── data-picker.test.ts │ ├── pagination │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── __tests__ │ │ │ └── pagination.test.ts │ │ └── src │ │ │ └── pagination.vue │ ├── switch │ │ ├── src │ │ │ ├── interface.d.ts │ │ │ └── switch.vue │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ └── __tests__ │ │ │ └── switch.test.ts │ ├── button-group │ │ ├── style │ │ │ └── index.ts │ │ ├── src │ │ │ └── button-group.vue │ │ └── index.ts │ ├── breadcrumb-item │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ └── src │ │ │ └── breadcrumb-item.vue │ ├── col │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ └── src │ │ │ ├── row.ts │ │ │ └── col.ts │ ├── row │ │ └── index.ts │ ├── carousel │ │ ├── src │ │ │ ├── instance.d.ts │ │ │ └── carousel.ts │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ └── __tests__ │ │ │ └── carousel.test.ts │ ├── input │ │ ├── index.ts │ │ ├── style │ │ │ └── index.ts │ │ └── __tests__ │ │ │ └── input.test.ts │ ├── dropdown │ │ ├── style │ │ │ └── index.ts │ │ ├── src │ │ │ ├── event.ts │ │ │ ├── interface.d.ts │ │ │ ├── dropdownItem.vue │ │ │ ├── dropdwon.vue │ │ │ ├── dropdownMenu.vue │ │ │ └── dropdownMenuClick.vue │ │ ├── index.ts │ │ └── __tests__ │ │ │ └── dropdwon.test.ts │ ├── table │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── __tests__ │ │ │ └── table.test.ts │ │ └── src │ │ │ └── table.vue │ ├── icon │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ └── src │ │ │ └── icon.vue │ ├── button │ │ ├── style │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── src │ │ │ ├── interface.d.ts │ │ │ ├── button.vue │ │ │ └── button.ts │ │ └── __tests__ │ │ │ └── button.test.ts │ ├── carousel-item │ │ ├── index.ts │ │ └── src │ │ │ └── carousel-item.ts │ ├── dropdown-menu │ │ └── index.ts │ ├── dropdown-item │ │ └── index.ts │ ├── checkbox-group │ │ ├── index.ts │ │ └── src │ │ │ └── checkbox-group.vue │ ├── dropdown-menu-click │ │ └── index.ts │ ├── index.ts │ ├── package.json │ ├── components.ts │ └── vite.config.ts ├── theme-chalk │ ├── src │ │ ├── fonts │ │ │ ├── iconfont.ttf │ │ │ ├── iconfont.woff │ │ │ └── iconfont.woff2 │ │ ├── mixins │ │ │ ├── config.scss │ │ │ ├── utils.scss │ │ │ ├── _var.scss │ │ │ └── function.scss │ │ ├── breadcrumb-item.scss │ │ ├── col.scss │ │ ├── index.scss │ │ ├── transfer.scss │ │ ├── breadcrumb.scss │ │ ├── color │ │ │ └── index.scss │ │ ├── row.scss │ │ ├── pagination.scss │ │ ├── backtop.scss │ │ ├── common │ │ │ └── popup.scss │ │ ├── upload.scss │ │ ├── dialog.scss │ │ ├── carousel-item.scss │ │ ├── progress.scss │ │ ├── slider.scss │ │ ├── alert.scss │ │ ├── message.scss │ │ ├── collapse.scss │ │ ├── date-picker.scss │ │ ├── button-group.scss │ │ ├── checkbox.scss │ │ ├── input.scss │ │ └── switch.scss │ └── package.json ├── utils │ ├── common.ts │ ├── package.json │ ├── withInstallFunc.ts │ └── withInstall.ts ├── constants │ ├── index.ts │ ├── package.json │ └── event.ts └── eslint-config │ ├── package.json │ ├── index.js │ ├── eslint.rules.js │ └── ts.rules.js ├── docs ├── .gitignore ├── public │ ├── vue.png │ ├── vite.png │ ├── typescript.png │ ├── images │ │ ├── logo.png │ │ └── logo_icon.png │ └── logo-horizontal.png ├── components │ ├── input │ │ ├── basic.vue │ │ ├── disabled.vue │ │ ├── clearable.vue │ │ ├── showPassword.vue │ │ ├── suffixIcon.vue │ │ └── size.vue │ ├── checkbox │ │ ├── disabled.vue │ │ ├── funct.vue │ │ ├── group.vue │ │ ├── base.vue │ │ └── index.md │ ├── alert │ │ └── base.vue │ ├── switch │ │ ├── definevalue.vue │ │ ├── detail.vue │ │ ├── changedetail.vue │ │ ├── disabled.vue │ │ ├── change.vue │ │ ├── switch-icon.vue │ │ └── size.vue │ ├── message │ │ ├── base.vue │ │ ├── textcenter.vue │ │ ├── different.vue │ │ └── closeable.vue │ ├── datepicker │ │ ├── base.vue │ │ ├── prefixIcon.vue │ │ └── index.md │ ├── pagination │ │ ├── maxSize.vue │ │ ├── base.vue │ │ └── index.md │ ├── backtop │ │ └── index.md │ ├── dialog │ │ ├── dialogdefault.vue │ │ ├── dialog.vue │ │ └── index.md │ ├── table │ │ ├── detile.vue │ │ ├── size.vue │ │ ├── style.vue │ │ └── slot.vue │ ├── swiper │ │ ├── default.vue │ │ └── address.vue │ ├── icon │ │ └── index.md │ ├── slider │ │ └── index.md │ ├── upload │ │ └── index.md │ └── breadcrumb │ │ └── index.md ├── guide │ ├── install.md │ └── quickstart.md ├── .vitepress │ └── theme │ │ ├── style │ │ ├── style.css │ │ └── var.css │ │ └── index.ts └── index.md ├── pnpm-workspace.yaml ├── .lintstagedrc.js ├── .eslintrc.json ├── .husky ├── pre-commit └── commit-msg ├── .gitattributes ├── examples ├── TestCx.vue ├── main.ts ├── router │ └── index.ts ├── vite.config.ts ├── package.json └── index.html ├── .eslintignore ├── .ls-lint.yml ├── .gitignore ├── typings ├── vue-shim.d.ts ├── vue-test-utils.d.ts └── components.d.ts ├── tsconfig.json ├── commitlint.config.js ├── .vscode └── settings.json ├── prettier.config.js ├── .github └── workflows │ └── ci.yml ├── LICENSE ├── README.md └── package.json /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist = true 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | -------------------------------------------------------------------------------- /packages/components/.gitignore: -------------------------------------------------------------------------------- 1 | /lib 2 | /es -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | .vitepress/cache 2 | *.sh 3 | dist -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - packages/** 3 | - example 4 | -------------------------------------------------------------------------------- /.lintstagedrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '*.vue': ['prettier --write'] 3 | }; 4 | -------------------------------------------------------------------------------- /docs/public/vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huccct/tass-ui/HEAD/docs/public/vue.png -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["@tass-ui/eslint-config"] 4 | } 5 | -------------------------------------------------------------------------------- /docs/public/vite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huccct/tass-ui/HEAD/docs/public/vite.png -------------------------------------------------------------------------------- /packages/components/alert/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/alert.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/dialog/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/dialog.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/progress/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/progress.scss'; -------------------------------------------------------------------------------- /packages/components/slider/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/slider.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/upload/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/upload.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/backtop/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/backtop.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/checkbox/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/checkbox.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/collapse/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/collapse.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/message/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/message.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/transfer/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/transfer.scss'; 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /docs/public/typescript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huccct/tass-ui/HEAD/docs/public/typescript.png -------------------------------------------------------------------------------- /packages/components/breadcrumb/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/breadcrumb.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/date-picker/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/date-picker.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/pagination/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/pagination.scss'; 2 | -------------------------------------------------------------------------------- /packages/components/switch/src/interface.d.ts: -------------------------------------------------------------------------------- 1 | export type SwitchSize = 'lg' | 'md' | 'sm' | 'xs'; 2 | -------------------------------------------------------------------------------- /docs/public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huccct/tass-ui/HEAD/docs/public/images/logo.png -------------------------------------------------------------------------------- /packages/components/button-group/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/button-group.scss'; 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx commitlint --edit $1 5 | -------------------------------------------------------------------------------- /docs/public/logo-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huccct/tass-ui/HEAD/docs/public/logo-horizontal.png -------------------------------------------------------------------------------- /packages/components/breadcrumb-item/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/breadcrumb-item.scss'; 2 | -------------------------------------------------------------------------------- /docs/public/images/logo_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huccct/tass-ui/HEAD/docs/public/images/logo_icon.png -------------------------------------------------------------------------------- /packages/components/alert/src/interface.d.ts: -------------------------------------------------------------------------------- 1 | export type AlertType = 'info' | 'success' | 'error' | 'warning'; 2 | -------------------------------------------------------------------------------- /packages/components/col/style/index.ts: -------------------------------------------------------------------------------- 1 | import '@tass-ui/theme-chalk/src/col.scss'; 2 | import '@tass-ui/theme-chalk/src/row.scss'; 3 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huccct/tass-ui/HEAD/packages/theme-chalk/src/fonts/iconfont.ttf -------------------------------------------------------------------------------- /packages/theme-chalk/src/fonts/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huccct/tass-ui/HEAD/packages/theme-chalk/src/fonts/iconfont.woff -------------------------------------------------------------------------------- /packages/theme-chalk/src/fonts/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huccct/tass-ui/HEAD/packages/theme-chalk/src/fonts/iconfont.woff2 -------------------------------------------------------------------------------- /packages/components/row/index.ts: -------------------------------------------------------------------------------- 1 | import row from '../col/src/row'; 2 | import { withInstall } from '@tass-ui/utils/withInstall'; 3 | 4 | export const TassRow = withInstall(row); 5 | 6 | export default TassRow; 7 | -------------------------------------------------------------------------------- /packages/components/carousel/src/instance.d.ts: -------------------------------------------------------------------------------- 1 | import type Carousel from './carousel.vue'; 2 | import type CarouselItem from './carousel-item.vue'; 3 | 4 | export type CarouselInstance = InstanceType; 5 | -------------------------------------------------------------------------------- /packages/components/input/index.ts: -------------------------------------------------------------------------------- 1 | import Input from './src/input.vue'; 2 | import { withInstall } from '@tass-ui/utils/withInstall'; 3 | 4 | export const TassInput = withInstall(Input); 5 | 6 | export default TassInput; 7 | -------------------------------------------------------------------------------- /packages/components/slider/index.ts: -------------------------------------------------------------------------------- 1 | import Slider from './src/slider.vue'; 2 | import { withInstall } from '@tass-ui/utils/withInstall'; 3 | 4 | export const TassSlider = withInstall(Slider); 5 | 6 | export default TassSlider; 7 | -------------------------------------------------------------------------------- /packages/utils/common.ts: -------------------------------------------------------------------------------- 1 | export const isNumber = (val: any) => typeof val === 'number'; 2 | export const isString = (val: any) => typeof val === 'string'; 3 | export const isFunction = (val: any) => typeof val === 'function'; 4 | -------------------------------------------------------------------------------- /packages/components/backtop/index.ts: -------------------------------------------------------------------------------- 1 | import backtop from './src/backtop.vue'; 2 | import { withInstall } from '@tass-ui/utils/withInstall'; 3 | 4 | export const TassBacktop = withInstall(backtop); 5 | 6 | export default {TassBacktop}; -------------------------------------------------------------------------------- /packages/components/dialog/index.ts: -------------------------------------------------------------------------------- 1 | import dialog from './src/dialog.vue'; 2 | 3 | import { withInstall } from '@tass-ui/utils/withInstall'; 4 | 5 | export const TassDialog = withInstall(dialog); 6 | 7 | export default TassDialog; 8 | -------------------------------------------------------------------------------- /packages/components/dropdown/style/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @name: index 3 | * @author: cxy 4 | * @date: 2023/2/8 14:19 5 | * @description:index 6 | * @update: 2023/2/8 14:19 7 | */ 8 | import '@tass-ui/theme-chalk/src/dropdown.scss'; 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.ts linguist-detectable=true 3 | *.css linguist-detectable=false 4 | *.scss linguist-detectable=false 5 | *.js linguist-detectable=false 6 | *.vue linguist-detectable=true 7 | .husky/* linguist-vendored -------------------------------------------------------------------------------- /packages/components/progress/index.ts: -------------------------------------------------------------------------------- 1 | import progress from './src/progress.vue'; 2 | import { withInstall } from '@tass-ui/utils/withInstall'; 3 | 4 | export const TassProgress = withInstall(progress); 5 | 6 | export default TassProgress; -------------------------------------------------------------------------------- /packages/components/dropdown/src/event.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @name: event 3 | * @author: cxy 4 | * @date: 2023/2/8 23:27 5 | * @description:event 6 | * @update: 2023/2/8 23:27 7 | */ 8 | import mitt from 'mitt' 9 | export default mitt() 10 | -------------------------------------------------------------------------------- /packages/components/table/style/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-12 18:37:47 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\table\style\index.ts 6 | */ 7 | import "@tass-ui/theme-chalk/src/table.scss"; -------------------------------------------------------------------------------- /packages/constants/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-24 13:09:29 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-01-24 13:09:46 7 | */ 8 | export * from './event'; 9 | -------------------------------------------------------------------------------- /examples/TestCx.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /packages/components/breadcrumb/index.ts: -------------------------------------------------------------------------------- 1 | import Breadcrumb from './src/breadcrumb.vue'; 2 | import { withInstall } from '@tass-ui/utils/withInstall'; 3 | 4 | export const TassBreadcrumb = withInstall(Breadcrumb); 5 | 6 | export default TassBreadcrumb; -------------------------------------------------------------------------------- /packages/components/switch/style/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-10 20:53:43 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\switch\style\index.ts 6 | */ 7 | import "@tass-ui/theme-chalk/src/switch.scss"; -------------------------------------------------------------------------------- /packages/theme-chalk/src/mixins/config.scss: -------------------------------------------------------------------------------- 1 | $namespace: 'tas' !default; // 空间名称 2 | $element-separator: '__' !default; // 局部 3 | $modifier-separator: '--' !default; // 修饰 4 | $state-prefix: 'is-' !default; // 状态 5 | $common-separator: '-' !default; 6 | -------------------------------------------------------------------------------- /packages/components/carousel/style/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-10 20:53:43 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\switch\style\index.ts 6 | */ 7 | import '@tass-ui/theme-chalk/src/carousel.scss'; -------------------------------------------------------------------------------- /packages/components/pagination/index.ts: -------------------------------------------------------------------------------- 1 | import Pagination from './src/pagination.vue'; 2 | import { withInstall } from '@tass-ui/utils/withInstall'; 3 | 4 | export const TassPagination = withInstall(Pagination); 5 | 6 | export default TassPagination; 7 | -------------------------------------------------------------------------------- /packages/components/dropdown/src/interface.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @name: interface.d.ts 3 | * @author: cxy 4 | * @date: 2023/2/12 18:16 5 | * @description:interface.d.ts 6 | * @update: 2023/2/12 18:16 7 | */ 8 | export type DropdownSize = 'medium' | 'small' ; 9 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | pnpm-lock.yaml 4 | CHANGELOG.en-US.md 5 | docs/components.d.ts 6 | coverage 7 | play 8 | ssr-testing/cases/* 9 | docs/.vitepress/i18n/* 10 | docs/.vitepress/crowdin/* 11 | !docs/.vitepress/crowdin/en-US 12 | !.* 13 | -------------------------------------------------------------------------------- /docs/components/input/basic.vue: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /docs/components/input/disabled.vue: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /packages/components/icon/style/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-08 11:09:55 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-08 11:10:31 7 | */ 8 | import '@tass-ui/theme-chalk/src/icon.scss'; 9 | -------------------------------------------------------------------------------- /packages/components/input/style/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-08 11:37:57 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-08 11:38:03 7 | */ 8 | import '@tass-ui/theme-chalk/src/input.scss'; 9 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/breadcrumb-item.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/color' as *; 3 | // @include b(bread-item) { 4 | // a{ 5 | // text-decoration: none; 6 | // cursor: pointer; 7 | // font-weight: 700; 8 | // } 9 | // } 10 | -------------------------------------------------------------------------------- /docs/components/input/clearable.vue: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /packages/components/button/style/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-07 23:13:51 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-07 23:14:17 7 | */ 8 | import '@tass-ui/theme-chalk/src/button.scss'; 9 | -------------------------------------------------------------------------------- /packages/components/checkbox/composables/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-24 13:40:17 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-01-24 13:41:16 7 | */ 8 | export * from './use-checkbox-props'; 9 | -------------------------------------------------------------------------------- /docs/components/input/showPassword.vue: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /docs/components/input/suffixIcon.vue: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /packages/components/message/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/message'; 2 | import { withInstallFunc } from '@tass-ui/utils/withInstallFunc'; 3 | import Message from './src/method'; 4 | 5 | export const TassMessage = withInstallFunc(Message, '$message'); 6 | 7 | export default TassMessage; 8 | -------------------------------------------------------------------------------- /packages/components/date-picker/utils.ts: -------------------------------------------------------------------------------- 1 | export const formatTime = (t: Date) => { 2 | let date = new Date(t); 3 | let year = date.getFullYear(); 4 | let month = date.getMonth(); 5 | let day = date.getDate(); 6 | return { 7 | year, 8 | month, 9 | day 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /.ls-lint.yml: -------------------------------------------------------------------------------- 1 | ls: 2 | packages/components/**: 3 | .dir: kebab-case 4 | .vue: kebab-case 5 | .js: kebab-case 6 | .ts: kebab-case 7 | .json: kebab-case 8 | .d.ts: kebab-case 9 | .tsx: kebab-case 10 | 11 | ignore: 12 | - .git 13 | - .vscode 14 | - node_modules 15 | -------------------------------------------------------------------------------- /docs/guide/install.md: -------------------------------------------------------------------------------- 1 | # 安装 2 | 3 | 4 | ::: tip 5 | 该项目基于Vue3+Vite+TypeScript 参考Element-Plus进行开发~ 6 | ::: 7 | ### 环境支持 8 | 由于 Vue 3 不再支持 IE11,Tass UI 也不再支持 IE 浏览器。 9 | 10 | ### 版本 11 | Tass UI 目前还处于快速开发迭代中。 12 | 13 | 14 | ### NPM安装 15 | 推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。 16 | ``` 17 | npm i tass-ui -S 18 | ``` -------------------------------------------------------------------------------- /packages/components/transfer/src/composables/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-25 11:39:57 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-01-25 20:07:40 7 | */ 8 | export * from './use-component-data'; 9 | export * from './use-check'; 10 | -------------------------------------------------------------------------------- /packages/constants/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tass-ui/constants", 3 | "version": "1.0.0", 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 | } 13 | -------------------------------------------------------------------------------- /packages/theme-chalk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tass-ui/theme-chalk", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT" 12 | } 13 | -------------------------------------------------------------------------------- /docs/components/checkbox/disabled.vue: -------------------------------------------------------------------------------- 1 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /packages/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tass-ui/eslint-config", 3 | "version": "1.0.0", 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 | } 13 | -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tass-ui/utils", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "./index.ts", 6 | "module": "./index.ts", 7 | "files": [ 8 | "dist" 9 | ], 10 | "scripts": { 11 | "build": "vite build" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /packages/constants/event.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-24 13:09:25 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-01-24 13:09:31 7 | */ 8 | export const UPDATE_MODEL_EVENT = 'update:modelValue'; 9 | export const CHANGE_EVENT = 'change'; 10 | export const INPUT_EVENT = 'input'; 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | CONTRIBUTING.md 5 | npm-debug.log 6 | yarn-debug.log* 7 | yarn-error.log* 8 | yarn.lock 9 | package-lock.json 10 | test/unit/coverage 11 | test/e2e/reports 12 | selenium-debug.log 13 | build/ 14 | packages/utils/dist 15 | 16 | 17 | # Editor directories and files 18 | .idea 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln -------------------------------------------------------------------------------- /docs/components/checkbox/funct.vue: -------------------------------------------------------------------------------- 1 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /docs/components/input/size.vue: -------------------------------------------------------------------------------- 1 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /packages/components/table/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-12 12:06:25 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\table\index.ts 6 | */ 7 | import Table from './src/table.vue'; 8 | import { withInstall } from '@tass-ui/utils/withInstall'; 9 | 10 | export const TassTable = withInstall(Table); 11 | 12 | export default TassTable; -------------------------------------------------------------------------------- /typings/vue-shim.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-06 11:08:16 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-06 11:29:24 7 | */ 8 | declare module '*.vue' { 9 | import type { defineComponent } from 'vue'; 10 | const component: ReturnType; 11 | export default component; 12 | } 13 | -------------------------------------------------------------------------------- /packages/components/switch/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-05 10:19:03 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\switch\index.ts 6 | */ 7 | import Switch from './src/switch.vue'; 8 | import { withInstall } from '@tass-ui/utils/withInstall'; 9 | 10 | export const TassSwitch = withInstall(Switch); 11 | 12 | export default TassSwitch; 13 | -------------------------------------------------------------------------------- /packages/components/dropdown/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @name: index 3 | * @author: cxy 4 | * @date: 2023/1/28 17:52 5 | * @description:index 6 | * @update: 2023/1/28 17:52 7 | */ 8 | import dropdown from './src/dropdwon.vue'; 9 | 10 | import { withInstall } from '@tass-ui/utils/withInstall'; 11 | 12 | export const TassDropdown = withInstall(dropdown); 13 | 14 | export default TassDropdown; 15 | -------------------------------------------------------------------------------- /docs/components/alert/base.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | -------------------------------------------------------------------------------- /packages/components/col/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-23 15:45:04 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:07:17 7 | */ 8 | import col from './src/col'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassCol = withInstall(col); 12 | 13 | export default TassCol; 14 | -------------------------------------------------------------------------------- /packages/components/collapse/__tests__/collapse.test.ts: -------------------------------------------------------------------------------- 1 | import Collapse from '../src/collapse.vue'; 2 | 3 | import { describe, expect, it, test } from 'vitest'; 4 | 5 | const list = ['diapers', 'kleenex', 'trash bags', 'paper towels', 'milk']; 6 | 7 | test('the shopping list has milk on it', () => { 8 | expect(list).toContain('milk'); 9 | expect(new Set(list)).toContain('milk'); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/components/alert/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Descripttion: Spicy chicken 3 | * @Author: YuShu Xiao 4 | * @Date: 2023-02-01 14:47:17 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:01:07 7 | */ 8 | import Alert from './src/alert.vue'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassAlert = withInstall(Alert); 12 | 13 | export default TassAlert; 14 | -------------------------------------------------------------------------------- /packages/components/icon/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-23 20:38:53 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:09:14 7 | */ 8 | import icon from './src/icon.vue'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassIcon = withInstall(icon); 12 | 13 | export default TassIcon; 14 | -------------------------------------------------------------------------------- /docs/components/switch/definevalue.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /packages/components/carousel/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-01-28 18:04:50 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\carousel\index.ts 6 | */ 7 | import Carousel from './src/carousel.vue'; 8 | import { withInstall } from '@tass-ui/utils/withInstall'; 9 | 10 | export const TassCarousel = withInstall(Carousel); 11 | 12 | export default TassCarousel; 13 | -------------------------------------------------------------------------------- /docs/components/message/base.vue: -------------------------------------------------------------------------------- 1 | 4 | 15 | -------------------------------------------------------------------------------- /packages/components/upload/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-05 14:53:41 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:26:44 7 | */ 8 | import upload from './src/upload.vue'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassUpload = withInstall(upload); 12 | 13 | export default TassUpload; 14 | -------------------------------------------------------------------------------- /packages/components/button/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-21 11:43:50 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:06:30 7 | */ 8 | import button from './src/button.vue'; 9 | 10 | import { withInstall } from '@tass-ui/utils/withInstall'; 11 | 12 | export const TassButton = withInstall(button); 13 | 14 | export default TassButton; 15 | -------------------------------------------------------------------------------- /packages/components/carousel-item/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-01-28 18:04:50 4 | * @Description: 铁沸物 5 | * @FilePath: \echo-ui\packages\components\carousel\index.ts 6 | */ 7 | import { withInstall } from '@tass-ui/utils/withInstall'; 8 | import CarouselItem from './src/carousel-item.vue'; 9 | 10 | export const TassCarouselItem = withInstall(CarouselItem); 11 | 12 | export default TassCarouselItem; 13 | -------------------------------------------------------------------------------- /packages/components/dropdown-menu/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @name: index 3 | * @author: cxy 4 | * @date: 2023/2/8 21:13 5 | * @description:index 6 | * @update: 2023/2/8 21:13 7 | */ 8 | import dropdownMenu from '../dropdown/src/dropdownMenu.vue'; 9 | 10 | import { withInstall } from '@tass-ui/utils/withInstall'; 11 | 12 | export const TassDropdownMenu = withInstall(dropdownMenu); 13 | 14 | export default TassDropdownMenu; 15 | -------------------------------------------------------------------------------- /packages/components/checkbox/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-23 20:28:30 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:14:37 7 | */ 8 | import checkBox from './src/checkbox.vue'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassCheckbox = withInstall(checkBox); 12 | 13 | export default TassCheckbox; 14 | -------------------------------------------------------------------------------- /packages/components/transfer/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-24 21:56:23 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:13:48 7 | */ 8 | import transfer from './src/transfer.vue'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassTransfer = withInstall(transfer); 12 | 13 | export default TassTransfer; 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "es2016", 5 | "sourceMap": false, 6 | "module": "esnext", 7 | "esModuleInterop": true, 8 | "strict": true, 9 | // "allowJs": true, 10 | "jsx": "preserve", 11 | "lib": ["esnext", "dom"], 12 | "types": ["node"], 13 | "rootDir": ".", 14 | // "outDir": "./build", 15 | "moduleResolution": "node" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/components/button-group/src/button-group.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 17 | -------------------------------------------------------------------------------- /packages/components/collapse/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-05 14:53:41 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:22:06 7 | */ 8 | import collapse from './src/collapse.vue'; 9 | 10 | import { withInstall } from '@tass-ui/utils/withInstall'; 11 | 12 | export const TassCollapse = withInstall(collapse); 13 | 14 | export default { TassCollapse }; 15 | -------------------------------------------------------------------------------- /packages/components/date-picker/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-12 10:55:52 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-12 11:55:50 7 | */ 8 | import DatePicker from './src/date-picker.vue'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassDatePicker = withInstall(DatePicker); 12 | 13 | export default TassDatePicker; 14 | -------------------------------------------------------------------------------- /packages/components/dropdown-item/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @name: index 3 | * @author: cxy 4 | * @date: 2023/2/8 21:12 5 | * @description:index 6 | * @update: 2023/2/8 21:12 7 | */ 8 | // @ts-ignore 9 | import dropdownItem from '../dropdown/src/dropdownItem.vue'; 10 | 11 | import { withInstall } from '@tass-ui/utils/withInstall'; 12 | 13 | export const TassDropdownItem = withInstall(dropdownItem); 14 | 15 | export default TassDropdownItem; 16 | -------------------------------------------------------------------------------- /packages/components/button-group/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-21 13:30:22 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:06:08 7 | */ 8 | import buttonGroup from './src/button-group.vue'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassButtonGroup = withInstall(buttonGroup); 12 | 13 | export default TassButtonGroup; 14 | -------------------------------------------------------------------------------- /packages/utils/withInstallFunc.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue'; 2 | import type { SFCInstallWithContext, SFCWithInstall } from './typescript'; 3 | 4 | export const withInstallFunc = (fn: T, name: string) => { 5 | (fn as SFCWithInstall).install = (app: App) => { 6 | (fn as SFCInstallWithContext)._context = app._context; 7 | app.config.globalProperties[name] = fn; 8 | }; 9 | 10 | return fn as SFCInstallWithContext; 11 | }; 12 | -------------------------------------------------------------------------------- /docs/components/datepicker/base.vue: -------------------------------------------------------------------------------- 1 | 8 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /packages/components/breadcrumb-item/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Descripttion: Spicy chicken 3 | * @Author: YuShu Xiao 4 | * @Date: 2023-02-07 13:09:53 5 | * @LastEditors: YuShu Xiao 6 | * @LastEditTime: 2023-02-07 13:14:19 7 | */ 8 | import BreadcrumbItem from './src/breadcrumb-item.vue'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassBreadcrumbItem = withInstall(BreadcrumbItem); 12 | 13 | export default TassBreadcrumbItem; -------------------------------------------------------------------------------- /packages/components/checkbox-group/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-23 20:28:58 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:06:53 7 | */ 8 | import checkboxGroup from './src/checkbox-group.vue'; 9 | import { withInstall } from '@tass-ui/utils/withInstall'; 10 | 11 | export const TassCheckboxGroup = withInstall(checkboxGroup); 12 | 13 | export default TassCheckboxGroup; 14 | -------------------------------------------------------------------------------- /packages/components/dropdown-menu-click/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @name: index 3 | * @author: cxy 4 | * @date: 2023/2/10 14:03 5 | * @description:index 6 | * @update: 2023/2/10 14:03 7 | */ 8 | import dropdownMenuClick from '../dropdown/src/dropdownMenuClick.vue'; 9 | 10 | import { withInstall } from '@tass-ui/utils/withInstall'; 11 | 12 | export const TassDropdownMenuClick = withInstall(dropdownMenuClick); 13 | 14 | export default TassDropdownMenuClick; 15 | -------------------------------------------------------------------------------- /docs/components/pagination/maxSize.vue: -------------------------------------------------------------------------------- 1 | 11 | 18 | 19 | -------------------------------------------------------------------------------- /examples/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-21 11:16:00 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-08 10:59:28 7 | */ 8 | import { createApp } from 'vue'; 9 | import App from './app.vue'; 10 | import router from './router'; 11 | import TassUI from '@tass-ui/components'; 12 | 13 | const app = createApp(App); 14 | 15 | app.use(TassUI as any); 16 | app.use(router); 17 | app.mount('#app'); 18 | -------------------------------------------------------------------------------- /typings/vue-test-utils.d.ts: -------------------------------------------------------------------------------- 1 | import type { CSSProperties, ComponentPublicInstance } from 'vue'; 2 | 3 | declare module '@vue/test-utils' { 4 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 5 | interface DOMWrapper { 6 | style: CSSProperties; 7 | } 8 | 9 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 10 | interface VueWrapper { 11 | style: CSSProperties; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | /* https://commitlint.js.org/#/reference-rules */ 2 | module.exports = { 3 | ignores: [commit => commit.includes('init')], 4 | extends: ['@commitlint/config-conventional'], 5 | rules: { 6 | 'body-leading-blank': [2, 'always'], 7 | 'footer-leading-blank': [1, 'always'], 8 | 'header-max-length': [2, 'always', 108], 9 | 'subject-empty': [2, 'never'], 10 | 'type-empty': [2, 'never'], 11 | 'subject-case': [0] 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /docs/components/datepicker/prefixIcon.vue: -------------------------------------------------------------------------------- 1 | 8 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /docs/components/checkbox/group.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /docs/components/switch/detail.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/col.scss: -------------------------------------------------------------------------------- 1 | // @use 'sass:math'; 2 | 3 | // @use 'mixins/mixins' as *; 4 | // @use 'common/var' as *; 5 | 6 | // @include b(col) { 7 | // @for $i from 0 through 24 { 8 | // &.#{$namespace}-col-span-#{$i} { 9 | // max-width: (math.div(1, 24) * $i * 100) * 1%; 10 | // flex: 0 0 (math.div(1, 24) * $i * 100) * 1%; 11 | // } 12 | 13 | // &.#{$namespace}-col-offset-#{$i} { 14 | // margin-left: (math.div(1, 24) * $i * 100) * 1%; 15 | // } 16 | // } 17 | // } 18 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.validate": ["html", "vue", "javascript", "jsx"], 3 | "emmet.syntaxProfiles": { 4 | "vue-html": "html", 5 | "vue": "html" 6 | }, 7 | "editor.tabSize": 2, 8 | "eslint.alwaysShowStatus": true, 9 | "eslint.quiet": true, 10 | "editor.codeActionsOnSave": { 11 | "source.fixAll.eslint": true, 12 | "source.fixAll": true 13 | }, 14 | "stylelint.customSyntax": "postcss-scss", 15 | "stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"] 16 | } 17 | -------------------------------------------------------------------------------- /packages/components/icon/src/icon.vue: -------------------------------------------------------------------------------- 1 | 8 | 11 | 20 | 21 | -------------------------------------------------------------------------------- /examples/router/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Descripttion: Spicy chicken 3 | * @Author: YuShu Xiao 4 | * @Date: 2023-02-07 15:54:11 5 | * @LastEditors: YuShu Xiao 6 | * @LastEditTime: 2023-02-12 22:25:21 7 | */ 8 | import {createRouter, createWebHashHistory, createWebHistory} from "vue-router"; 9 | const router=createRouter({ 10 | history:createWebHashHistory(import.meta.env.BASE_URL), 11 | routes:[{path:'/sp',component:()=>import('../TestCx.vue')},{path:'/',component:()=>import('../TestCx.vue')}] 12 | }) 13 | export default router; -------------------------------------------------------------------------------- /packages/components/carousel-item/src/carousel-item.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-01-29 16:44:59 4 | * @Description: 铁沸物 5 | * @FilePath: \echo-ui\packages\components\carousel\src\carousel-item.ts 6 | */ 7 | import type { ExtractPropTypes } from 'vue'; 8 | 9 | export const carouselItemProps = { 10 | name: { type: String, default: '' }, 11 | label: { 12 | type: [String, Number], 13 | default: '' 14 | } 15 | }; 16 | 17 | export type CarouselItemProps = ExtractPropTypes; 18 | -------------------------------------------------------------------------------- /typings/components.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-13 17:17:16 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-13 17:17:20 7 | */ 8 | declare module '@vue/runtime-core' { 9 | export interface GlobalComponents { 10 | TassButton: typeof import('@tass-ui/components').TassButton; 11 | TassInput: typeof import('@tass-ui/components').TassInput; 12 | TassUpload: typeof import('@tass-ui/components').TassUpload; 13 | } 14 | } 15 | export {}; 16 | -------------------------------------------------------------------------------- /examples/vite.config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-21 11:15:22 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-01-22 16:48:55 7 | */ 8 | /// 9 | import { defineConfig } from 'vite'; 10 | import type { PluginOption } from 'vite'; 11 | import vue from '@vitejs/plugin-vue'; 12 | import VueSetupExtend from 'vite-plugin-vue-setup-extend'; 13 | 14 | export default defineConfig({ 15 | plugins: [vue() as PluginOption, VueSetupExtend()] 16 | }); 17 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/index.scss: -------------------------------------------------------------------------------- 1 | @use 'button.scss'; 2 | @use 'button-group.scss'; 3 | @use 'icon.scss'; 4 | @use 'row.scss'; 5 | @use 'col.scss'; 6 | @use 'transfer.scss'; 7 | @use 'message.scss'; 8 | @use 'collapse.scss'; 9 | @use 'alert.scss'; 10 | @use 'upload.scss'; 11 | @use 'dialog.scss'; 12 | @use 'input.scss'; 13 | @use 'breadcrumb.scss'; 14 | @use 'breadcrumb-item.scss'; 15 | @use 'dropdown.scss'; 16 | @use 'slider.scss'; 17 | @use 'progress.scss'; 18 | @use 'checkbox.scss'; 19 | @use 'pagination.scss'; 20 | @use 'date-picker.scss'; 21 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/transfer.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | 4 | // @include b(transfer) { 5 | // @include e(item) { 6 | // display: inline-block; 7 | // width: 200px; 8 | // vertical-align: middle; 9 | // border: 1px solid #ccc; 10 | // border-radius: 10px; 11 | // margin: 0 20px; 12 | // } 13 | // @include e(body) { 14 | // height: 200px; 15 | // overflow: scroll; 16 | // } 17 | // @include e(buttons) { 18 | // display: inline-block; 19 | // } 20 | // } 21 | -------------------------------------------------------------------------------- /packages/components/button/src/interface.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-21 11:58:09 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-01-21 11:58:14 7 | */ 8 | import type { ButtonHTMLAttributes } from 'vue'; 9 | 10 | export type ButtonSizeType = 'default' | 'medium' | 'small' | 'mini' | 'tiny'; 11 | 12 | export type ButtonType = 'default' | 'primary' | 'success' | 'info' | 'danger' | 'warning'; 13 | 14 | export type ButtonNativeType = NonNullable; 15 | -------------------------------------------------------------------------------- /packages/components/progress/__test__/progress.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { mount } from '@vue/test-utils'; 3 | import progress from '../src/progress.vue'; 4 | 5 | describe('test Progress', () => { 6 | it('should render slot', () => { 7 | const wrapper = mount(progress, { 8 | slots: { 9 | default: '' 10 | } 11 | }); 12 | 13 | expect(wrapper.text()).toContain(''); 14 | }); 15 | it('should have class', () => { 16 | const wrapper = mount(progress); 17 | 18 | }); 19 | }); -------------------------------------------------------------------------------- /docs/.vitepress/theme/style/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | overflow: overlay; 4 | background-color: transparent; 5 | transition: 0.3s background-color; 6 | } 7 | ::-webkit-scrollbar { 8 | background-color: transparent; 9 | width: 12px; 10 | } 11 | ::-webkit-scrollbar-thumb { 12 | background-color: inherit; 13 | border-radius: 8px; 14 | background-clip: content-box; 15 | border: 2px solid transparent; 16 | } 17 | body[scroll], 18 | ::-webkit-scrollbar-thumb { 19 | background-color: rgba(166, 166, 205, 0.3); 20 | transition: 0s; 21 | } 22 | -------------------------------------------------------------------------------- /docs/components/switch/changedetail.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/breadcrumb.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/color' as *; 3 | 4 | // @include b(bread) { 5 | // display: flex; 6 | // padding: 25px 10px; 7 | // &-item { 8 | // a { 9 | // color: #666; 10 | // transition: all .4s; 11 | // &:hover { 12 | // color: #6565bc; 13 | // } 14 | // } 15 | // } 16 | // i{ 17 | // font-size: 11px; 18 | // margin-left: 5px; 19 | // margin-right: 5px; 20 | // margin-top: 2px; 21 | // line-height: 22px; 22 | // } 23 | // } 24 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "vite" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@vitejs/plugin-vue": "^4.0.0", 15 | "vite": "^4.0.4", 16 | "vite-plugin-eslint": "^1.8.1", 17 | "vite-plugin-vue-setup-extend": "^0.4.0" 18 | }, 19 | "dependencies": { 20 | "vue-router": "^4.1.6" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/transfer/src/transfer.type.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-25 11:21:16 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-01-25 20:04:03 7 | */ 8 | export type key = string | number; 9 | export interface IData { 10 | key: key; 11 | label: string; 12 | disabled: boolean; 13 | } 14 | export interface Props { 15 | key: string; 16 | label: string; 17 | disabled: string; 18 | } 19 | export interface ItransferProps { 20 | data: IData[]; 21 | modelValue: key[]; 22 | props: Props; 23 | } 24 | -------------------------------------------------------------------------------- /packages/components/upload/__tests__/upload.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { mount } from '@vue/test-utils'; 3 | import upload from '../src/upload.vue'; 4 | 5 | describe('test Upload', () => { 6 | it('should render slot', () => { 7 | const wrapper = mount(upload, { 8 | slots: { 9 | default: '' 10 | } 11 | }); 12 | 13 | expect(wrapper.text()).toContain(''); 14 | }); 15 | it('should have class', () => { 16 | const wrapper = mount(upload); 17 | expect(wrapper.classes()).toContain('tas-upload'); 18 | }); 19 | }); -------------------------------------------------------------------------------- /docs/components/switch/disabled.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /docs/guide/quickstart.md: -------------------------------------------------------------------------------- 1 | 8 | # 快速开始 9 | 10 | 本节将介绍如何在项目中使用 Tass UI. 11 | ## 用法 12 | ### 完整引入 13 | 如果你对打包后的文件大小不是很在乎,那么使用完整导入会更方便。 14 | ``` 15 | // main.ts 16 | import { createApp } from 'vue'; 17 | import App from './App.vue'; 18 | import TassUI from 'tass-ui'; 19 | import 'tass-ui/es/style.css'; 20 | const app = createApp(App); 21 | app.use(TassUI).mount('#app'); 22 | ``` 23 | # 开始使用 24 | 现在你可以启动项目了。 对于每个组件的用法,请参考单个组件对应的文档。 -------------------------------------------------------------------------------- /docs/components/checkbox/base.vue: -------------------------------------------------------------------------------- 1 | 8 | 13 | 18 | 19 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Document 15 | 16 | 17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/components/switch/change.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /docs/components/message/textcenter.vue: -------------------------------------------------------------------------------- 1 | 8 | 11 | 23 | -------------------------------------------------------------------------------- /packages/components/checkbox/src/checkbox.type.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-23 21:45:34 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-01-24 11:13:45 7 | */ 8 | import type { ComputedRef } from 'vue'; 9 | export interface checkBoxProps { 10 | indeterminate?: boolean; 11 | isChecked?: boolean; 12 | name?: string; 13 | disabled?: boolean; 14 | label?: string | number | boolean | object; 15 | modelValue?: string | number | boolean; 16 | } 17 | 18 | export interface T { 19 | modelValue?: ComputedRef; 20 | handlerChange?: (val: unknown) => void; 21 | } 22 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/color/index.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:color'; 2 | @use 'sass:string'; 3 | 4 | @function rgb2hex($color) { 5 | @return unquote('#' + #{string.slice(color.ie-hex-str($color), 4)}); 6 | } 7 | 8 | // rgba color above solid color 9 | @function mix-overlay-color($upper, $lower) { 10 | $opacity: color.alpha($upper); 11 | 12 | $red: color.red($upper) * $opacity + color.red($lower) * (1 - $opacity); 13 | $green: color.green($upper) * $opacity + color.green($lower) * (1 - $opacity); 14 | $blue: color.blue($upper) * $opacity + color.blue($lower) * (1 - $opacity); 15 | 16 | @return rgb2hex(rgb($red, $green, $blue)); 17 | } 18 | -------------------------------------------------------------------------------- /docs/components/switch/switch-icon.vue: -------------------------------------------------------------------------------- 1 | 7 | 15 | 16 | -------------------------------------------------------------------------------- /docs/components/pagination/base.vue: -------------------------------------------------------------------------------- 1 | 8 | 18 | 25 | 26 | -------------------------------------------------------------------------------- /packages/components/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-21 11:34:40 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-09 15:20:09 7 | */ 8 | import type { App } from 'vue'; 9 | import * as components from './components'; 10 | import { version } from './package.json'; 11 | import Message from './message'; 12 | 13 | const install = function (app: App) { 14 | Object.entries(components).forEach(([key, value]) => { 15 | app.component(key, value); 16 | app.config.globalProperties.$message = Message; 17 | }); 18 | }; 19 | 20 | export default install; 21 | export * from './components'; 22 | export { version }; 23 | -------------------------------------------------------------------------------- /packages/components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tass-ui/components", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.ts", 6 | "scripts": { 7 | "test": "vitest", 8 | "coverage": "vitest run --coverage", 9 | "build": "vite build" 10 | }, 11 | "files": [ 12 | "es", 13 | "lib" 14 | ], 15 | "keywords": [ 16 | "tass-ui", 17 | "vue3组件库", 18 | "vue ui", 19 | "components", 20 | "beautiful" 21 | ], 22 | "author": "Components Team", 23 | "license": "MIT", 24 | "dependencies": { 25 | "@tass-ui/utils": "workspace:^1.0.0" 26 | }, 27 | "devDependencies": { 28 | "@vitest/coverage-c8": "^0.28.4" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/components/date-picker/__tests__/data-picker.test.ts: -------------------------------------------------------------------------------- 1 | import datapicker from '../src/date-picker.vue'; 2 | 3 | import { describe, expect, it, test } from 'vitest'; 4 | import { mount } from '@vue/test-utils'; 5 | 6 | describe('test checkbox', () => { 7 | it('should render slot', () => { 8 | const wrapper = mount(datapicker, { 9 | slots: { 10 | default: '' 11 | } 12 | }); 13 | 14 | // Assert the rendered text of the component 15 | expect(wrapper.text()).toContain(''); 16 | it('should have class', () => { 17 | const wrapper = mount(datapicker); 18 | expect(wrapper.classes()).toContain('tas-datapicker'); 19 | }); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | hero: 5 | name: Tass 6 | text: 一个Vue3组件库 7 | tagline: 基于Vue3,简洁高效的组件库 8 | image: 9 | src: /images/logo.png 10 | alt: tass-ui 11 | actions: 12 | - theme: brand 13 | text: Get Started 14 | link: /guide/install 15 | - theme: alt 16 | text: View on GitHub 17 | link: https://github.com/huccct/tass-ui 18 | 19 | features: 20 | - icon: 21 | src: /vue.png 22 | title: Vue3 23 | details: 渐进式JavaScript 框架 24 | - icon: 25 | src: /typescript.png 26 | title: TypeScript 27 | details: 带有类型语法的JavaScript 28 | - icon: 29 | src: /vite.png 30 | title: Vite 31 | details: 下一代的前端工具链 32 | --- 33 | -------------------------------------------------------------------------------- /docs/components/backtop/index.md: -------------------------------------------------------------------------------- 1 | 15 | 16 | # Backtop 回到顶部 17 | 18 | 返回页面顶部的操作按钮。 19 | 20 | ## 基础用法 21 | 22 | 点击按钮直接回到页面顶部。 23 | 24 |
25 | Scroll down to see the bottom-right button. 26 | 27 |
28 | 29 |
30 | 展开查看 31 | 32 | ```vue 33 | 37 | ``` 38 | 39 |
40 | -------------------------------------------------------------------------------- /packages/components/slider/__tests__/slider.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-22 16:51:31 5 | * @LastEditors: Please set LastEditors 6 | * @LastEditTime: 2023-02-13 15:50:40 7 | */ 8 | import { describe, expect, it } from 'vitest'; 9 | 10 | import { mount } from '@vue/test-utils'; 11 | import slider from '../src/slider.vue'; 12 | 13 | describe('test Slider', () => { 14 | it('should render slot', () => { 15 | const wrapper = mount(slider, { 16 | slots: { 17 | default: '' 18 | } 19 | }); 20 | }); 21 | it('should have class', () => { 22 | const wrapper = mount(slider); 23 | expect(wrapper.classes()).toContain('tas-slider'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, //最大单行长度 3 | tabWidth: 2, //每个缩进的空格数 4 | useTabs: false, //使用制表符而不是空格缩进行 5 | semi: true, //在语句的末尾打印分号 6 | vueIndentScriptAndStyle: true, //是否缩进 Vue 文件中的代码 -------------------------------------------------------------------------------- /packages/theme-chalk/src/mixins/utils.scss: -------------------------------------------------------------------------------- 1 | @mixin utils-clearfix { 2 | $selector: &; 3 | 4 | @at-root { 5 | #{$selector}::before, 6 | #{$selector}::after { 7 | display: table; 8 | content: ''; 9 | } 10 | #{$selector}::after { 11 | clear: both; 12 | } 13 | } 14 | } 15 | 16 | @mixin utils-vertical-center { 17 | $selector: &; 18 | 19 | @at-root { 20 | #{$selector}::after { 21 | display: inline-block; 22 | content: ''; 23 | height: 100%; 24 | vertical-align: middle; 25 | } 26 | } 27 | } 28 | 29 | @mixin utils-ellipsis { 30 | overflow: hidden; 31 | text-overflow: ellipsis; 32 | white-space: nowrap; 33 | } 34 | 35 | @mixin utils-inline-flex-center { 36 | display: inline-flex; 37 | justify-content: center; 38 | align-items: center; 39 | } 40 | -------------------------------------------------------------------------------- /packages/components/alert/__tests__/alert.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-13 16:01:33 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\alert\__tests__\alert.test.ts 6 | */ 7 | import { describe, expect, it } from 'vitest'; 8 | 9 | import { mount } from '@vue/test-utils'; 10 | import alert from '../src/alert.vue'; 11 | // The component to test 12 | 13 | describe('test alert', () => { 14 | it('should render slot', () => { 15 | const wrapper = mount(alert, { 16 | slots: { 17 | default: '' 18 | } 19 | }); 20 | 21 | // Assert the rendered text of the component 22 | expect(wrapper.text()).toContain(''); 23 | it('should have class', () => { 24 | const wrapper = mount(alert); 25 | expect(wrapper.classes()).toContain('tas-table'); 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/components/carousel/__tests__/carousel.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-01 21:33:37 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\carousel\ 6 | */ 7 | import { describe, expect, it } from 'vitest'; 8 | 9 | import { mount } from '@vue/test-utils'; 10 | import carousel from '../src/carousel.vue'; 11 | // The component to test 12 | 13 | describe('test carousel', () => { 14 | it('should render slot', () => { 15 | const wrapper = mount(carousel, { 16 | slots: { 17 | default: '' 18 | } 19 | }); 20 | 21 | // Assert the rendered text of the component 22 | expect(wrapper.text()).toContain(''); 23 | it('should have class', () => { 24 | const wrapper = mount(carousel); 25 | expect(wrapper.classes()).toContain('tas-carousel'); 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/components/backtop/__tests__/backtop.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-13 16:01:33 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\backtop\__tests__\backtop.test.ts 6 | */ 7 | import { describe, expect, it } from 'vitest'; 8 | 9 | import { mount } from '@vue/test-utils'; 10 | import backtop from '../src/backtop.vue'; 11 | // The component to test 12 | 13 | describe('test backtop', () => { 14 | it('should render slot', () => { 15 | const wrapper = mount(backtop, { 16 | slots: { 17 | default: '' 18 | } 19 | }); 20 | 21 | // Assert the rendered text of the component 22 | expect(wrapper.text()).toContain(''); 23 | it('should have class', () => { 24 | const wrapper = mount(backtop); 25 | expect(wrapper.classes()).toContain('tas-backtop'); 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/components/pagination/__tests__/pagination.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-13 16:10:42 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\pagination\__tests__\pagination.test.ts 6 | */ 7 | import pagination from '../src/pagination.vue'; 8 | 9 | import { describe, expect, it, test } from 'vitest'; 10 | import { mount } from '@vue/test-utils'; 11 | 12 | describe('test checkbox', () => { 13 | it('should render slot', () => { 14 | const wrapper = mount(pagination, { 15 | slots: { 16 | default: '' 17 | } 18 | }); 19 | 20 | // Assert the rendered text of the component 21 | expect(wrapper.text()).toContain(''); 22 | it('should have class', () => { 23 | const wrapper = mount(pagination); 24 | expect(wrapper.classes()).toContain('tas-pagination'); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/components/checkbox/__tests__/checkbox.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-13 16:06:30 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\checkbox\__tests__\carousel.test.ts 6 | */ 7 | import { describe, expect, it } from 'vitest'; 8 | 9 | import { mount } from '@vue/test-utils'; 10 | import checkbox from '../src/checkbox.vue'; 11 | // The component to test 12 | 13 | describe('test checkbox', () => { 14 | it('should render slot', () => { 15 | const wrapper = mount(checkbox, { 16 | slots: { 17 | default: '' 18 | } 19 | }); 20 | 21 | // Assert the rendered text of the component 22 | expect(wrapper.text()).toContain(''); 23 | it('should have class', () => { 24 | const wrapper = mount(checkbox); 25 | expect(wrapper.classes()).toContain('tas-checkbox'); 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/components/breadcrumb/__tests__/backtop.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-13 16:05:37 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\breadcrumb\__tests__\backtop.test.ts 6 | */ 7 | import { describe, expect, it } from 'vitest'; 8 | 9 | import { mount } from '@vue/test-utils'; 10 | import breadcrumb from '../src/breadcrumb.vue'; 11 | // The component to test 12 | 13 | describe('test breadcrumb', () => { 14 | it('should render slot', () => { 15 | const wrapper = mount(breadcrumb, { 16 | slots: { 17 | default: '' 18 | } 19 | }); 20 | 21 | // Assert the rendered text of the component 22 | expect(wrapper.text()).toContain(''); 23 | it('should have class', () => { 24 | const wrapper = mount(breadcrumb); 25 | expect(wrapper.classes()).toContain('tas-breadcrumb'); 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/components/dialog/__tests__/dialog.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-22 16:51:31 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-06 14:15:27 7 | */ 8 | import { describe, expect, it } from 'vitest'; 9 | 10 | import { mount } from '@vue/test-utils'; 11 | import dialog from '../src/dialog.vue'; 12 | // The component to test 13 | 14 | describe('test Dialog', () => { 15 | it('should render slot', () => { 16 | const wrapper = mount(dialog, { 17 | slots: { 18 | default: 'Hello world' 19 | } 20 | }); 21 | 22 | // Assert the rendered text of the component 23 | expect(wrapper.text()).toContain('Hello world'); 24 | }); 25 | it('should have class', () => { 26 | const wrapper = mount(dialog); 27 | expect(wrapper.classes()).toContain('tas-dialog'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/row.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | 4 | // @include b(row) { 5 | // display: flex; 6 | // flex-wrap: wrap; 7 | // position: relative; 8 | // box-sizing: border-box; 9 | 10 | // @include when(justify-center) { 11 | // justify-content: center; 12 | // } 13 | // @include when(justify-end) { 14 | // justify-content: flex-end; 15 | // } 16 | // @include when(justify-space-between) { 17 | // justify-content: space-between; 18 | // } 19 | // @include when(justify-space-around) { 20 | // justify-content: space-around; 21 | // } 22 | // @include when(justify-space-evenly) { 23 | // justify-content: space-evenly; 24 | // } 25 | // @include when(align-middle) { 26 | // align-items: center; 27 | // } 28 | // @include when(align-bottom) { 29 | // align-items: flex-end; 30 | // } 31 | // } 32 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/pagination.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | 4 | // @include b(pagination) { 5 | // display: flex; 6 | // justify-content: flex-start; 7 | // padding: 30px; 8 | // & > a { 9 | // display: inline-block; 10 | // padding: 5px 10px; 11 | // border: 1px solid #e4e4e4; 12 | // border-radius: 4px; 13 | // margin-right: 10px; 14 | // text-decoration: none; 15 | // color: #333; 16 | // &:hover { 17 | // color: #9090c0; 18 | // } 19 | // &.active { 20 | // background: #9090c0; 21 | // color: #fff; 22 | // border-color: #9090c0; 23 | // } 24 | // &.disabled { 25 | // cursor: not-allowed; 26 | // opacity: 0.4; 27 | // &:hover { 28 | // color: #333; 29 | // } 30 | // } 31 | // } 32 | // & > span { 33 | // margin-right: 10px; 34 | // } 35 | // } 36 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # ci.yml 2 | name: Tass UI 3 | on: 4 | push: 5 | branches: 6 | - main 7 | jobs: 8 | build-and-deploy: 9 | concurrency: ci-${{ github.ref }} 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 🛎️ # 将代码拉取到虚拟机 13 | uses: actions/checkout@v3 14 | 15 | - name: Install pnpm 16 | run: npm i pnpm@7 -g 17 | 18 | - uses: actions/setup-node@v3 19 | with: 20 | node-version: '16' 21 | cache: 'pnpm' 22 | 23 | - name: Install and Build 🔧 # 安装依赖、打包,如果提前已打包好无需这一步 24 | run: | 25 | pnpm install 26 | pnpm run build:components 27 | pnpm run docs:build 28 | 29 | - name: Deploy 🚀 # 部署 30 | uses: JamesIves/github-pages-deploy-action@v4.3.3 31 | with: 32 | branch: gh-pages # 部署后提交到那个分支 33 | folder: docs/.vitepress/dist # 这里填打包好的目录名称 34 | -------------------------------------------------------------------------------- /packages/components/dropdown/__tests__/dropdwon.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @name: dropdwon.test.ts 3 | * @author: cxy 4 | * @date: 2023/2/12 17:43 5 | * @description:dropdwon.test.ts 6 | * @update: 2023/2/12 17:43 7 | */ 8 | import { describe, expect, it } from 'vitest'; 9 | 10 | import { mount } from '@vue/test-utils'; 11 | import dropdown from '../src/dropdwon.vue'; 12 | // The component to test 13 | 14 | describe('test dropdown', () => { 15 | it('should render slot', () => { 16 | const wrapper = mount(dropdown, { 17 | slots: { 18 | default: '' 19 | } 20 | }); 21 | 22 | // Assert the rendered text of the component 23 | expect(wrapper.text()).toContain(''); 24 | it('should have class', () => { 25 | const wrapper = mount(dropdown); 26 | expect(wrapper.classes()).toContain('tas-dropdown'); 27 | }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/backtop.scss: -------------------------------------------------------------------------------- 1 | // @use 'sass:math'; 2 | 3 | // @use 'mixins/mixins' as *; 4 | // @use 'common/var' as *; 5 | 6 | // @include b(backtop) { 7 | 8 | // position: fixed; 9 | // right: 50px; 10 | // bottom: 50px; 11 | // z-index: 2; 12 | // border: 1px solid $color-primary; 13 | // border-radius: 50%; 14 | // width: 50px; 15 | // height: 50px; 16 | // display: flex; 17 | // cursor: pointer; 18 | // justify-content: center; 19 | // align-items: center; 20 | // transition: all ease-in-out .5s; 21 | // overflow: hidden; 22 | // &:hover { 23 | // color: $color-primary; 24 | // background-color: $color-primary-light-7; 25 | 26 | // } 27 | // @include b(backtop-icon) { 28 | // color:$color-primary; 29 | 30 | // &:hover { 31 | 32 | // color: $color-primary-light-12; 33 | // background-color: $color-primary-light-7; 34 | // } 35 | 36 | // } 37 | // } 38 | -------------------------------------------------------------------------------- /packages/components/transfer/__tests__/transfer.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-13 15:56:13 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\transfer\__tests__\transfer.test.ts 6 | */ 7 | import { describe, expect, it } from 'vitest'; 8 | 9 | import { mount } from '@vue/test-utils'; 10 | import transfer from '../src/transfer.vue'; 11 | // The component to test 12 | 13 | describe('test transfer', () => { 14 | it('should render slot', () => { 15 | const wrapper = mount(transfer, { 16 | slots: { 17 | default: '' 18 | } 19 | }); 20 | 21 | // Assert the rendered text of the component 22 | expect(wrapper.text()).toContain(''); 23 | }); 24 | it('should have class', () => { 25 | const wrapper = mount(transfer, { 26 | props: { 27 | type: 'primary' 28 | } 29 | }); 30 | expect(wrapper.classes()).toContain('tas-transfer'); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /docs/components/dialog/dialogdefault.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 35 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/common/popup.scss: -------------------------------------------------------------------------------- 1 | @use './var' as *; 2 | @use '../mixins/mixins' as *; 3 | @use '../mixins/var' as *; 4 | 5 | :root { 6 | @include set-component-css-var('popup', $popup); 7 | } 8 | 9 | .v-modal-enter { 10 | animation: v-modal-in getCssVar('transition-duration-fast') ease; 11 | } 12 | 13 | .v-modal-leave { 14 | animation: v-modal-out getCssVar('transition-duration-fast') ease forwards; 15 | } 16 | 17 | @keyframes v-modal-in { 18 | 0% { 19 | opacity: 0; 20 | } 21 | 100% { 22 | } 23 | } 24 | 25 | @keyframes v-modal-out { 26 | 0% { 27 | } 28 | 100% { 29 | opacity: 0; 30 | } 31 | } 32 | 33 | .v-modal { 34 | position: fixed; 35 | left: 0; 36 | top: 0; 37 | width: 100%; 38 | height: 100%; 39 | opacity: getCssVar('popup-modal-opacity'); 40 | background: getCssVar('popup-modal-bg-color'); 41 | } 42 | 43 | @include b(popup-parent) { 44 | @include m(hidden) { 45 | overflow: hidden; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/components/transfer/src/composables/use-component-data.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-25 11:40:08 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-01-25 20:07:21 7 | */ 8 | import { computed } from 'vue'; 9 | export const useComponentData = props => { 10 | const propKey = computed(() => props.props.key); 11 | const data = computed(() => { 12 | return props.data.reduce((memo, current) => { 13 | memo[current[propKey.value]] = current; 14 | return memo; 15 | }, {}); 16 | }); 17 | 18 | const sourceData = computed(() => { 19 | return props.data.filter(item => !props.modelValue.includes(item[propKey.value])); 20 | }); 21 | 22 | const targetData = computed(() => { 23 | return props.data.filter(item => props.modelValue.includes(item[propKey.value])); 24 | }); 25 | 26 | return { 27 | propKey, 28 | sourceData, 29 | targetData 30 | }; 31 | }; 32 | -------------------------------------------------------------------------------- /docs/components/dialog/dialog.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 36 | -------------------------------------------------------------------------------- /packages/components/button/__tests__/button.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-22 16:51:31 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-06 14:15:27 7 | */ 8 | import { describe, expect, it } from 'vitest'; 9 | 10 | import { mount } from '@vue/test-utils'; 11 | import button from '../src/button.vue'; 12 | // The component to test 13 | 14 | describe('test Button', () => { 15 | it('should render slot', () => { 16 | const wrapper = mount(button, { 17 | slots: { 18 | default: 'Hello world' 19 | } 20 | }); 21 | 22 | // Assert the rendered text of the component 23 | expect(wrapper.text()).toContain('Hello world'); 24 | }); 25 | it('should have class', () => { 26 | const wrapper = mount(button, { 27 | props: { 28 | type: 'primary' 29 | } 30 | }); 31 | expect(wrapper.classes()).toContain('tas-button--primary'); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/components/dropdown/src/dropdownItem.vue: -------------------------------------------------------------------------------- 1 | 8 | 15 | 16 | 39 | -------------------------------------------------------------------------------- /packages/components/dropdown/src/dropdwon.vue: -------------------------------------------------------------------------------- 1 | 8 | 13 | 14 | 38 | -------------------------------------------------------------------------------- /docs/components/table/detile.vue: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/style/var.css: -------------------------------------------------------------------------------- 1 | :root { 2 | /* 标题 */ 3 | --vp-home-hero-name-color: transparent; 4 | --vp-home-hero-name-background: linear-gradient(135deg, #9090c0 10%, #595b83 100%); 5 | 6 | /* 图标背景 */ 7 | --vp-home-hero-image-background-image: linear-gradient(135deg, #9090c0 10%, #595b83 100%); 8 | --vp-home-hero-image-filter: blur(150px); 9 | 10 | /* brand按钮 */ 11 | --vp-button-brand-border: #9090c0; 12 | --vp-button-brand-text: #fff; 13 | --vp-button-brand-bg: #9090c0; 14 | 15 | --vp-button-brand-hover-border: #595b83; 16 | --vp-button-brand-hover-text: #fff; 17 | --vp-button-brand-hover-bg: #595b83; 18 | 19 | --vp-button-brand-active-border: #595b83; 20 | --vp-button-brand-active-text: #fff; 21 | --vp-button-brand-active-bg: #595b83; 22 | 23 | /* 主页 */ 24 | --vp-c-brand: #8888d0; 25 | --vp-c-brand-dark: #8888d0; 26 | 27 | --vp-custom-block-tip-border: #9090c0; 28 | --vp-custom-block-tip-text: #fff; 29 | --vp-custom-block-tip-bg: #9090c0; 30 | } 31 | -------------------------------------------------------------------------------- /packages/components/checkbox-group/src/checkbox-group.vue: -------------------------------------------------------------------------------- 1 | 8 | 13 | 34 | 35 | -------------------------------------------------------------------------------- /packages/components/dropdown/src/dropdownMenu.vue: -------------------------------------------------------------------------------- 1 | 8 | 15 | 16 | 40 | -------------------------------------------------------------------------------- /packages/components/input/__tests__/input.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-13 16:10:42 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\input\__tests__\data-picker.test.ts 6 | */ 7 | import input from '../src/input.vue'; 8 | 9 | import { describe, expect, it, test } from 'vitest'; 10 | import { mount } from '@vue/test-utils'; 11 | const list = ['diapers', 'kleenex', 'trash bags', 'paper towels', 'milk']; 12 | 13 | describe('test checkbox', () => { 14 | it('should render slot', () => { 15 | const wrapper = mount(input, { 16 | slots: { 17 | default: '' 18 | } 19 | }); 20 | 21 | // Assert the rendered text of the component 22 | expect(wrapper.text()).toContain(''); 23 | it('should have class', () => { 24 | const wrapper = mount(input); 25 | expect(wrapper.classes()).toContain('tas-input'); 26 | }); 27 | }); 28 | }); 29 | 30 | test('the shopping list has milk on it', () => { 31 | expect(list).toContain('milk'); 32 | expect(new Set(list)).toContain('milk'); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /packages/components/table/__tests__/table.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-13 15:49:42 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\table\__tests__\table.test.ts 6 | */ 7 | /* 8 | * @Author: 申恒杰 9 | * @Date: 2023-02-13 15:49:42 10 | * @Description: 铁沸物 11 | * @FilePath: \tass-ui\packages\components\table\__tests__\table.test.ts 12 | */ 13 | import { describe, expect, it } from 'vitest'; 14 | 15 | import { mount } from '@vue/test-utils'; 16 | import table from '../src/table.vue'; 17 | // The component to test 18 | 19 | describe('test table', () => { 20 | it('should render slot', () => { 21 | const wrapper = mount(table, { 22 | slots: { 23 | default: '' 24 | } 25 | }); 26 | 27 | // Assert the rendered text of the component 28 | expect(wrapper.text()).toContain(''); 29 | it('should have class', () => { 30 | const wrapper = mount(table); 31 | expect(wrapper.classes()).toContain('tas-table'); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /docs/components/table/size.vue: -------------------------------------------------------------------------------- 1 | 7 | 13 | 14 | -------------------------------------------------------------------------------- /packages/components/message/__tests__/message.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-13 16:10:42 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\message\__tests__\message.test.ts 6 | */ 7 | import message from '../src/message.vue'; 8 | 9 | import { describe, expect, it, test } from 'vitest'; 10 | import { mount } from '@vue/test-utils'; 11 | const list = ['diapers', 'kleenex', 'trash bags', 'paper towels', 'milk']; 12 | 13 | describe('test checkbox', () => { 14 | it('should render slot', () => { 15 | const wrapper = mount(message, { 16 | slots: { 17 | default: '' 18 | } 19 | }); 20 | 21 | // Assert the rendered text of the component 22 | expect(wrapper.text()).toContain(''); 23 | it('should have class', () => { 24 | const wrapper = mount(message); 25 | expect(wrapper.classes()).toContain('tas-message'); 26 | }); 27 | }); 28 | }); 29 | 30 | test('the shopping list has kleenex on it', () => { 31 | expect(list).toContain('kleenex'); 32 | expect(new Set(list)).toContain('kleenex'); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 huccct 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/components/breadcrumb/src/breadcrumb.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 33 | -------------------------------------------------------------------------------- /docs/components/swiper/default.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /packages/components/breadcrumb-item/src/breadcrumb-item.vue: -------------------------------------------------------------------------------- 1 | 8 | 20 | 40 | -------------------------------------------------------------------------------- /packages/components/dropdown/src/dropdownMenuClick.vue: -------------------------------------------------------------------------------- 1 | 8 | 15 | 16 | 43 | -------------------------------------------------------------------------------- /docs/components/table/style.vue: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /packages/components/backtop/src/backtop.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 36 | 38 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/upload.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | // @include b(upload) { 4 | // width: 100%; 5 | // font-size: 0; 6 | // .drop-upload { 7 | // background-color: #fff; 8 | // border: 1px dashed #d9d9d9; 9 | // border-radius: 6px; 10 | // box-sizing: border-box; 11 | // width: 360px; 12 | // height: 180px; 13 | // display: flex; 14 | // align-items: center; 15 | // justify-content: center; 16 | // .drop-upload__out { 17 | // display: flex; 18 | // justify-content: center; 19 | // .drop-upload__out__word { 20 | // color: #606266; 21 | // margin-top: 16px; 22 | // font-size: 14px; 23 | // } 24 | // .drop-upload__out__uploadWord { 25 | // color:mediumpurple; 26 | // font-size: 14px; 27 | // cursor: pointer; 28 | // margin-top: 16px; 29 | // } 30 | // } 31 | // } 32 | // .file { 33 | // display: flex; 34 | // width: 100%; 35 | // margin-bottom: 3px; 36 | // align-items: center; 37 | // justify-content: space-between; 38 | 39 | // span { 40 | // font-size: 14px; 41 | // color: #666; 42 | // } 43 | // } 44 | 45 | // input { 46 | // width: 0 !important; 47 | // height: 0 !important; 48 | // } 49 | // } 50 | -------------------------------------------------------------------------------- /packages/components/col/src/row.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-23 15:46:05 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-08 11:39:48 7 | */ 8 | import '../style/'; 9 | import { computed, defineComponent, h, provide } from 'vue'; 10 | 11 | export default defineComponent({ 12 | name: 'TassRow', 13 | props: { 14 | tag: { 15 | type: String, 16 | default: 'div' 17 | }, 18 | gutter: { 19 | type: Number, 20 | default: 0 21 | }, 22 | justify: { 23 | type: String, 24 | default: 'start' 25 | } 26 | }, 27 | setup(props, ctx) { 28 | provide('TassRow', props.gutter); 29 | const Class = computed(() => [ 30 | 'tas-row', 31 | props.justify !== 'start' ? `is-justify-${props.justify}` : '' 32 | ]); 33 | const styles = computed(() => { 34 | const res = { 35 | marginLeft: '', 36 | marginRight: '' 37 | }; 38 | if (props.gutter) { 39 | res.marginLeft = res.marginRight = `-${props.gutter / 2}px`; 40 | } 41 | return res; 42 | }); 43 | return () => 44 | h( 45 | props.tag, 46 | { 47 | class: Class.value, 48 | style: styles.value 49 | }, 50 | ctx.slots.default?.() 51 | ); 52 | } 53 | }); 54 | -------------------------------------------------------------------------------- /docs/components/swiper/address.vue: -------------------------------------------------------------------------------- 1 | 7 | 23 | 24 | -------------------------------------------------------------------------------- /docs/components/message/different.vue: -------------------------------------------------------------------------------- 1 | 8 | 14 | 49 | -------------------------------------------------------------------------------- /docs/components/icon/index.md: -------------------------------------------------------------------------------- 1 | 8 | 11 | 28 | # Icon 图标 29 | Tass UI 提供了一套常用的图标集合。 30 | ## 基础用法 31 | 32 |
33 |   34 |   35 | 下载 36 |
37 |
38 |
39 | 40 |
41 | 展开查看 42 | 43 | ```vue 44 | 51 | ``` 52 |
53 | 54 | ## 所有图标 55 |
56 | 57 | 58 |
59 | -------------------------------------------------------------------------------- /packages/components/switch/__tests__/switch.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-01 21:33:37 4 | * @Description: 铁沸物 5 | * @FilePath: \tass-ui\packages\components\switch\__tests__\switch.test.ts 6 | */ 7 | import { describe, expect, it } from 'vitest'; 8 | 9 | import { mount } from '@vue/test-utils'; 10 | import switchtest from '../src/switch.vue'; 11 | // The component to test 12 | 13 | describe('test switch', () => { 14 | 15 | it('create', () => { 16 | const props = { 17 | activeText: 'on', 18 | inactiveText: 'off', 19 | activeColor: '#0f0', 20 | inactiveColor: '#f00', 21 | width: 100, 22 | } 23 | const wrapper = mount(switchtest) 24 | const vm = wrapper.vm 25 | expect(vm.$el.classList.contains('is-checked')).false 26 | const switchinput = vm.$el.querySelector('.tas-switch-input') 27 | const formswitch = wrapper.find('.tas-form-switch') 28 | expect(switchinput).toContain(vm.$el.querySelector('.tas-switch-input')); 29 | }) 30 | 31 | it('should render slot', () => { 32 | const wrapper = mount(switchtest, { 33 | slots: { 34 | default: '' 35 | } 36 | }); 37 | 38 | // Assert the rendered text of the component 39 | expect(wrapper.text()).toContain(''); 40 | it('should have class', () => { 41 | const wrapper = mount(switchtest); 42 | expect(wrapper.classes()).toContain('tas-switch'); 43 | }); 44 | }); 45 | 46 | }); 47 | -------------------------------------------------------------------------------- /packages/components/button/src/button.vue: -------------------------------------------------------------------------------- 1 | 8 | 24 | 25 | 49 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/dialog.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | // @include b(dialog){ 4 | // position: fixed; 5 | // left: 0; 6 | // top: 0; 7 | // width: 100vw; 8 | // height: 100vh; 9 | // background: rgba(0, 0, 0, 0.3); 10 | // user-select: none; 11 | // z-index: 999999; 12 | // transition: opacity 0.3s, transform 0.4s, top 0.4s; 13 | // @include b(dialog__body){ 14 | // display: table-cell; 15 | // width: 100vw; 16 | // height: 100vh; 17 | // text-align: center; 18 | // vertical-align: middle; 19 | // @include b(dialog__box){ 20 | // display: inline-block; 21 | // padding: 24px 24px 12px 24px; 22 | // background: white; 23 | // text-align: left; 24 | // } 25 | // @include b(dialog__header) { 26 | // display: flex; 27 | // justify-content: space-between; 28 | // z-index: 2147483647; 29 | // } 30 | // @include b(dialog__title) { 31 | // margin: 0; 32 | // color:black !important; 33 | // line-height: 30px; 34 | // width: calc(100% - 30px); 35 | // } 36 | // @include b(dialog__close) { 37 | // color:black; 38 | // cursor: pointer; 39 | // } 40 | // @include b(dialog__footer) { 41 | // text-align: right; 42 | // } 43 | // } 44 | // } 45 | // .tas-dialog-fade-enter-from, 46 | // .tas-dialog-fade-leave-to { 47 | // opacity: 0; 48 | // transform: translateX(0),translateY(1); 49 | // } 50 | -------------------------------------------------------------------------------- /docs/components/table/slot.vue: -------------------------------------------------------------------------------- 1 | 7 | 18 | 19 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/carousel-item.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | 4 | // @include b(carousel) { 5 | // @include e(item) { 6 | // position: absolute; 7 | // top: 0; 8 | // left: 0; 9 | // width: 100%; 10 | // height: 100%; 11 | // display: inline-block; 12 | // overflow: hidden; 13 | // z-index: calc(getCssVar('index', 'normal') - 1); 14 | 15 | // @include when(active) { 16 | // z-index: calc(getCssVar('index', 'normal') - 1); 17 | // } 18 | 19 | // @include when(animating) { 20 | // transition: transform 0.4s ease-in-out; 21 | // } 22 | 23 | // @include m(card) { 24 | // width: 50%; 25 | // transition: transform 0.4s ease-in-out; 26 | // &.is-in-stage { 27 | // cursor: pointer; 28 | // z-index: getCssVar('index', 'normal'); 29 | // &:hover .#{$namespace}-carousel__mask, 30 | // &.is-hover .#{$namespace}-carousel__mask { 31 | // opacity: 0.12; 32 | // } 33 | // } 34 | // &.is-active { 35 | // z-index: calc(getCssVar('index', 'normal') + 1); 36 | // } 37 | // } 38 | // } 39 | 40 | // @include e(mask) { 41 | // position: absolute; 42 | // width: 100%; 43 | // height: 100%; 44 | // top: 0; 45 | // left: 0; 46 | // background-color: getCssVar('color', 'white'); 47 | // opacity: 0.24; 48 | // transition: getCssVar('transition-duration', 'fast'); 49 | // } 50 | // } 51 | -------------------------------------------------------------------------------- /docs/components/message/closeable.vue: -------------------------------------------------------------------------------- 1 | 8 | 14 | 53 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/progress.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | 4 | // @include b(progress) { 5 | // width: 100%; 6 | // display: flex; 7 | // align-items: center; 8 | // justify-content: space-between; 9 | // margin: 10px 5px; 10 | // .line { 11 | // width: 90%; 12 | // background-color: rgb(235, 238, 245); 13 | // border-radius: 100px; 14 | // .colorLine { 15 | // height: 6px; 16 | // text-align: right; 17 | // border-radius: 100px; 18 | // line-height: 1; 19 | // white-space: nowrap; 20 | // transition: width 0.6s ease; 21 | // } 22 | // } 23 | // .percent { 24 | // min-width: 8%; 25 | // font-size: 14.4px; 26 | // color: rgb(96, 98, 102); 27 | // text-align: left; 28 | // } 29 | 30 | // .status { 31 | // width: 8%; 32 | // text-align: left; 33 | // } 34 | // } 35 | // @include b(circleprogress) { 36 | // display: inline-flex; 37 | // align-items: center; 38 | // justify-content: center; 39 | // position: relative; 40 | // height: 100px; 41 | // text-align: center; 42 | // @include e(svgCircle) { 43 | // position: relative; 44 | // transform: rotate(-90deg); 45 | // } 46 | // .svg-progress { 47 | // stroke: #2196f3; 48 | // stroke-linecap: round; 49 | // transition: all 0.3s linear; 50 | // } 51 | // .mask { 52 | // position: absolute; 53 | // top: 50%; 54 | // left: 50%; 55 | // transform: translate(-50%, -50%); 56 | // } 57 | // } 58 | -------------------------------------------------------------------------------- /packages/eslint-config/eslint.rules.js: -------------------------------------------------------------------------------- 1 | /* eslint配置规则 https://eslint.org/docs/latest/rules/ */ 2 | module.exports = { 3 | 'prettier/prettier': 'error', 4 | 'arrow-body-style': 'off', 5 | 'prefer-arrow-callback': 'off', 6 | 'no-console': 2, 7 | // 不允许不必要的转义字符 https://eslint.org/docs/latest/rules/no-useless-escape 8 | 'no-useless-escape': 'off', 9 | // 10 | 'comma-dangle': 'off', 11 | // 禁止使用 var https://eslint.org/docs/latest/rules/no-var#rule-details 12 | 'no-var': 'off', 13 | // 使用单引号 https://eslint.org/docs/latest/rules/quotes#version 14 | quotes: ['error', 'single'], 15 | // 禁止分号 https://eslint.org/docs/latest/rules/semi#rule-details 16 | // semi: 'error', 17 | // 禁止 debugger https://eslint.org/docs/latest/rules/no-debugger#rule-details 18 | 'no-debugger': 'error', 19 | // 禁止未使用的变量 https://eslint.org/docs/latest/rules/no-unused-vars#rule-details 20 | 'no-unused-vars': 'off', 21 | // 不允许使用未声明的变量 https://eslint.org/docs/latest/rules/no-undef 22 | 'no-undef': 'off', 23 | // 函数括号前的空格 https://eslint.org/docs/latest/rules/space-before-function-paren 24 | 'space-before-function-paren': 'off', 25 | // 禁止多个空行 https://eslint.org/docs/latest/rules/no-multiple-empty-lines#rule-details 26 | 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0, maxBOF: 0 }], 27 | // 在文件末尾要求或禁止换行 https://eslint.org/docs/latest/rules/eol-last#rule-details 28 | 'eol-last': 'error', 29 | // 禁止所有选项卡 https://eslint.org/docs/latest/rules/no-tabs#rule-details 30 | 'no-tabs': 'error', 31 | 'default-param-last': 'off' 32 | }; 33 | -------------------------------------------------------------------------------- /packages/components/transfer/src/transferItem.vue: -------------------------------------------------------------------------------- 1 | 8 | 23 | 46 | -------------------------------------------------------------------------------- /packages/components/col/src/col.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-23 15:46:01 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-08 11:30:00 7 | */ 8 | import '../style/'; 9 | import { computed, defineComponent, h, inject } from 'vue'; 10 | 11 | export default defineComponent({ 12 | name: 'TassCol', 13 | props: { 14 | tag: { 15 | type: String, 16 | default: 'div' 17 | }, 18 | span: { 19 | type: Number, 20 | default: 24 21 | }, 22 | offset: { 23 | type: Number, 24 | default: 0 25 | } 26 | }, 27 | setup(props, ctx) { 28 | const gutter = inject('TassRow') as number; 29 | 30 | const Class = computed(() => { 31 | const res: string[] = []; 32 | const pops = ['span', 'offset'] as const; 33 | pops.forEach(item => { 34 | const size = props[item]; 35 | 36 | if (typeof size === 'number' && size > 0) { 37 | res.push(`tas-col-${item}-${size}`); 38 | } 39 | }); 40 | return ['tas-col', ...res]; 41 | }); 42 | const styles = computed(() => { 43 | if (gutter !== 0) { 44 | return { 45 | paddingLeft: gutter / 2 + 'px', 46 | paddingRight: gutter / 2 + 'px' 47 | }; 48 | } 49 | return {}; 50 | }); 51 | return () => 52 | h( 53 | props.tag, 54 | { 55 | class: Class.value, 56 | style: styles.value 57 | }, 58 | ctx.slots.default?.() 59 | ); 60 | } 61 | }); 62 | -------------------------------------------------------------------------------- /docs/components/datepicker/index.md: -------------------------------------------------------------------------------- 1 | 8 | 12 | 26 | 27 | # DatePicker 日期选择器 28 | 29 | 用于选择或输入日期 30 | 31 | ## 选择某一天 32 | 33 | 以”日“为基本单位,基础的日期选择控件 34 | 35 |
36 | 37 |
38 |
39 | 展开查看 40 | 41 | ```vue 42 | 45 | 49 | ``` 50 | 51 |
52 | 53 | ## 设置自定义前缀的内容 54 | 55 | 前缀内容可以被自定义。 56 | 57 | 当你从其他 vue 组件或由渲染函数生成的组件中导入组件时, 你可以设置 prefix-icon 属性来定制前缀内容 58 | 59 |
60 | 61 |
62 |
63 | 展开查看 64 | 65 | ```vue 66 | 69 | 73 | ``` 74 | 75 |
76 | -------------------------------------------------------------------------------- /packages/components/transfer/src/composables/use-check.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-25 13:04:28 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-03 23:20:47 7 | */ 8 | 9 | import type { ComponentInternalInstance } from 'vue'; 10 | import { computed, watch, getCurrentInstance } from 'vue'; 11 | export const useCheck = (props, state) => { 12 | const { emit } = getCurrentInstance() as ComponentInternalInstance; 13 | const labelProps = computed(() => props.props.props.label); 14 | const keyProps = computed(() => props.props.props.key); 15 | const disabledProps = computed(() => props.props.props.disabled); 16 | 17 | const checkDisabled = computed(() => { 18 | return props.data.filter(item => !item[disabledProps.value]); 19 | }); 20 | const handlerChange = val => { 21 | state.allCheck = val; 22 | state.checked = val 23 | ? checkDisabled.value.map(item => { 24 | return item[keyProps.value]; 25 | }) 26 | : []; 27 | }; 28 | 29 | watch( 30 | () => state.checked, 31 | () => { 32 | const checkkeys = checkDisabled.value.map(item => item[keyProps.value]); 33 | state.allCheck = checkkeys.length > 0 && checkkeys.every(key => state.checked.includes(key)); 34 | emit('checkChange', state.checked); 35 | } 36 | ); 37 | watch( 38 | () => props.data, 39 | () => { 40 | state.allCheck = false; 41 | } 42 | ); 43 | return { 44 | labelProps, 45 | keyProps, 46 | disabledProps, 47 | handlerChange 48 | }; 49 | }; 50 | -------------------------------------------------------------------------------- /packages/components/components.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-21 11:53:35 5 | * @LastEditors: Please set LastEditors 6 | * @LastEditTime: 2023-02-12 19:21:03 7 | */ 8 | export { TassButton } from './button'; 9 | export { TassButtonGroup } from './button-group'; 10 | export { TassIcon } from './icon'; 11 | export { TassCol } from './col/'; 12 | export { TassRow } from './row'; 13 | export { TassCheckbox } from './checkbox'; 14 | export { TassCheckboxGroup } from './checkbox-group'; 15 | export { TassTransfer } from './transfer'; 16 | export { TassMessage } from './message'; 17 | export { TassCollapse } from './collapse'; 18 | export { TassDropdown } from './dropdown'; 19 | export { TassDropdownItem } from './dropdown-item'; 20 | export { TassDropdownMenu } from './dropdown-menu'; 21 | export { TassDropdownMenuClick } from './dropdown-menu-click'; 22 | export { TassDialog } from './dialog'; 23 | export { TassAlert } from './alert'; 24 | export { TassCarousel } from './carousel'; 25 | export { TassCarouselItem } from './carousel-item'; 26 | export { TassSwitch } from './switch'; 27 | export { TassSlider } from './slider'; 28 | export { TassUpload } from './upload'; 29 | export { TassInput } from './input'; 30 | export { TassTable } from './table'; 31 | export { TassBreadcrumb } from './breadcrumb'; 32 | export { TassBreadcrumbItem } from './breadcrumb-item'; 33 | export { TassProgress } from './progress'; 34 | export { TassPagination } from './pagination'; 35 | export { TassBacktop } from './backtop'; 36 | export { TassDatePicker } from './date-picker'; 37 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/slider.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | // @include b(slider) { 4 | // width: 50%; 5 | // @include b(slider__content) { 6 | // position: relative; 7 | // cursor: pointer; 8 | // -webkit-user-drag: none; 9 | // user-select: none; 10 | // width: calc(100%); 11 | // } 12 | // @include b(slider__track) { 13 | // width: 100%; 14 | // height: 6px; 15 | // border-radius: 3px; 16 | // background-color: #e1e1e1; 17 | // overflow: hidden; 18 | // &:hover { 19 | // background: #e1e1e1; 20 | // } 21 | // } 22 | // @include b(slider__fill) { 23 | // background-color: $color-primary; 24 | // height: 100%; 25 | // width: 20%; 26 | // } 27 | // @include b(slider__thumb) { 28 | // position: absolute; 29 | // height: 14px; 30 | // width: 14px; 31 | // border-radius: 50%; 32 | // border: 2px solid $color-primary; 33 | // background: white; 34 | // cursor: pointer; 35 | // z-index: 100; 36 | // top: 50%; 37 | // transform: translateY(-50%); 38 | // } 39 | // @include b(slider__other) { 40 | // position: absolute; 41 | // left: 0; 42 | // top: -25px; 43 | // } 44 | // @include b(slider__value) { 45 | // display: inline-block; 46 | // margin-left: 50%; 47 | // transform: translateX(-50%); 48 | // } 49 | // @include b(slider__thumb-active) { 50 | // height: 20px; 51 | // width: 20px; 52 | // } 53 | 54 | // @include b(slider__thumb-disabled) { 55 | // cursor: not-allowed; 56 | // border: 2px solid black; 57 | // background: black; 58 | // } 59 | // } 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 8 |

9 | Tass 10 |

11 |

12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |

22 | 23 | - 💪 Vue 3 Composition API 24 | - 🔥 Written in TypeScript 25 | 26 | ## 安装 27 | 28 | ``` 29 | npm i tass-ui -S 30 | ``` 31 | 32 | ## 快速开始 33 | 34 | ```vue 35 | 38 | ``` 39 | 40 | ```ts 41 | // main.ts 42 | import { createApp } from 'vue'; 43 | import App from './App.vue'; 44 | import TassUI from 'tass-ui'; 45 | import 'tass-ui/es/style.css'; 46 | const app = createApp(App); 47 | app.use(TassUI).mount('#app'); 48 | ``` 49 | 50 | ## 在线文档 51 | 52 | https://huccct.github.io/tass-ui 53 | 54 | ## 使用仓库相关命令 55 | 56 | ### 安装 pnpm 57 | 58 | ``` 59 | npm i pnpm -g 60 | ``` 61 | 62 | ### 安装所有依赖 63 | 64 | ``` 65 | pnpm install 66 | ``` 67 | 68 | ### 启动本地测试项目 69 | 70 | ``` 71 | pnpm run dev 72 | ``` 73 | 74 | ### 打包组件库 75 | 76 | ``` 77 | pnpm run build:components 78 | ``` 79 | 80 | ### 启动文档 81 | 82 | ``` 83 | pnpm run docs:dev 84 | ``` 85 | 86 | ### 单元测试 87 | 88 | ``` 89 | pnpm run test 90 | ``` 91 | 92 | ### 查看测试覆盖率 93 | 94 | ``` 95 | pnpm run coverage 96 | ``` 97 | -------------------------------------------------------------------------------- /docs/components/slider/index.md: -------------------------------------------------------------------------------- 1 | 8 | 24 | 25 | # Slider 滑块 26 | 27 | 通过拖动滑块在一个固定区间内进行选择。 28 | 29 | ## 基础用法 30 | 31 |
32 |

33 | 34 |
35 | 36 |
37 | 展开查看 38 | 39 | ```vue 40 | 44 | ``` 45 | 46 |
47 | 48 | ## 自定义初末值 49 | 50 | 通过设置 min 与 mix , 来展示初末位置。 51 | 52 |
53 | 54 |
55 | 56 |
57 | 展开查看 58 | 59 | ```vue 60 | 63 | ``` 64 | 65 |
66 | 67 | ## 自定义初始值 68 | 69 | 通过设置 value , 来展示初始值。 70 | 71 |
72 | 73 |
74 | 75 |
76 | 展开查看 77 | 78 | ```vue 79 | 82 | ``` 83 | 84 |
85 | -------------------------------------------------------------------------------- /packages/components/carousel/src/carousel.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 申恒杰 3 | * @Date: 2023-02-02 19:23:39 4 | * @Description: 铁沸物 5 | * @FilePath: \echo-ui\packages\components\carousel\src\index.ts 6 | */ 7 | declare const isNumber: (val: any) => val is number; 8 | import type { ExtractPropTypes } from 'vue'; 9 | 10 | export const carouselProps = { 11 | initialIndex: { 12 | type: Number, 13 | default: 0 14 | }, 15 | height: { 16 | type: String, 17 | default: '' 18 | }, 19 | trigger: { 20 | type: String, 21 | values: ['hover', 'click'], 22 | default: 'hover' 23 | }, 24 | autoplay: { 25 | type: Boolean, 26 | default: true 27 | }, 28 | interval: { 29 | type: Number, 30 | default: 3000 31 | }, 32 | indicatorPosition: { 33 | type: String, 34 | values: ['', 'none', 'outside'], 35 | default: '' 36 | }, 37 | indicator: { 38 | type: Boolean, 39 | default: true 40 | }, 41 | arrow: { 42 | type: String, 43 | values: ['always', 'hover', 'never'], 44 | default: 'hover' 45 | }, 46 | type: { 47 | type: String, 48 | values: ['', 'card'], 49 | default: '' 50 | }, 51 | loop: { 52 | type: Boolean, 53 | default: true 54 | }, 55 | direction: { 56 | type: String, 57 | values: ['horizontal', 'vertical'], 58 | default: 'horizontal' 59 | }, 60 | pauseOnHover: { 61 | type: Boolean, 62 | default: true 63 | } 64 | }; 65 | 66 | export const carouselEmits = { 67 | change: (current: number, prev: number) => [current, prev].every(isNumber) 68 | }; 69 | 70 | export type CarouselProps = ExtractPropTypes; 71 | export type CarouselEmits = typeof carouselEmits; 72 | -------------------------------------------------------------------------------- /docs/components/pagination/index.md: -------------------------------------------------------------------------------- 1 | 5 | 22 | 23 | # Pagination 分页 24 | 当数据量过多时,使用分页分解数据。 25 | 26 | ## 基础用法 27 | total表示总条目数,pagesize用于设置每页显示的页码数量,page默认起始页 28 |
29 | 30 |
31 | 32 |
33 | 展开查看 34 | 35 | ```vue 36 | 46 | 53 | ``` 54 |
55 | 56 | ## 设置最大页码按钮数 57 | 当总页数超过 pagesize 时,Pagination 会折叠多余的页码按钮。通过调节 pagesize 来设置 58 |
59 | 60 |
61 | 62 |
63 | 展开查看 64 | 65 | ```vue 66 | 76 | 83 | ``` 84 |
-------------------------------------------------------------------------------- /packages/eslint-config/ts.rules.js: -------------------------------------------------------------------------------- 1 | /* ts配置规则 https://typescript-eslint.io/rules */ 2 | module.exports = { 3 | // 规定数组类型定义方式 https://typescript-eslint.io/rules/array-type 4 | '@typescript-eslint/array-type': 'error', 5 | // 禁止使用大写 String、Number 定义类型 https://typescript-eslint.io/rules/ban-types 6 | '@typescript-eslint/ban-types': 'off', // beta 7 | // 不允许尾随逗号 https://typescript-eslint.io/rules/comma-dangle 8 | '@typescript-eslint/comma-dangle': 'error', 9 | // 强制使用 interface 定义类型 https://typescript-eslint.io/rules/consistent-type-definitions 10 | '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], 11 | // 统一导出规则 https://typescript-eslint.io/rules/consistent-type-exports 12 | // '@typescript-eslint/consistent-type-exports': 'error', 13 | // 自定义对象类型样式 https://typescript-eslint.io/rules/consistent-indexed-object-style 14 | '@typescript-eslint/consistent-indexed-object-style': ['warn', 'record'], 15 | // !禁止使用后缀运算符的非空断言 https://typescript-eslint.io/rules/no-non-null-assertion/ 16 | '@typescript-eslint/no-non-null-assertion': 'off', 17 | // 强制一致地使用类型导入 https://typescript-eslint.io/rules/consistent-type-imports 18 | '@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports' }], 19 | // 禁止未使用的变量 https://typescript-eslint.io/rules/no-unused-vars 20 | '@typescript-eslint/no-unused-vars': 'error', 21 | // 不可以有 any https://typescript-eslint.io/rules/no-explicit-any/ 22 | '@typescript-eslint/no-explicit-any': 'off', 23 | // 不可以有 require https://typescript-eslint.io/rules/no-var-requires/ 24 | '@typescript-eslint/no-var-requires': 'off', 25 | // 带有默认值的函数参数在最后 https://typescript-eslint.io/rules/default-param-last 26 | '@typescript-eslint/default-param-last': 'error', 27 | // 必须标记函数返回值 https://typescript-eslint.io/rules/explicit-function-return-type 28 | '@typescript-eslint/explicit-function-return-type': 'off' 29 | }; 30 | -------------------------------------------------------------------------------- /packages/components/collapse/src/collapse.vue: -------------------------------------------------------------------------------- 1 | 8 | 32 | 33 | 66 | -------------------------------------------------------------------------------- /packages/components/checkbox/src/checkbox.vue: -------------------------------------------------------------------------------- 1 | 8 | 30 | 64 | 65 | -------------------------------------------------------------------------------- /packages/components/button/src/button.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-21 11:57:34 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-06-16 19:44:08 7 | */ 8 | import type { ExtractPropTypes, PropType } from 'vue'; 9 | import type { ButtonNativeType, ButtonSizeType, ButtonType } from './interface'; 10 | 11 | export const Props = { 12 | type: { 13 | type: String as PropType, 14 | default: (): ButtonType => 'default', 15 | validator(value: ButtonType) { 16 | return (['default', 'primary', 'success', 'info', 'danger', 'warning'] as const).includes( 17 | value 18 | ); 19 | } 20 | }, 21 | size: { 22 | type: String as PropType, 23 | validator(value: ButtonSizeType) { 24 | return (['default', 'medium', 'small', 'mini', 'tiny'] as const).includes(value); 25 | } 26 | }, 27 | plain: { 28 | type: Boolean, 29 | default: (): Boolean => false 30 | }, 31 | round: { 32 | type: Boolean, 33 | default: (): Boolean => false 34 | }, 35 | circle: { 36 | type: Boolean, 37 | default: (): Boolean => false 38 | }, 39 | loading: { 40 | type: Boolean, 41 | default: (): Boolean => false 42 | }, 43 | disabled: { 44 | type: Boolean, 45 | default: (): Boolean => false 46 | }, 47 | icon: { 48 | type: String, 49 | default: (): String => '' 50 | }, 51 | autoFocus: { 52 | type: Boolean, 53 | default: (): Boolean => false 54 | }, 55 | nativeType: { 56 | type: String as PropType, 57 | default: (): ButtonNativeType => 'button', 58 | validator(value: ButtonNativeType) { 59 | return (['button', 'submit', 'reset'] as const).includes(value); 60 | } 61 | } 62 | }; 63 | 64 | export const Emits = { 65 | click: (evt: MouseEvent): MouseEvent => evt 66 | }; 67 | 68 | export type ButtonProps = ExtractPropTypes; 69 | -------------------------------------------------------------------------------- /docs/components/upload/index.md: -------------------------------------------------------------------------------- 1 | 8 | 22 | # Upload 上传 23 | 通过点击或者拖拽上传文件。 24 | ## 基础用法 25 | 通过点击上传文件。 26 |
27 | 28 |
29 | 30 |
31 | 展开查看 32 | 33 | ```vue 34 | 39 | 40 | 50 | ``` 51 |
52 | 53 | ## 拖拽上传 54 | 通过点击或者拖拽文件实现上传。 55 |
56 | 57 |
58 | 59 |
60 | 展开查看 61 | 62 | ```vue 63 | 68 | 69 | 75 | ``` 76 |
-------------------------------------------------------------------------------- /packages/components/checkbox/composables/use-checkbox-props.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-01-24 13:40:26 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-05 15:42:21 7 | */ 8 | import type { ComponentInternalInstance } from 'vue'; 9 | import { inject } from 'vue'; 10 | import { computed, getCurrentInstance } from 'vue'; 11 | import type { checkBoxProps, T } from '@tass-ui/components/checkbox/src/checkbox.type'; 12 | import { UPDATE_MODEL_EVENT, CHANGE_EVENT } from '@tass-ui/constants'; 13 | function useModel(props: checkBoxProps) { 14 | const { emit } = getCurrentInstance() as ComponentInternalInstance; 15 | const useProvide = inject('TassCheckboxGroup', {}); 16 | const model = computed({ 17 | get() { 18 | return useProvide.modelValue ? useProvide.modelValue.value : props.modelValue; 19 | }, 20 | set(val: unknown) { 21 | if (useProvide.modelValue) { 22 | return useProvide.handlerChange?.(val); 23 | } 24 | emit(UPDATE_MODEL_EVENT, val); 25 | } 26 | }); 27 | return model; 28 | } 29 | function useCheckbox(props: checkBoxProps, model) { 30 | const isChecked = computed(() => { 31 | const value = model.value; 32 | if (Array.isArray(value)) { 33 | return value.includes(props.label); 34 | } else { 35 | return value; 36 | } 37 | }); 38 | return isChecked; 39 | } 40 | 41 | function useEvent() { 42 | const { emit } = getCurrentInstance() as ComponentInternalInstance; 43 | function handlerChange(e) { 44 | const target = e.target; 45 | const val = target.checked ? true : false; 46 | emit(CHANGE_EVENT, val); 47 | } 48 | return handlerChange; 49 | } 50 | export const useCheckBoxProps = (props: checkBoxProps) => { 51 | const model = useModel(props); 52 | const isChecked = useCheckbox(props, model); 53 | const handlerChange = useEvent(); 54 | return { 55 | model, 56 | isChecked, 57 | handlerChange 58 | }; 59 | }; 60 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/mixins/_var.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:map'; 2 | 3 | @use 'config'; 4 | @use 'function' as *; 5 | @use '../common/var' as *; 6 | 7 | // set css var value, because we need translate value to string 8 | // for example: 9 | // @include set-css-var-value(('color', 'primary'), red); 10 | // --el-color-primary: red; 11 | @mixin set-css-var-value($name, $value) { 12 | #{joinVarName($name)}: #{$value}; 13 | } 14 | 15 | // @include set-css-var-type('color', 'primary', $map); 16 | // --el-color-primary: #{map.get($map, 'primary')}; 17 | @mixin set-css-var-type($name, $type, $variables) { 18 | #{getCssVarName($name, $type)}: #{map.get($variables, $type)}; 19 | } 20 | 21 | @mixin set-css-color-type($colors, $type) { 22 | @include set-css-var-value(('color', $type), map.get($colors, $type, 'base')); 23 | 24 | @each $i in (3, 5, 7, 8, 9) { 25 | @include set-css-var-value( 26 | ('color', $type, 'light', $i), 27 | map.get($colors, $type, 'light-#{$i}') 28 | ); 29 | } 30 | 31 | @include set-css-var-value(('color', $type, 'dark-2'), map.get($colors, $type, 'dark-2')); 32 | } 33 | 34 | // set all css var for component by map 35 | @mixin set-component-css-var($name, $variables) { 36 | @each $attribute, $value in $variables { 37 | @if $attribute == 'default' { 38 | #{getCssVarName($name)}: #{$value}; 39 | } @else { 40 | #{getCssVarName($name, $attribute)}: #{$value}; 41 | } 42 | } 43 | } 44 | 45 | @mixin set-css-color-rgb($type) { 46 | $color: map.get($colors, $type, 'base'); 47 | @include set-css-var-value(('color', $type, 'rgb'), #{red($color), green($color), blue($color)}); 48 | } 49 | 50 | // generate css var from existing css var 51 | // for example: 52 | // @include css-var-from-global(('button', 'text-color'), ('color', $type)) 53 | // --el-button-text-color: var(--el-color-#{$type}); 54 | @mixin css-var-from-global($var, $gVar) { 55 | $varName: joinVarName($var); 56 | $gVarName: joinVarName($gVar); 57 | #{$varName}: var(#{$gVarName}); 58 | } 59 | -------------------------------------------------------------------------------- /packages/components/dialog/src/dialog.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 64 | 65 | -------------------------------------------------------------------------------- /packages/components/vite.config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-05 16:01:16 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-07 12:54:00 7 | */ 8 | /// 9 | import { defineConfig } from 'vite'; 10 | import vue from '@vitejs/plugin-vue'; 11 | import dts from 'vite-plugin-dts'; 12 | import { resolve } from 'path'; 13 | export default defineConfig({ 14 | build: { 15 | target: 'modules', 16 | //打包文件目录 17 | outDir: 'es', 18 | //压缩 19 | minify: false, 20 | //css分离 21 | //cssCodeSplit: true, 22 | rollupOptions: { 23 | //忽略打包vue文件 24 | external: ['vue'], 25 | input: './index.ts', 26 | output: [ 27 | { 28 | format: 'es', 29 | //不用打包成.es.js,这里我们想把它打包成.js 30 | entryFileNames: '[name].mjs', 31 | //让打包目录和我们目录对应 32 | preserveModules: true, 33 | exports: 'named', 34 | //配置打包根目录 35 | dir: resolve(__dirname, '../../build/es') 36 | }, 37 | { 38 | format: 'cjs', 39 | entryFileNames: '[name].js', 40 | //让打包目录和我们目录对应 41 | preserveModules: true, 42 | exports: 'named', 43 | //配置打包根目录 44 | dir: resolve(__dirname, '../../build/lib') 45 | } 46 | ] 47 | }, 48 | lib: { 49 | entry: './index.ts', 50 | formats: ['es', 'cjs'], 51 | name: 'tass-ui' 52 | } 53 | }, 54 | plugins: [ 55 | vue(), 56 | dts({ 57 | entryRoot: 'components', 58 | outputDir: [ 59 | resolve(__dirname, '../../build/es/components'), 60 | resolve(__dirname, '../../build/lib/components') 61 | ], 62 | //指定使用的tsconfig.json为我们整个项目根目录下掉,如果不配置,你也可以在components下新建tsconfig.json 63 | tsConfigFilePath: '../../tsconfig.json' 64 | }) 65 | ], 66 | resolve: { 67 | alias: { 68 | '@': resolve(__dirname, 'components') 69 | } 70 | }, 71 | test: { 72 | environment: 'happy-dom' 73 | } 74 | }); 75 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/alert.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | 4 | // @include b(alert) { 5 | // display: flex; 6 | // align-items: center; 7 | // position: relative; 8 | // padding: 15px 16px; 9 | // margin-bottom: 5px; 10 | // border-radius: $alert-border-radius; 11 | // @include b(global-ellipsis){ 12 | // /*一行省略*/ 13 | // white-space: nowrap; 14 | // text-overflow: ellipsis; 15 | // overflow: hidden; 16 | 17 | // } 18 | // @include b(alert__content) { 19 | // overflow: auto; 20 | // padding-left: 15px; 21 | // } 22 | // @include b(alert__title) { 23 | // margin:0; 24 | // font-size: $alert-title-font-size; 25 | // } 26 | // @include b(alert__desc) { 27 | // margin: 0px; 28 | // font-size: $alert-description-font-size; 29 | // } 30 | // @include b(alert__close-btn) { 31 | // cursor: pointer; 32 | // position: absolute; 33 | // top: 50%; 34 | // transform: translateY(-50%); 35 | // right: 20px; 36 | // font-size: $alert-description-font-size; 37 | // } 38 | // @include m(warning) { 39 | // background-color: $alert-warning-color; 40 | // color: mix($color-white, $color-warning, 10%); 41 | // } 42 | // @include m(success) { 43 | // background-color: $alert-success-color; 44 | // color: mix($color-white, $color-success, 10%); 45 | // } 46 | // @include m(info) { 47 | // background-color: $alert-info-color; 48 | // color: mix($color-white, $color-info, 10%); 49 | // } 50 | // @include m(error) { 51 | // background-color: $alert-danger-color; 52 | // color: mix($color-white, $color-danger, 10%); 53 | // } 54 | // } 55 | // .is-center { 56 | // justify-content: center; 57 | // } 58 | // .tas-alert-fade-enter-from, 59 | // .tas-alert-fade-leave-to { 60 | // transform: translateX(100px); 61 | // opacity: 0; 62 | // } 63 | // .tas-alert-fade-enter-to, 64 | // .tas-alert-fade-leave-from { 65 | // opacity: 1; 66 | // } 67 | // .tas-alert-fade-enter-active, 68 | // .tas-alert-fade-leave-active { 69 | // transition: all 0.5s; 70 | // } 71 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/message.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | 4 | // @include b(message) { 5 | // width: fit-content; 6 | // // max-width: calc(100% + 25px); 7 | // max-width: calc(100% - 32px); 8 | // height: 42px; 9 | // // line-height: 42px; 10 | // font-size: 14px; 11 | // box-sizing: border-box; 12 | // border-radius: 5px; 13 | // border-width: 1px; 14 | // border-style: solid; 15 | // border-color: #ebeef5; 16 | // position: fixed; 17 | // left: 50%; 18 | // top: 20px; 19 | // transform: translateX(-50%); 20 | // background-color: $message-background-color; 21 | // transition: opacity 0.3s, transform 0.4s, top 0.4s; 22 | // overflow: hidden; 23 | // padding: $message-padding; 24 | // display: flex; 25 | // align-items: center; 26 | // z-index: 999; 27 | // box-shadow: 0 6px 16px 0 rgb(0 0 0 / 8%), 0 3px 6px -4px rgb(0 0 0 / 12%), 28 | // 0 9px 28px 8px rgb(0 0 0 / 5%); 29 | // @include b(message__close-btn) { 30 | // cursor: pointer; 31 | // position: absolute; 32 | // top: 50%; 33 | // transform: translateY(-50%); 34 | // right: 12px; 35 | // font-size: $message-close-size; 36 | // } 37 | // @include b(message__content) { 38 | // padding-left: 6px; 39 | // padding-right: 31px; 40 | // } 41 | // @include m(success) { 42 | // background: $message-success-font-color; 43 | // color: mix($color-white, $color-success, 10%); 44 | // } 45 | // @include m(error) { 46 | // background: $message-danger-font-color; 47 | // color: mix($color-white, $color-danger, 10%); 48 | // } 49 | // @include m(warning) { 50 | // background: $message-warning-font-color; 51 | // color: mix($color-white, $color-warning, 10%); 52 | // } 53 | // @include m(info) { 54 | // background: $message-info-font-color; 55 | // color: mix($color-white, $color-info, 10%); 56 | // } 57 | // @include when(center) { 58 | // justify-content: center; 59 | // } 60 | // } 61 | 62 | // .tas-message-fade-enter-from, 63 | // .tas-message-fade-leave-to { 64 | // opacity: 0; 65 | // transform: translate(-50%, -100%); 66 | // } 67 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/collapse.scss: -------------------------------------------------------------------------------- 1 | // @use 'sass:math'; 2 | 3 | // @use 'mixins/mixins' as *; 4 | // @use 'common/var' as *; 5 | 6 | // @include b(collapse) { 7 | 8 | // width: 45em; 9 | // padding: 1.5em; 10 | // height: max-content; 11 | // border: 1px solid $color-primary-light-11; 12 | // background-color: white; 13 | // border-radius: $border-radius-base; 14 | // @include b(collapse-ul) { 15 | // list-style-type: none; 16 | // margin: 0; 17 | // padding: 0; 18 | 19 | // } 20 | 21 | // } 22 | 23 | // [class^='#{$namespace}-collapse-title'] { 24 | // height: 50px; 25 | // line-height: 50px; 26 | // margin-top: 1em; 27 | // padding-left: 10px; 28 | // padding-right: 10px; 29 | // border-top: 0.2px solid $color-primary-light-11; 30 | // border-bottom: 0.2px solid $color-primary-light-11; 31 | // background: white; 32 | // color: $color-primary-light-10; 33 | // cursor: pointer; 34 | // } 35 | 36 | // // 箭头选中后的动画 37 | // .icon-select:before{ 38 | // transform: rotate(90deg); 39 | // display: inline-block; 40 | // transition: all 1s; 41 | 42 | // } 43 | 44 | // // 箭头未选中的动画 45 | // .icon-unselect:before{ 46 | // transform: rotate(0deg); 47 | // display: inline-block; 48 | // transition: all 1s; 49 | 50 | // } 51 | 52 | // [class^='#{$namespace}-collapse-content'] { 53 | 54 | // background: white; 55 | // color: $color-primary-light-10; 56 | // line-height: 1.769230769230769; 57 | // width: fit-content; 58 | // height: 100px; 59 | 60 | // } 61 | 62 | // .tas-collapse-enter-active { //定义进入过渡生效时的状态 63 | // height: 0px !important; 64 | // transition:all 1s ease; 65 | // overflow: hidden; 66 | // } 67 | // .tas-collapse-enter-to { //定义离开过渡的结束状态 68 | // height: 100px !important; 69 | // transition:all 1s ease; 70 | // overflow: hidden; 71 | // } 72 | 73 | // .tas-collapse-leave-active{ //定义离开过渡生效时的状态 74 | // height: 100px !important; 75 | // transition:all 1s ease; 76 | // overflow: hidden; 77 | // } 78 | 79 | // .tas-collapse-leave-to { //定义离开过渡的结束状态 80 | // height: 0px !important; 81 | // transition:all 1s ease; 82 | // overflow: hidden; 83 | // } 84 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/date-picker.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | 4 | // button { 5 | // cursor: pointer; 6 | // border: none; 7 | // outline: none; 8 | // } 9 | 10 | // @include b(datepicker) { 11 | // width: 250px; 12 | // cursor: pointer; 13 | // @include b(picker) { 14 | // position: absolute; 15 | // cursor: pointer; 16 | // width: 323px; 17 | // height: 300px; 18 | // color: #606266; 19 | // border: 1px solid #e4e7ed; 20 | // box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%); 21 | // background-color: #fff; 22 | // border-radius: 4px; 23 | // line-height: 30px; 24 | // margin: 5px 0; 25 | // z-index: 99; 26 | // @include e(header) { 27 | // cursor: pointer; 28 | // padding: 5px; 29 | // display: flex; 30 | // justify-content: space-around; 31 | // } 32 | // @include e(weeks) { 33 | // display: flex; 34 | // justify-content: space-around; 35 | // border-bottom: 1px solid #ddd; 36 | // padding: 5px; 37 | // } 38 | // @include e(content) { 39 | // display: flex; 40 | // justify-content: space-around; 41 | // margin-top: 5px; 42 | // & > span { 43 | // width: 30px; 44 | // text-align: center; 45 | // font-size: 14px; 46 | // } 47 | // & > span:hover { 48 | // background-color: $color-primary; 49 | // border-radius: 50%; 50 | // } 51 | // } 52 | // @include e(items) { 53 | // } 54 | // } 55 | // .tas-icon svg { 56 | // width: 1em; 57 | // height: 1em; 58 | // } 59 | // .isNotCurrentMonth { 60 | // color: #ccc; 61 | // pointer-events: none; 62 | // } 63 | // .isNotCurrentMonth:hover { 64 | // background-color: #fff !important; 65 | // } 66 | // .isToday { 67 | // border-radius: 50%; 68 | // background-color: $color-primary; 69 | // color: #fff; 70 | // font-weight: 700; 71 | // } 72 | // } 73 | 74 | // .tas-datepicker-transition-enter-active, 75 | // .tas-datepicker-transition-leave-active { 76 | // opacity: 1; 77 | // transition: all 0.5s ease-out; 78 | // } 79 | // .tas-datepicker-transition-enter-from, 80 | // .tas-datepicker-transition-leave-to { 81 | // opacity: 0; 82 | // } 83 | -------------------------------------------------------------------------------- /packages/components/message/src/message.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Stay hungry,Stay foolish 3 | * @Author: Huccct 4 | * @Date: 2023-02-08 23:09:59 5 | * @LastEditors: Huccct 6 | * @LastEditTime: 2023-02-09 15:29:20 7 | */ 8 | import { PropType, VNode, ExtractPropTypes, AppContext } from 'vue'; 9 | export const messageTypes = ['success', 'info', 'warning', 'error'] as const; 10 | export const MessageProps = { 11 | duration: { 12 | type: Number, 13 | default: 3000 14 | }, 15 | message: { 16 | type: [String, Object, Function] as PropType VNode)> 17 | }, 18 | dangerouslyUseHTMLString: { 19 | type: Boolean, 20 | default: false 21 | }, 22 | icon: { 23 | type: String, 24 | default: '' 25 | }, 26 | id: { 27 | type: String, 28 | default: '' 29 | }, 30 | onClose: { 31 | type: Function, 32 | required: false 33 | }, 34 | closeable: { 35 | type: Boolean, 36 | default: false 37 | }, 38 | type: { 39 | type: String, 40 | values: messageTypes, 41 | default: 'info' 42 | }, 43 | offset: { 44 | type: Number, 45 | default: 20 46 | }, 47 | zIndex: { 48 | type: Number, 49 | default: 0 50 | }, 51 | grouping: { 52 | type: Boolean, 53 | default: false 54 | }, 55 | repeatNum: { 56 | type: Number, 57 | default: 1 58 | }, 59 | center: { 60 | type: Boolean, 61 | default: true 62 | } 63 | }; 64 | 65 | export interface MessageHandle { 66 | close: () => void; 67 | } 68 | export type MessageFn = (( 69 | options?: MessageParams, 70 | appContext?: null | AppContext 71 | ) => MessageHandle) & { 72 | closeAll(): void; 73 | }; 74 | export type MessagePropsTypes = ExtractPropTypes; 75 | export type MessageParams = Partial | string | VNode | any; 76 | export type MessageOptionsTyped = Omit; 77 | export type MessageParamsTyped = Partial | string | VNode; 78 | export type MessageTypedFn = ( 79 | options?: MessageParamsTyped, 80 | appContext?: null | AppContext 81 | ) => MessageHandle; 82 | export interface Message extends MessageFn { 83 | success: MessageTypedFn; 84 | warning: MessageTypedFn; 85 | info: MessageTypedFn; 86 | error: MessageTypedFn; 87 | } 88 | -------------------------------------------------------------------------------- /packages/components/table/src/table.vue: -------------------------------------------------------------------------------- 1 | 7 | 41 | -------------------------------------------------------------------------------- /packages/components/message/src/message.vue: -------------------------------------------------------------------------------- 1 | 8 | 27 | 73 | 74 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/button-group.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:map'; 2 | 3 | @use 'common/var' as *; 4 | @use 'mixins/mixins' as *; 5 | @use 'mixins/utils' as *; 6 | 7 | @include b(button-group) { 8 | @include utils-clearfix; 9 | display: inline-block; 10 | vertical-align: middle; 11 | 12 | & > .#{$namespace}-button { 13 | float: left; 14 | position: relative; 15 | & + .#{$namespace}-button { 16 | margin-left: 0; 17 | } 18 | &:first-child { 19 | border-top-right-radius: 0; 20 | border-bottom-right-radius: 0; 21 | } 22 | &:last-child { 23 | border-top-left-radius: 0; 24 | border-bottom-left-radius: 0; 25 | } 26 | &:first-child:last-child { 27 | border-top-right-radius: map.get($button-border-radius, 'default'); 28 | border-bottom-right-radius: map.get($button-border-radius, 'default'); 29 | border-top-left-radius: map.get($button-border-radius, 'default'); 30 | border-bottom-left-radius: map.get($button-border-radius, 'default'); 31 | 32 | &.is-round { 33 | border-radius: getCssVar('border-radius', 'round'); 34 | } 35 | 36 | &.is-circle { 37 | border-radius: 50%; 38 | } 39 | } 40 | &:not(:first-child):not(:last-child) { 41 | border-radius: 0; 42 | } 43 | &:not(:last-child) { 44 | margin-right: -1px; 45 | } 46 | 47 | &:hover, 48 | &:focus, 49 | &:active { 50 | z-index: 1; 51 | } 52 | 53 | @include when(active) { 54 | z-index: 1; 55 | } 56 | } 57 | 58 | & > .#{$namespace}-dropdown { 59 | & > .#{$namespace}-button { 60 | border-top-left-radius: 0; 61 | border-bottom-left-radius: 0; 62 | border-left-color: getCssVar('button', 'divide-border-color'); 63 | } 64 | } 65 | 66 | @each $type in (primary, success, warning, danger, info) { 67 | .#{$namespace}-button--#{$type} { 68 | &:first-child { 69 | border-right-color: getCssVar('button', 'divide-border-color'); 70 | } 71 | &:last-child { 72 | border-left-color: getCssVar('button', 'divide-border-color'); 73 | } 74 | &:not(:first-child):not(:last-child) { 75 | border-left-color: getCssVar('button', 'divide-border-color'); 76 | border-right-color: getCssVar('button', 'divide-border-color'); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /docs/components/dialog/index.md: -------------------------------------------------------------------------------- 1 | 5 | 18 | 19 | # Dialog 对话框 20 | 21 | ## 基础用法 22 | 23 |
24 | 25 |
26 | 27 |
28 | 展开查看 29 | 30 | ```vue 31 | 41 | 42 | 55 | ``` 56 | 57 |
58 | 59 | ## 自定义内容 60 | 61 | 通过设置 title,来展示自定义内容。 62 | 63 |
64 | 65 |
66 | 67 |
68 | 展开查看 69 | 70 | ```vue 71 | 82 | 83 | 96 | ``` 97 | 98 |
99 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/checkbox.scss: -------------------------------------------------------------------------------- 1 | // @use './mixins/mixins.scss' as *; 2 | // @use './mixins/utils.scss' as *; 3 | // @use './common/var.scss' as *; 4 | 5 | // @include b(checkbox) { 6 | // color: $checkbox-font-color; 7 | // font-weight: $checkbox-font-weight; 8 | // font-size: $checkbox-font-size; 9 | // position: relative; 10 | // cursor: pointer; 11 | // display: inline-flex; 12 | // align-items: center; 13 | // white-space: nowrap; 14 | // user-select: none; 15 | // margin-right: 30px !important; 16 | // height: $checkbox-input-height; 17 | // input[type='checkbox'] { 18 | // cursor: pointer; 19 | // position: relative; 20 | // border: none; 21 | // background-color: none; 22 | // appearance: none; 23 | // width: 18px; 24 | // height: 18px; 25 | // } 26 | // input[type='checkbox']::after { 27 | // position: absolute; 28 | // top: 0; 29 | // background-color: #fff; 30 | // color: #fff; 31 | // width: 18px; 32 | // height: 18px; 33 | // display: inline-block; 34 | // visibility: visible; 35 | // padding-left: 0px; 36 | // text-align: center; 37 | // content: ' '; 38 | // border-radius: 2px; 39 | // box-sizing: border-box; 40 | // border: 1px solid #ddd; 41 | // } 42 | // input[type='checkbox']:checked::after { 43 | // content: '✓'; 44 | // background-color: $color-primary; 45 | // border-color: $color-primary; 46 | // background-color: $color-primary; 47 | // } 48 | // @include e(input) { 49 | // white-space: nowrap; 50 | // cursor: pointer; 51 | // outline: none; 52 | // display: inline-flex; 53 | // position: relative; 54 | // } 55 | 56 | // @include when(disabled) { 57 | // &, 58 | // &:hover, 59 | // &:focus { 60 | // cursor: not-allowed; 61 | // } 62 | // input[type='checkbox']::after { 63 | // cursor: not-allowed; 64 | // position: absolute; 65 | // top: 0; 66 | // background-color: rgb(245, 247, 250); 67 | // color: #fff; 68 | // width: 18px; 69 | // height: 18px; 70 | // display: inline-block; 71 | // visibility: visible; 72 | // padding-left: 0px; 73 | // text-align: center; 74 | // content: ' '; 75 | // border-radius: 2px; 76 | // box-sizing: border-box; 77 | // border: 1px solid #ddd; 78 | // } 79 | // } 80 | // } 81 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/mixins/function.scss: -------------------------------------------------------------------------------- 1 | @use 'config'; 2 | 3 | // BEM support Func 4 | @function selectorToString($selector) { 5 | $selector: inspect($selector); 6 | $selector: str-slice($selector, 2, -2); 7 | @return $selector; 8 | } 9 | 10 | @function containsModifier($selector) { 11 | $selector: selectorToString($selector); 12 | 13 | @if str-index($selector, config.$modifier-separator) { 14 | @return true; 15 | } @else { 16 | @return false; 17 | } 18 | } 19 | 20 | @function containWhenFlag($selector) { 21 | $selector: selectorToString($selector); 22 | 23 | @if str-index($selector, '.' + config.$state-prefix) { 24 | @return true; 25 | } @else { 26 | @return false; 27 | } 28 | } 29 | 30 | @function containPseudoClass($selector) { 31 | $selector: selectorToString($selector); 32 | 33 | @if str-index($selector, ':') { 34 | @return true; 35 | } @else { 36 | @return false; 37 | } 38 | } 39 | 40 | @function hitAllSpecialNestRule($selector) { 41 | @return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector); 42 | } 43 | 44 | // join var name 45 | // joinVarName(('button', 'text-color')) => '--el-button-text-color' 46 | @function joinVarName($list) { 47 | $name: '--' + config.$namespace; 48 | @each $item in $list { 49 | @if $item != '' { 50 | $name: $name + '-' + $item; 51 | } 52 | } 53 | @return $name; 54 | } 55 | 56 | // getCssVarName('button', 'text-color') => '--el-button-text-color' 57 | @function getCssVarName($args...) { 58 | @return joinVarName($args); 59 | } 60 | 61 | // getCssVar('button', 'text-color') => var(--el-button-text-color) 62 | @function getCssVar($args...) { 63 | @return var(#{joinVarName($args)}); 64 | } 65 | 66 | // getCssVarWithDefault(('button', 'text-color'), red) => var(--el-button-text-color, red) 67 | @function getCssVarWithDefault($args, $default) { 68 | @return var(#{joinVarName($args)}, #{$default}); 69 | } 70 | 71 | // bem('block', 'element', 'modifier') => 'el-block__element--modifier' 72 | @function bem($block, $element: '', $modifier: '') { 73 | $name: config.$namespace + config.$common-separator + $block; 74 | 75 | @if $element != '' { 76 | $name: $name + config.$element-separator + $element; 77 | } 78 | 79 | @if $modifier != '' { 80 | $name: $name + config.$modifier-separator + $modifier; 81 | } 82 | 83 | // @debug $name; 84 | @return $name; 85 | } 86 | -------------------------------------------------------------------------------- /packages/components/alert/src/alert.vue: -------------------------------------------------------------------------------- 1 | 8 | 30 | 87 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/input.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | 4 | // @include b(input) { 5 | // font-size: 14px; 6 | // display: inline-block; 7 | // position: relative; 8 | // width: 100%; 9 | // @include e(inner) { 10 | // background-color: #fff; 11 | // border-radius: 4px; 12 | // border: 1px solid #dcdfe6; 13 | // box-sizing: border-box; 14 | // color: #606266; 15 | // display: inline-block; 16 | // font-size: inherit; 17 | // height: 40px; 18 | // line-height: 40px; 19 | // outline: none; 20 | // padding: 0 15px; 21 | // width: 100%; 22 | // &:hover { 23 | // border: 1px solid #c0c4cc; 24 | // } 25 | 26 | // &:focus { 27 | // outline: none; 28 | // border-color: $color-primary; 29 | // border-width: 1px solid; 30 | // } 31 | // &::placeholder { 32 | // color: #c2c2ca; 33 | // } 34 | // } 35 | // & .#{$namespace}-input__suffix, 36 | // & .#{$namespace}-input__prefix { 37 | // position: absolute; 38 | // right: 10px; 39 | // height: 100%; 40 | // top: 0; 41 | // display: flex; 42 | // align-items: center; 43 | // cursor: pointer; 44 | // color: #c0c4cc; 45 | // font-size: 15px; 46 | // } 47 | // .no-cursor { 48 | // cursor: default; 49 | // } 50 | // .tas-input--prefix.tas-input__inner { 51 | // padding-left: 30px; 52 | // } 53 | // & .#{$namespace}-input__prefix { 54 | // position: absolute; 55 | // width: 20px; 56 | // cursor: default; 57 | // left: 10px; 58 | // } 59 | // @include when(disabled) { 60 | // .#{$namespace}-input__inner { 61 | // cursor: not-allowed; 62 | // background-color: #f5f7fa; 63 | // border-color: #e4e7ed; 64 | // color: #c0c4cc; 65 | // &::placeholder { 66 | // color: #c3c4cc; 67 | // } 68 | // } 69 | // } 70 | // @include m(medium) { 71 | // .#{$namespace}-input__inner { 72 | // height: 36px; 73 | // &::placeholder { 74 | // font-size: 15px; 75 | // } 76 | // } 77 | // } 78 | // @include m(small) { 79 | // .#{$namespace}-input__inner { 80 | // height: 32px; 81 | // &::placeholder { 82 | // font-size: 14px; 83 | // } 84 | // } 85 | // } 86 | // @include m(mini) { 87 | // .#{$namespace}-input__inner { 88 | // height: 28px; 89 | // &::placeholder { 90 | // font-size: 13px; 91 | // } 92 | // } 93 | // } 94 | // } 95 | -------------------------------------------------------------------------------- /packages/components/transfer/src/transfer.vue: -------------------------------------------------------------------------------- 1 | 8 | 42 | 93 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tass-ui", 3 | "version": "0.4.4", 4 | "description": "A high quality UI Toolkit built on Vue.js3+.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "pnpm --filter components test", 8 | "coverage": "pnpm --filter components coverage", 9 | "dev": "pnpm -C examples dev --open", 10 | "build:components": "pnpm --filter components build", 11 | "del-mod": "rimraf node_modules packages/components/node_modules", 12 | "build:theme": "pnpm run -C packages/theme-chalk build", 13 | "prepare": "husky install", 14 | "lint:fix": "eslint . --fix", 15 | "lint:eslint": "eslint .", 16 | "lint:prettier": "prettier --write .", 17 | "lint:ls-lint": "ls-lint", 18 | "lint:staged": "lint-staged", 19 | "lint:css": "stylelint 'packages/theme-chalk/src/**/*.scss' --fix --custom-syntax postcss-scss", 20 | "postinstall": "npx husky install", 21 | "commit": "git add . && git-cz", 22 | "docs:dev": "vitepress dev docs", 23 | "docs:build": "vitepress build docs", 24 | "docs:serve": "vitepress serve docs", 25 | "docs:preview": "vitepress preview docs --port 8080" 26 | }, 27 | "keywords": [], 28 | "author": "", 29 | "license": "MIT", 30 | "config": { 31 | "commitizen": { 32 | "path": "cz-conventional-changelog" 33 | } 34 | }, 35 | "devDependencies": { 36 | "@commitlint/cli": "^17.4.2", 37 | "@commitlint/config-conventional": "^17.4.2", 38 | "@ls-lint/ls-lint": "^1.11.2", 39 | "@types/node": "^18.11.19", 40 | "@types/sass": "^1.43.1", 41 | "@typescript-eslint/eslint-plugin": "^5.49.0", 42 | "@typescript-eslint/parser": "^5.49.0", 43 | "@vitejs/plugin-vue": "^4.0.0", 44 | "@vue/test-utils": "^2.2.10", 45 | "c8": "^7.12.0", 46 | "cz-conventional-changelog": "^3.3.0", 47 | "eslint": "^8.32.0", 48 | "eslint-config-prettier": "^8.6.0", 49 | "eslint-plugin-prettier": "^4.2.1", 50 | "eslint-plugin-vue": "^9.9.0", 51 | "happy-dom": "^8.1.5", 52 | "husky": "^8.0.3", 53 | "lint-staged": "^13.1.0", 54 | "postcss-scss": "^4.0.6", 55 | "prettier": "^2.8.3", 56 | "rimraf": "^4.1.2", 57 | "sass": "^1.55.0", 58 | "stylelint": "^14.16.1", 59 | "stylelint-scss": "^4.3.0", 60 | "typescript": "^4.9.4", 61 | "vite": "^4.0.4", 62 | "vite-plugin-dts": "^1.4.1", 63 | "vite-plugin-vue-setup-extend": "^0.4.0", 64 | "vitepress": "1.0.0-alpha.45", 65 | "vitepress-theme-demoblock": "^2.0.2", 66 | "vitest": "^0.27.3", 67 | "vue": "^3.2.45", 68 | "mitt": "^3.0.0", 69 | "vue-router": "^4.1.6", 70 | "vue3-eventbus": "^2.0.0" 71 | }, 72 | "dependencies": { 73 | "@jridgewell/sourcemap-codec": "^1.4.14", 74 | "@tass-ui/components": "workspace:^1.0.0", 75 | "@tass-ui/constants": "workspace:^1.0.0", 76 | "@tass-ui/eslint-config": "workspace:^1.0.0", 77 | "@tass-ui/theme-chalk": "workspace:^1.0.0", 78 | "@tass-ui/utils": "workspace:^1.0.0" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/components/progress/src/progress.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 86 | -------------------------------------------------------------------------------- /packages/components/switch/src/switch.vue: -------------------------------------------------------------------------------- 1 | 7 | 38 | 43 | 44 | 103 | -------------------------------------------------------------------------------- /packages/components/pagination/src/pagination.vue: -------------------------------------------------------------------------------- 1 | 8 | 28 | 100 | 101 | -------------------------------------------------------------------------------- /docs/components/breadcrumb/index.md: -------------------------------------------------------------------------------- 1 | 8 | 16 | # Breadcrumb 面包屑 17 | 显示当前页面的路径,快速返回之前的任意页面。 18 | ## 基础用法 19 | 在 tass-breadcrumb 中使用 tass-breadcrumb-item 标签表示从首页开始的每一级。 该组件接受一个 String 类型的参数 separator-icon来作为分隔符。 默认值为"chevronright"。 20 | 21 |
22 | 23 | homepage 24 | promotion management 25 | promotion list 26 | promotion list 27 | 28 |
29 |
30 | 展开查看 31 | 32 | ```vue 33 | 41 | ``` 42 |
43 | 44 | ## 图标分隔符 45 | 通过设置 separator-icon 可使用相应的 tassUI中icon的名字作为分隔符 46 |
47 | 48 | homepage 49 | promotion management 50 | promotion list 51 | promotion list 52 | 53 |
54 |
55 | 展开查看 56 | 57 | ```vue 58 | 66 | ``` 67 |
68 | 69 | ## 路由跳转记录 70 | 通过设置replace 如果设置该属性为 true, 导航将不会留下历史记录 71 |
72 | 73 | homepage 74 | promotion management 75 | 76 |
77 |
78 | 展开查看 79 | 80 | ```vue 81 | 87 | ``` 88 |
-------------------------------------------------------------------------------- /docs/components/checkbox/index.md: -------------------------------------------------------------------------------- 1 | 8 | 14 | 31 | 32 | # Checkbox 多选框 33 | 在一组备选项中进行多选。 34 | 35 | ## 基础用法 36 | 单独使用可以表示两种状态之间的切换,写在标签中的内容为 checkbox 按钮后的介绍 37 | 38 |
39 | 40 |
41 | 42 |
43 | 展开查看 44 | 45 | ```vue 46 | 51 | 56 | ``` 57 |
58 | 59 | ## 禁用状态 60 | 多选框不可用状态。 61 | 62 | 设置 disabled 属性即可 63 |
64 | 65 |
66 | 67 |
68 | 展开查看 69 | 70 | ```vue 71 | 75 | 79 | ``` 80 |
81 | 82 | ## 多选框组 83 | 适用于多个勾选框绑定到同一个数组的情景,通过是否勾选来表示这一组选项中选中的项。 84 |
85 | 86 |
87 | 88 |
89 | 展开查看 90 | 91 | ```vue 92 | 98 | 103 | ``` 104 |
105 | 106 | ## 事件回调 107 |
108 | 109 |
110 | 111 |
112 | 展开查看 113 | 114 | ```vue 115 | 118 | 125 | ``` 126 |
127 | -------------------------------------------------------------------------------- /packages/theme-chalk/src/switch.scss: -------------------------------------------------------------------------------- 1 | // @use 'mixins/mixins' as *; 2 | // @use 'common/var' as *; 3 | // $switch-lg: 24px; 4 | // $switch-md: 22px; 5 | // $switch-sm: 20px; 6 | // $switch-xs: 18px; 7 | 8 | // $switch-lg-min-width: 42px; 9 | // $switch-md-min-width: 37px; 10 | // $switch-sm-min-width: 32px; 11 | // $switch-xs-min-width: 27px; 12 | 13 | // @mixin set-size($size, $min-width) { 14 | // & { 15 | // .tas-form-switch { 16 | // height: $size; 17 | // min-width: $min-width; 18 | // span { 19 | // width: calc($size - 4px); 20 | // height: calc($size - 4px); 21 | // transition: all 0.1s linear; 22 | // } 23 | // em { 24 | // margin-left: calc($size - 3px); 25 | // } 26 | // } 27 | // .tas-form-onswitch { 28 | // span { 29 | // left: calc(100% - calc($size - 1px)); 30 | // } 31 | // em { 32 | // margin-right: calc($size - 3px); 33 | // margin-left: 0px; 34 | // } 35 | // } 36 | // } 37 | // } 38 | 39 | // .tas-switch-container { 40 | // &[size='lg'] { 41 | // @include set-size($switch-lg, $switch-lg-min-width); 42 | // } 43 | // &[size='md'] { 44 | // @include set-size($switch-md, $switch-md-min-width); 45 | // } 46 | // &[size='sm'] { 47 | // @include set-size($switch-sm, $switch-sm-min-width); 48 | // } 49 | // &[size='xs'] { 50 | // @include set-size($switch-xs, $switch-xs-min-width); 51 | // } 52 | // } 53 | 54 | // .tas-switch-container .tas-switch-input { 55 | // display: none; 56 | // } 57 | 58 | // .tas-form-switch { 59 | // position: relative; 60 | // height: 22px; 61 | // line-height: 22px; 62 | // min-width: 35px; 63 | // padding: 0 4px; 64 | // border-radius: 20px; 65 | // cursor: pointer; 66 | // background-color: $color-bginfo; 67 | // -webkit-transition: all 0.1s linear; 68 | // transition: all 0.1s linear; 69 | // } 70 | 71 | // .tas-form-switch span { 72 | // position: absolute; 73 | // display: flex; 74 | // align-items: center; 75 | // justify-content: center; 76 | // left: 3px; 77 | // top: 2px; 78 | // width: 18px; 79 | // height: 18px; 80 | // line-height: 18px; 81 | // border-radius: 20px; 82 | // background-color: #fff; 83 | // box-shadow: 0 2px 4px #00230b33; 84 | // -webkit-transition: all 0.1s linear; 85 | // transition: all 0.1s linear; 86 | // } 87 | 88 | // .tas-form-switch em { 89 | // position: relative; 90 | // padding: 0 2px; 91 | // text-align: center !important; 92 | // color: #999 !important; 93 | // font-style: normal !important; 94 | // font-size: 12px; 95 | // width: 25px; 96 | // top: 0; 97 | // } 98 | 99 | // .tas-form-onswitch { 100 | // border-color: black; 101 | // background-color: $color-primary; 102 | // } 103 | 104 | // .tas-form-onswitch span { 105 | // background-color: #fff; 106 | // } 107 | 108 | // .tas-form-onswitch em { 109 | // color: #fff !important; 110 | // } 111 | 112 | // .tas-switch-disabled { 113 | // opacity: 0.6; 114 | // } 115 | 116 | // .tas-switch-disabled, 117 | // .tas-switch-disabled * { 118 | // cursor: not-allowed !important; 119 | // } 120 | --------------------------------------------------------------------------------