diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..191ae4cc --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +*.d.ts \ No newline at end of file diff --git a/package.json b/package.json index bf44a22c..99ba82fb 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "@vitejs/plugin-vue-jsx": "^1.3.10", "@vue/compiler-sfc": "^3.2.37", "@vue/server-renderer": "^3.2.37", + "vite-plugin-dts": "^1.5.0", "less": "^4.1.3", "rimraf": "^3.0.2", "rollup": "^2.75.5", diff --git a/package/component/package.json b/package/component/package.json index 538b4f5b..5a36957f 100644 --- a/package/component/package.json +++ b/package/component/package.json @@ -11,7 +11,7 @@ "types": "types/index.d.ts", "style": "lib/index.css", "type": "module", - "keywords": [ + "keywords": [ "vue", "vue-component", "component-library", @@ -26,9 +26,9 @@ "./es/": "./es/" }, "scripts": { - "build": "npm run build:all && npm run build:es && npm run build:umd && npm run build:types", + "build": "npm run build:all && npm run build:es && npm run build:umd", "build:es": "vite build --emptyOutDir --config ./script/build.es.ts", - "build:all": "vite build --emptyOutDir --config ./script/build.all.ts", + "build:all": "rimraf types && vite build --emptyOutDir --config ./script/build.all.ts", "build:umd": "vite build --emptyOutDir --config ./script/build.umd.ts", "build:types": "rimraf types && tsc -d" }, @@ -41,7 +41,8 @@ "@umijs/ssr-darkreader": "^4.9.45", "dayjs": "^1.11.0", "evtd": "^0.2.3", - "vue-i18n": "^9.1.10" + "vue-i18n": "^9.1.10", + "@ctrl/tinycolor": "^3.4.1" }, "files": [ "lib", diff --git a/package/component/script/build.all.ts b/package/component/script/build.all.ts index 2e545d24..c3090767 100644 --- a/package/component/script/build.all.ts +++ b/package/component/script/build.all.ts @@ -1,7 +1,8 @@ import { UserConfigExport } from "vite"; import vue from "@vitejs/plugin-vue"; import vueJsx from "@vitejs/plugin-vue-jsx"; -import { resolve } from "path"; +import dts from "vite-plugin-dts"; +import path, { resolve } from "path"; export default (): UserConfigExport => { return { @@ -14,7 +15,26 @@ export default (): UserConfigExport => { }, ], }, - plugins: [vue(), vueJsx()], + plugins: [ + vue(), + vueJsx(), + dts({ + outputDir: ["types"], + insertTypesEntry: true, + cleanVueFileName: true, + copyDtsFiles: true, + include: ["src"], + beforeWriteFile: (filePath: string, content: string) => { + return { + filePath: filePath.replace( + `${path.sep}package${path.sep}component${path.sep}src`, + "" + ), + content: content, + }; + }, + }), + ], build: { cssCodeSplit: false, outDir: "lib", diff --git a/package/component/src/component/space/index.vue b/package/component/src/component/space/index.vue index 48d64372..d7c35883 100644 --- a/package/component/src/component/space/index.vue +++ b/package/component/src/component/space/index.vue @@ -13,7 +13,7 @@ import { VNodeNormalizedChildren, } from "vue"; -export type SpaceSize = "lg" | "md" | "sm" | "xs" | number | string; +type SpaceSize = "lg" | "md" | "sm" | "xs" | number | string; export default defineComponent({ name: "LaySpace", diff --git a/package/component/src/component/tag/index.less b/package/component/src/component/tag/index.less index 2d13613a..ac372024 100644 --- a/package/component/src/component/tag/index.less +++ b/package/component/src/component/tag/index.less @@ -1,14 +1,12 @@ @tagColors: { - default: #EEE; - red: #ff5722; - orange: #ffb800; - green: #009688; - cyan: #2f4056; - blue: #1e9fff; - black: #000000; - gray: #808080; + primary: #009688; + normal: #1e9fff; + warm: #ffb800; + danger: #ff5722; } + @tagSizes: lg, md, sm, xs; + @tag-size-default: 28px; @tag-size-default-font-size: 14px; @tag-size-lg: @tag-size-default + 4px; @@ -22,6 +20,10 @@ @tag-border-width: 1px; .layui-tag { + --layui-tag-bg-color: #FFF; + --layui-tag-border-color: var(--global-neutral-color-5); + --layui-tag-hover-color: #FFF; + --layui-tag-text-color: currentColor; display: inline-flex; align-items: baseline; vertical-align: middle; @@ -31,7 +33,8 @@ padding: 0 8px; font-size: @tag-size-md-font-size; font-weight: 500; - color: currentColor; + color: var(--layui-tag-text-color); + background-color: var(--layui-tag-bg-color); border-width: @tag-border-width; border-style: solid; border-color: transparent; @@ -42,7 +45,7 @@ } &-bordered { - border-color: var(--global-neutral-color-5); + border-color: var(--layui-tag-border-color); } &-disabled { @@ -78,45 +81,6 @@ text-overflow: ellipsis } - &-size-lg { - height: @tag-size-lg; - font-size: @tag-size-lg-font-size; - line-height: @tag-size-lg; - - .layui-icon { - font-size: @tag-size-lg-font-size; - } - } - - &-size-md { - height: @tag-size-md; - font-size: @tag-size-md-font-size; - line-height: @tag-size-md; - - .layui-icon { - font-size: @tag-size-md-font-size; - } - } - - &-size-sm { - height: @tag-size-sm; - font-size: @tag-size-sm-font-size; - line-height: @tag-size-sm; - - .layui-icon { - font-size: @tag-size-sm-font-size; - } - } - - &-size-xs { - height: @tag-size-xs; - font-size: @tag-size-xs-font-size; - line-height: @tag-size-xs; - - .layui-icon { - font-size: @tag-size-xs-font-size; - } - } & &-close-icon { margin-left: 4px; @@ -131,46 +95,52 @@ } } + each(@tagSizes, { + &-size-@{value} { + height: ~'@{tag-size-@{value}}'; + font-size: ~'@{tag-size-@{value}-font-size}'; + line-height: ~'@{tag-size-@{value}}'; + } + + .layui-icon { + font-size: ~'@{tag-size-@{value}-font-size}'; + } + + }) + each(@tagColors, { - &-default { - &-color-@{key} { - color: #FFF; - background-color: @value; - border-color: transparent; - } - - &-bordered-@{key} { - border-color: saturate(@value, 10%); - } - - &-checked-color-@{key} { - background-color: darken(@value, 10%); - } + &-@{key} { + --layui-tag-bg-color: @value; + --layui-tag-border-color: transparent; + --layui-tag-hover-color: @value; + --layui-tag-text-color: contrast(@value, #FFF,#000000,60%); + &-bordered { + --layui-tag-border-color: @value; } + } - &-light { - &-color-@{key} { - color: @value; - background-color: fadeout(saturate(lighten(@value, 13%),5%),85%); - border-color: transparent; - } + &-@{key}.layui-tag-variant-light { + --layui-tag-bg-color: tint(@value, 90%); + --layui-tag-border-color: transparent; + --layui-tag-hover-color: tint(@value, 90%); + --layui-tag-text-color: @value; - &-bordered-@{key} { - border-color: fadeout(saturate(lighten(@value, 13%), 5%), 50%); - } + &-bordered { + --layui-tag-border-color: tint(@value, 50%); } + } - &-plain { - &-color-@{key} { - color: @value; - background-color: transparent; - border-color: @value; - } + &-@{key}.layui-tag-variant-plain { + --layui-tag-bg-color: transparent; + --layui-tag-hover-color: transparent; + --layui-tag-text-color: @value; + --layui-tag-border-color: transparent; - &-bordered-@{key} { - border-color: @value; - } + &-bordered { + --layui-tag-border-color: @value; } - }) + } + + }) } \ No newline at end of file diff --git a/package/component/src/component/tag/index.vue b/package/component/src/component/tag/index.vue index cfd04f09..71864fe6 100644 --- a/package/component/src/component/tag/index.vue +++ b/package/component/src/component/tag/index.vue @@ -7,34 +7,30 @@ export default { import "./index.less"; import { LayIcon } from "@layui/icons-vue"; import { computed, ref } from "vue"; -import { TAG_COLORS, TagColor } from "./interface"; +import { TinyColor } from "@ctrl/tinycolor"; +import { TAG_COLORS, tagType } from "./interface"; export interface LayTagProps { - color?: TagColor | string; + type?: tagType; + color?: string; closable?: boolean; size?: string; bordered?: boolean; disabled?: boolean; shape?: "square" | "round"; maxWidth?: string; - variant?: "default" | "light" | "plain"; + variant?: "dark" | "light" | "plain"; } const props = withDefaults(defineProps(), { - color: "#EEE", size: "md", shape: "square", - variant: "default", + variant: "dark", + bordered: true, }); const emit = defineEmits(["close", "check", "update:checked"]); -const isBuiltInColor = computed( - () => props.color && TAG_COLORS.includes(props.color as any) -); -const isCustomColor = computed( - () => props.color && !TAG_COLORS.includes(props.color as any) -); const visible = ref(true); const handleClose = (e: MouseEvent) => { @@ -48,9 +44,10 @@ const classTag = computed(() => [ `layui-tag-size-${props.size}`, `layui-tag-shap-${props.shape}`, { - [`layui-tag-${props.variant}-color-${props.color}`]: isBuiltInColor.value, - [`layui-tag-${props.variant}-bordered-${props.color}`]: - isBuiltInColor.value && props.bordered, + [`layui-tag-variant-${props.variant}`]: props.variant, + [`layui-tag-variant-${props.variant}-bordered`]: props.bordered, + [`layui-tag-${props.type}-bordered`]: props.bordered, + [`layui-tag-${props.type}`]: props.type, "layui-tag-bordered": props.bordered, "layui-tag-disabled": props.disabled, "layui-tag-ellipsis": props.maxWidth, @@ -58,11 +55,51 @@ const classTag = computed(() => [ ]); const styleTag = computed(() => [ - isCustomColor.value ? { backgroundColor: props.color } : {}, { "max-width": props.maxWidth ?? "unset", + ...useTagCustomStyle(props).value, }, ]); + +function useTagCustomStyle(props: LayTagProps) { + return computed(() => { + let styles: Record = {}; + + const tagColor = props.color; + + if (tagColor) { + const color = new TinyColor(tagColor); + if (props.variant === "dark") { + const isDark = color.getBrightness() < 190; + const textColor = isDark ? "#FFF" : "#000000"; + styles = { + "--layui-tag-bg-color": tagColor, + "--layui-tag-border-color": props.bordered ? tagColor : "transparent", + "--layui-tag-hover-color": tagColor, + "--layui-tag-text-color": textColor, + }; + } else if (props.variant === "light") { + styles = { + "--layui-tag-bg-color": color.tint(90).toString(), + "--layui-tag-border-color": props.bordered + ? color.tint(50).toString() + : "transparent", + "--layui-tag-hover-color": color.tint(90).toString(), + "--layui-tag-text-color": tagColor, + }; + } else if (props.variant === "plain") { + styles = { + "--layui-tag-bg-color": "transparent", + "--layui-tag-border-color": props.bordered ? tagColor : "transparent", + "--layui-tag-hover-color": "transparent", + "--layui-tag-text-color": tagColor, + }; + } + } + + return styles; + }); +}