diff --git a/code/base-project/base-vue/packages/ao-design/src/button/demo.vue b/code/base-project/base-vue/packages/ao-design/src/button/demo.vue new file mode 100644 index 00000000..024f2639 --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/button/demo.vue @@ -0,0 +1,121 @@ + diff --git a/code/base-project/base-vue/packages/ao-design/src/button/index.scss b/code/base-project/base-vue/packages/ao-design/src/button/index.scss index 4ba4df9c..ce1d8cbd 100644 --- a/code/base-project/base-vue/packages/ao-design/src/button/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/button/index.scss @@ -5,22 +5,24 @@ $btn-prefix: #{$prefix}-btn; $btn-hover-bgcolor: #f4f5f5; $btn-active-bgcolor: #eceded; -/* ====== 通用颜色交互函数 ====== */ +/* ====== 通用颜色交互函数(新版写法) ====== */ @function color-hover($color, $amount: 8%) { - $l: color.lightness($color); + $l: color.channel($color, 'lightness', $space: hsl); @if $l > 50% { - @return color.adjust($color, $lightness: -$amount); + // 亮色:向暗靠近 + @return color.scale($color, $lightness: -$amount); } @else { - @return color.adjust($color, $lightness: $amount); + // 暗色:向亮靠近 + @return color.scale($color, $lightness: $amount); } } @function color-active($color, $amount: 12%) { - $l: color.lightness($color); + $l: color.channel($color, 'lightness', $space: hsl); @if $l > 50% { - @return color.adjust($color, $lightness: -$amount); + @return color.scale($color, $lightness: -$amount); } @else { - @return color.adjust($color, $lightness: $amount); + @return color.scale($color, $lightness: $amount); } } @@ -31,12 +33,11 @@ $btn-active-bgcolor: #eceded; gap: 4px; box-sizing: border-box; user-select: none; - border-radius: 3px; + border-radius: 2px; border: 1px solid transparent; cursor: pointer; transition: all 0.2s ease; - font-weight: 600; - + font-weight: 500; &-block { width: 100%; } @@ -96,7 +97,6 @@ $btn-active-bgcolor: #eceded; /* ===== Outline 按钮 ===== */ &-outline { - font-weight: 500; background: transparent; @each $status, @@ -124,7 +124,6 @@ $btn-active-bgcolor: #eceded; /* ===== Dashed 按钮 ===== */ &-dashed { - font-weight: 500; background: transparent; border: 1px dashed currentColor; @@ -153,7 +152,6 @@ $btn-active-bgcolor: #eceded; /* ===== Text 按钮 ===== */ &-text { - font-weight: 500; background: transparent; border: none; @@ -185,14 +183,16 @@ $btn-active-bgcolor: #eceded; padding: 0 12px; font-size: 12px; } + &-medium { height: 28px; padding: 0 14px; - font-size: 14px; + font-size: 12px; } + &-large { height: 32px; padding: 0 16px; - font-size: 14px; + font-size: 13px; } } diff --git a/code/base-project/base-vue/packages/ao-design/src/input/index.scss b/code/base-project/base-vue/packages/ao-design/src/input/index.scss index 270049f7..e13e4692 100644 --- a/code/base-project/base-vue/packages/ao-design/src/input/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/input/index.scss @@ -1,7 +1,71 @@ @use '../_styles/theme/index' as *; +@use 'sass:color'; $input-prefix: #{$prefix}-input; -.#{$input-prefix} { - border-color: #d9d9d9; +.#{$input-prefix}-wrapper { + display: flex; + align-items: center; + width: 100%; + box-sizing: border-box; + border: 1px solid #d9d9d9; + border-radius: 2px; + background-color: #fff; + color: #000000d9; + transition: + border-color 0.2s, + box-shadow 0.2s; + + &:hover:not(&-disabled) { + border-color: $primary-color; + } + + &:focus-within:not(&-disabled) { + border-color: $primary-color; + box-shadow: 0 0 0 1px color.change($primary-color, $alpha: 0.1); + } + + &-disabled { + color: #00000040; + background-color: #f5f5f5; + border-color: #d9d9d9; + cursor: not-allowed; + } + + /* 尺寸变体 */ + &-small { + height: 24px; + font-size: 12px; + } + &-medium { + height: 28px; + font-size: 14px; + } + &-large { + height: 32px; + font-size: 16px; + } } + +.#{$input-prefix}-inner { + flex: 1; + border: none; + outline: none; + background: transparent; + width: 100%; + height: 100%; + font-family: inherit; + + &::placeholder { + color: #00000040; + } +} + +.#{$input-prefix}-icon { + display: flex; + align-items: center; + justify-content: center; + color: #00000040; + margin: 0 4px; +} + \ No newline at end of file diff --git a/code/base-project/base-vue/packages/ao-design/src/input/index.tsx b/code/base-project/base-vue/packages/ao-design/src/input/index.tsx index b38d2259..72b618ab 100644 --- a/code/base-project/base-vue/packages/ao-design/src/input/index.tsx +++ b/code/base-project/base-vue/packages/ao-design/src/input/index.tsx @@ -1,23 +1,60 @@ -import { computed, defineComponent, ref } from 'vue' +import type { PropType } from 'vue' +import { computed, defineComponent, h, ref } from 'vue' import { getPrefixCls } from '../_utils/getPrefixCls' +import Icon from '../icon' export default defineComponent({ name: 'AInput', - setup() { + props: { + size: { + type: String as PropType<'small' | 'medium' | 'large'>, + default: 'medium', + }, + placeholder: String, + disabled: Boolean, + prefixIcon: String, + suffixIcon: String, + }, + setup(props, { slots }) { const inputRef = ref(null) - - // 使用统一前缀 const prefixCls = getPrefixCls('input') - const cls = computed(() => [prefixCls]) + + const wrapperCls = computed(() => [ + `${prefixCls}-wrapper`, + `${prefixCls}-wrapper-${props.size}`, + { [`${prefixCls}-wrapper-disabled`]: props.disabled }, + ]) + + const iconSizeMap: Record = { small: 12, medium: 14, large: 16 } + + const renderIcon = (slot: any, iconProp?: string) => { + if (slot) + return typeof slot === 'function' ? slot() : slot + if (iconProp) + return h(Icon, { icon: iconProp, width: iconSizeMap[props.size], height: iconSizeMap[props.size] }) + return null + } return () => ( -
+
+ {(slots.prefix || props.prefixIcon) && ( + + {renderIcon(slots.prefix, props.prefixIcon)} + + )} + + + {(slots.suffix || props.suffixIcon) && ( + + {renderIcon(slots.suffix, props.suffixIcon)} + + )}
) }, diff --git a/code/base-project/base-vue/src/App.vue b/code/base-project/base-vue/src/App.vue index b006b0a9..71ebab53 100644 --- a/code/base-project/base-vue/src/App.vue +++ b/code/base-project/base-vue/src/App.vue @@ -2,114 +2,30 @@