diff --git a/apps/playground/src/pages/button/basic.vue b/apps/playground/src/pages/button/basic.vue index 9a6d2daba..8be3ef789 100644 --- a/apps/playground/src/pages/button/basic.vue +++ b/apps/playground/src/pages/button/basic.vue @@ -1,9 +1,56 @@ diff --git a/packages-config/tailwind-config/tailwind.css b/packages-config/tailwind-config/tailwind.css index 133165919..e8bc5e254 100644 --- a/packages-config/tailwind-config/tailwind.css +++ b/packages-config/tailwind-config/tailwind.css @@ -1,5 +1,4 @@ @import 'tailwindcss' source(none); -@plugin '@tailwindcss/typography'; @utility text-tint-* { color: color-mix(in srgb, --value(--color-*, [*]), white calc(--modifier(integer) * 1%)); diff --git a/packages/ui/package.json b/packages/ui/package.json index 4a9bfd4e3..50764e254 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -53,7 +53,7 @@ "license": "MIT", "main": "./dist/lib.cjs", "module": "./dist/lib.mjs", - "types": "./dist/types/index.d.ts", + "types": "./dist/index.d.ts", "files": [ "dist", "src/style", @@ -72,6 +72,7 @@ "@floating-ui/dom": "^1.6.13", "@floating-ui/vue": "^1.1.6", "lodash-es": "^4.17.21", + "@ctrl/tinycolor": "^4.0.0", "resize-observer-polyfill": "^1.5.1" }, "devDependencies": { diff --git a/packages/ui/src/components/button/Button.vue b/packages/ui/src/components/button/Button.vue index 6b800f8c9..68c304697 100644 --- a/packages/ui/src/components/button/Button.vue +++ b/packages/ui/src/components/button/Button.vue @@ -1,5 +1,7 @@ @@ -7,20 +9,42 @@ diff --git a/packages/ui/src/components/button/index.ts b/packages/ui/src/components/button/index.ts index eeb3f80cb..c5ade40b1 100644 --- a/packages/ui/src/components/button/index.ts +++ b/packages/ui/src/components/button/index.ts @@ -2,7 +2,6 @@ import { App, Plugin } from 'vue' import Button from './Button.vue' import './style/index.css' -// 导出组件 export { default as Button } from './Button.vue' export * from './meta' diff --git a/packages/ui/src/components/button/meta.ts b/packages/ui/src/components/button/meta.ts index 91a7101f6..364dc3367 100644 --- a/packages/ui/src/components/button/meta.ts +++ b/packages/ui/src/components/button/meta.ts @@ -6,9 +6,61 @@ export const buttonProps = { * Specifies the visual style variant of the button * @default 'primary' */ - type: { - type: String as PropType<'primary' | 'secondary'>, - default: 'primary', + variant: { + type: String as PropType<'solid' | 'outlined' | 'text' | 'link' | 'dashed' | 'filled'>, + default: 'solid', + }, + + /** + * Specifies the size of the button + * @default 'md' + */ + size: { + type: String as PropType<'sm' | 'md' | 'lg'>, + default: 'md', + }, + + /** + * Specifies the shape of the button + * @default 'default' + */ + shape: { + type: String as PropType<'default' | 'circle' | 'round'>, + default: 'default', + }, + + /** + * Specifies the loading state of the button + * @default false + */ + loading: { + type: Boolean, + default: false, + }, + + /** + * Specifies the disabled state of the button + * @default false + */ + disabled: { + type: Boolean, + default: false, + }, + + /** + * Specifies the danger state of the button + * @default false + */ + danger: { + type: Boolean, + default: false, + }, + + /** + * Specifies the color of the button + */ + color: { + type: String, }, } as const @@ -31,6 +83,14 @@ export const buttonSlots = { * Main content slot for the button text or custom content */ default: (_: any) => null as any, + /** + * Slot for the button icon + */ + icon: (_: any) => null as any, + /** + * Slot for the button loading indicator + */ + loading: (_: any) => null as any, } as const export type ButtonSlots = typeof buttonSlots diff --git a/packages/ui/src/components/button/style/index.css b/packages/ui/src/components/button/style/index.css index c18500629..6366bb47a 100644 --- a/packages/ui/src/components/button/style/index.css +++ b/packages/ui/src/components/button/style/index.css @@ -1,5 +1,50 @@ @reference '../../../style/tailwind.css'; .ant-btn { - @apply text-primary-content; + @apply relative; + @apply inline-flex shrink-0 cursor-pointer items-center justify-center gap-1 whitespace-nowrap; + @apply border-1 text-sm; + @apply box-border rounded-md px-4 transition-all duration-200 select-none; + &:where(.ant-btn-disabled) { + @apply cursor-not-allowed; + } + &:where(.ant-btn-loading) { + @apply cursor-default opacity-50; + } + + &:where(.ant-btn-solid) { + @apply border-none bg-[var(--bg-color)] text-[var(--bg-color-content)]; + @apply not-disabled:hover:bg-[var(--bg-color-hover)] not-disabled:active:bg-[var(--bg-color-active)]; + } + &:where(.ant-btn-outlined), + &:where(.ant-btn-dashed) { + @apply border-[var(--border-color-tint-30)] bg-transparent text-[var(--text-color)]; + @apply not-disabled:hover:border-[var(--border-color-hover)] not-disabled:hover:text-[var(--text-color-hover)] not-disabled:active:border-[var(--border-color-active)] not-disabled:active:text-[var(--text-color-active)]; + @apply disabled:border-[var(--border-color-tint-80)]; + } + &:where(.ant-btn-text) { + @apply border-none bg-transparent text-[var(--text-color)]; + @apply not-disabled:hover:bg-[var(--bg-color-tint-90)] not-disabled:hover:text-[var(--text-color-hover)]; + } + + &:where(.ant-btn-link) { + @apply border-none bg-transparent text-[var(--text-color)] not-disabled:hover:text-[var(--text-color-hover)]; + } + &:where(.ant-btn-dashed) { + @apply border-dashed; + } + &:where(.ant-btn-filled) { + @apply border-none bg-[var(--bg-color-tint-90)] text-[var(--text-color)] not-disabled:hover:text-[var(--text-color-hover)]; + @apply not-disabled:hover:bg-[var(--bg-color-tint-80)] not-disabled:active:bg-[var(--bg-color-tint-80)]; + } + + &:where(.ant-btn-sm) { + @apply h-6 text-xs; + } + &:where(.ant-btn-md) { + @apply h-8 text-sm; + } + &:where(.ant-btn-lg) { + @apply h-10 text-base; + } } diff --git a/packages/ui/src/utils/colorAlgorithm.ts b/packages/ui/src/utils/colorAlgorithm.ts new file mode 100644 index 000000000..4c19db8a9 --- /dev/null +++ b/packages/ui/src/utils/colorAlgorithm.ts @@ -0,0 +1,50 @@ +import { TinyColor } from '@ctrl/tinycolor' + +export const getAlphaColor = (baseColor: string, alpha: number) => + new TinyColor(baseColor).setAlpha(alpha).toRgbString() + +export const getSolidColor = (baseColor: string, brightness: number) => { + const instance = new TinyColor(baseColor) + return instance.darken(brightness).toHexString() +} + +export const getTintColor = (baseColor: string, tintNumber: number) => { + return new TinyColor(baseColor).tint(tintNumber).toString() +} + +export const getShadeColor = (baseColor: string, shadeNumber: number) => { + return new TinyColor(baseColor).shade(shadeNumber).toString() +} + +export const getCssVarColor = (baseColor: string) => { + return { + '--bg-color': baseColor, + '--bg-color-hover': getTintColor(baseColor, 10), + '--bg-color-active': getTintColor(baseColor, 20), + '--bg-color-content': '#ffffff', + '--border-color': baseColor, + '--border-color-hover': getTintColor(baseColor, 10), + '--border-color-active': getTintColor(baseColor, 20), + '--border-color-tint-10': getTintColor(baseColor, 10), + '--border-color-tint-20': getTintColor(baseColor, 20), + '--border-color-tint-30': getTintColor(baseColor, 30), + '--border-color-tint-40': getTintColor(baseColor, 40), + '--border-color-tint-50': getTintColor(baseColor, 50), + '--border-color-tint-60': getTintColor(baseColor, 60), + '--border-color-tint-70': getTintColor(baseColor, 70), + '--border-color-tint-80': getTintColor(baseColor, 80), + '--border-color-tint-90': getTintColor(baseColor, 90), + '--bg-color-tint-10': getTintColor(baseColor, 10), + '--bg-color-tint-20': getTintColor(baseColor, 20), + '--bg-color-tint-30': getTintColor(baseColor, 30), + '--bg-color-tint-40': getTintColor(baseColor, 40), + '--bg-color-tint-50': getTintColor(baseColor, 50), + '--bg-color-tint-60': getTintColor(baseColor, 60), + '--bg-color-tint-70': getTintColor(baseColor, 70), + '--bg-color-tint-80': getTintColor(baseColor, 80), + '--bg-color-tint-90': getTintColor(baseColor, 90), + '--text-color': baseColor, + '--text-color-hover': getTintColor(baseColor, 10), + '--text-color-active': getTintColor(baseColor, 20), + } +}