u
This commit is contained in:
1 parent
8bd73b3786
commit
554fe2945f
15 files changed
+531
-159
No files matched your search
@@ -1,29 +1,198 @@
|
||||
@import '../_styles/theme/index.scss';
|
||||
@use 'sass:color';
|
||||
@use '../_styles/theme/index' as *;
|
||||
|
||||
// 按钮基础样式示例
|
||||
.#{$prefix}-btn {
|
||||
padding: 6px 16px;
|
||||
border-radius: 4px;
|
||||
$btn-prefix: #{$prefix}-btn;
|
||||
$btn-hover-bgcolor: #f4f5f5;
|
||||
$btn-active-bgcolor: #eceded;
|
||||
|
||||
/* ====== 通用颜色交互函数 ====== */
|
||||
@function color-hover($color, $amount: 8%) {
|
||||
$l: color.lightness($color);
|
||||
@if $l > 50% {
|
||||
@return color.adjust($color, $lightness: -$amount);
|
||||
} @else {
|
||||
@return color.adjust($color, $lightness: $amount);
|
||||
}
|
||||
}
|
||||
|
||||
@function color-active($color, $amount: 12%) {
|
||||
$l: color.lightness($color);
|
||||
@if $l > 50% {
|
||||
@return color.adjust($color, $lightness: -$amount);
|
||||
} @else {
|
||||
@return color.adjust($color, $lightness: $amount);
|
||||
}
|
||||
}
|
||||
|
||||
.#{$btn-prefix} {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
border-radius: 3px;
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-weight: 600;
|
||||
|
||||
&-default {
|
||||
background: #fff;
|
||||
border-color: $border-color;
|
||||
color: $text-secondary-color;
|
||||
&-block {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-primary {
|
||||
background: $primary-color;
|
||||
color: #fff;
|
||||
&-icon-left {
|
||||
margin-right: 4px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
&-icon-right {
|
||||
margin-left: 4px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $primary-hover-color;
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* ===== Solid 按钮 ===== */
|
||||
&-solid {
|
||||
@each $status,
|
||||
$color
|
||||
in (
|
||||
normal: #d9d9d9,
|
||||
primary: $primary-color,
|
||||
danger: $danger-color,
|
||||
warning: $warning-color,
|
||||
success: $success-color
|
||||
)
|
||||
{
|
||||
&.#{$btn-prefix}-status-#{$status} {
|
||||
@if $status == normal {
|
||||
background: #f4f5f5;
|
||||
color: #000;
|
||||
&:hover:enabled {
|
||||
background: #eceded;
|
||||
}
|
||||
&:active:enabled {
|
||||
background: #e4e4e5;
|
||||
}
|
||||
} @else {
|
||||
background: $color;
|
||||
color: #fff;
|
||||
border: 1px solid transparent;
|
||||
&:hover:enabled {
|
||||
background: color-hover($color, 5%);
|
||||
}
|
||||
&:active:enabled {
|
||||
background: color-active($color, -5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-danger {
|
||||
background: $danger-color;
|
||||
color: #fff;
|
||||
/* ===== Outline 按钮 ===== */
|
||||
&-outline {
|
||||
font-weight: 500;
|
||||
background: transparent;
|
||||
|
||||
@each $status,
|
||||
$color
|
||||
in (
|
||||
normal: $primary-color,
|
||||
primary: $primary-color,
|
||||
danger: $danger-color,
|
||||
warning: $warning-color,
|
||||
success: $success-color
|
||||
)
|
||||
{
|
||||
&.#{$btn-prefix}-status-#{$status} {
|
||||
color: if($status == normal, #000, $color);
|
||||
border-color: if($status == normal, #d9d9d9, $color);
|
||||
&:hover:enabled {
|
||||
background-color: $btn-hover-bgcolor;
|
||||
}
|
||||
&:active:enabled {
|
||||
background-color: $btn-active-bgcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== Dashed 按钮 ===== */
|
||||
&-dashed {
|
||||
font-weight: 500;
|
||||
background: transparent;
|
||||
border: 1px dashed currentColor;
|
||||
|
||||
@each $status,
|
||||
$color
|
||||
in (
|
||||
normal: #000,
|
||||
primary: $primary-color,
|
||||
danger: $danger-color,
|
||||
warning: $warning-color,
|
||||
success: $success-color
|
||||
)
|
||||
{
|
||||
&.#{$btn-prefix}-status-#{$status} {
|
||||
color: $color;
|
||||
border-color: if($status == normal, #d9d9d9, $color);
|
||||
&:hover:enabled {
|
||||
background-color: $btn-hover-bgcolor;
|
||||
}
|
||||
&:active:enabled {
|
||||
background-color: $btn-active-bgcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== Text 按钮 ===== */
|
||||
&-text {
|
||||
font-weight: 500;
|
||||
background: transparent;
|
||||
border: none;
|
||||
|
||||
@each $status,
|
||||
$color
|
||||
in (
|
||||
normal: #000,
|
||||
primary: $primary-color,
|
||||
danger: $danger-color,
|
||||
warning: $warning-color,
|
||||
success: $success-color
|
||||
)
|
||||
{
|
||||
&.#{$btn-prefix}-status-#{$status} {
|
||||
color: $color;
|
||||
&:hover:enabled {
|
||||
background-color: $btn-hover-bgcolor;
|
||||
}
|
||||
&:active:enabled {
|
||||
background-color: $btn-active-bgcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== 尺寸 ===== */
|
||||
&-small {
|
||||
height: 24px;
|
||||
padding: 0 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
&-medium {
|
||||
height: 28px;
|
||||
padding: 0 14px;
|
||||
font-size: 14px;
|
||||
}
|
||||
&-large {
|
||||
height: 32px;
|
||||
padding: 0 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,70 @@
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { getPrefixCls } from '../_utils/getPrefixCls'
|
||||
import Icon from '../icon'
|
||||
import './index.scss'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AButton',
|
||||
name: 'Button',
|
||||
props: {
|
||||
type: { type: String as () => 'primary' | 'danger' | 'default', default: 'default' },
|
||||
type: {
|
||||
type: String as () => 'solid' | 'outline' | 'text' | 'dashed',
|
||||
default: 'solid',
|
||||
},
|
||||
status: {
|
||||
type: String as () => 'primary' | 'danger' | 'warning' | 'success' | 'normal',
|
||||
default: 'normal',
|
||||
},
|
||||
disabled: { type: Boolean, default: false },
|
||||
loading: { type: Boolean, default: false },
|
||||
icon: { type: String, default: '' },
|
||||
iconPosition: { type: String as () => 'left' | 'right', default: 'left' },
|
||||
size: { type: String as () => 'small' | 'medium' | 'large', default: 'medium' },
|
||||
block: { type: Boolean, default: false },
|
||||
},
|
||||
setup(props, { slots }) {
|
||||
const prefixCls = getPrefixCls('btn')
|
||||
const cls = computed(() => [prefixCls, `${prefixCls}-${props.type}`])
|
||||
return () => <button class={cls.value}>{slots.default?.()}</button>
|
||||
|
||||
const cls = computed(() => [
|
||||
prefixCls,
|
||||
`${prefixCls}-${props.type}`,
|
||||
`${prefixCls}-status-${props.status}`,
|
||||
`${prefixCls}-${props.size}`,
|
||||
props.block && `${prefixCls}-block`,
|
||||
])
|
||||
|
||||
const iconSize = computed(() => {
|
||||
const map = { small: 14, medium: 16, large: 16 }
|
||||
return map[props.size]
|
||||
})
|
||||
|
||||
return () => (
|
||||
<button class={cls.value} disabled={props.disabled || props.loading}>
|
||||
{/* 左侧图标 */}
|
||||
{props.iconPosition === 'left' && (props.loading || props.icon) && (
|
||||
<Icon
|
||||
icon={props.loading ? 'mingcute:loading-line' : props.icon}
|
||||
class={`${prefixCls}-icon-left`}
|
||||
spin={props.loading}
|
||||
width={iconSize.value}
|
||||
height={iconSize.value}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 插槽文本 */}
|
||||
<span>
|
||||
{slots.default?.()}
|
||||
</span>
|
||||
|
||||
{/* 右侧图标 */}
|
||||
{props.iconPosition === 'right' && props.icon && (
|
||||
<Icon
|
||||
icon={props.icon}
|
||||
class={`${prefixCls}-icon-right`}
|
||||
width={iconSize.value}
|
||||
height={iconSize.value}
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
},
|
||||
})
|
||||
Reference in new issue
Block a user