chore: establish V1.1 recovery baseline
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Button 按钮(规范 §22 / Token §2 主色 + 功能色)
|
||||
*
|
||||
* 变体 variant:primary(主红)/ secondary(白底红边)/ ghost(无背景)/ danger / text
|
||||
* 尺寸 size:sm / md(默认)/ lg
|
||||
* 状态:disabled / loading
|
||||
* 用法:
|
||||
* <ui-button variant="primary" size="md" bindtap="onSubmit">提交</ui-button>
|
||||
* <ui-button variant="danger" block loading>删除</ui-button>
|
||||
*/
|
||||
Component({
|
||||
options: { addGlobalClass: true, multipleSlots: true },
|
||||
externalClasses: ['custom-class'],
|
||||
properties: {
|
||||
variant: { type: String, value: 'primary' }, // primary|secondary|ghost|danger|text
|
||||
size: { type: String, value: 'md' }, // sm|md|lg
|
||||
block: { type: Boolean, value: false }, // 是否撑满父容器
|
||||
disabled: { type: Boolean, value: false },
|
||||
loading: { type: Boolean, value: false },
|
||||
openType: { type: String, value: '' }, // 透传原生 open-type(getPhoneNumber 等)
|
||||
hoverClass: { type: String, value: 'ui-btn--hover' },
|
||||
},
|
||||
methods: {
|
||||
onTap(e) {
|
||||
if (this.data.disabled || this.data.loading) return;
|
||||
this.triggerEvent('tap', e.detail || {});
|
||||
},
|
||||
onGetPhoneNumber(e) {
|
||||
this.triggerEvent('getphonenumber', e.detail || {});
|
||||
},
|
||||
onError(e) {
|
||||
this.triggerEvent('error', e.detail || {});
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<view
|
||||
class="ui-btn ui-btn--{{variant}} ui-btn--{{size}} {{block ? 'ui-btn--block' : ''}} {{disabled ? 'ui-btn--disabled' : ''}} {{loading ? 'ui-btn--loading' : ''}} custom-class"
|
||||
hover-class="{{disabled || loading ? '' : hoverClass}}"
|
||||
hover-stay-time="100"
|
||||
bindtap="onTap"
|
||||
>
|
||||
<view wx:if="{{loading}}" class="ui-btn__spinner">
|
||||
<view class="ui-btn__spinner-dot"></view>
|
||||
</view>
|
||||
<slot></slot>
|
||||
</view>
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Button 组件样式
|
||||
* 引用全局 Design Token(addGlobalClass: true)
|
||||
*/
|
||||
.ui-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--radius-full);
|
||||
font-family: var(--font-family-cn);
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-align: center;
|
||||
transition: opacity var(--motion-fast) var(--ease-standard),
|
||||
transform var(--motion-fast) var(--ease-standard);
|
||||
user-select: none;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 尺寸 */
|
||||
.ui-btn--sm {
|
||||
padding: 14rpx 24rpx;
|
||||
font-size: var(--font-size-sm);
|
||||
min-height: 56rpx;
|
||||
}
|
||||
.ui-btn--md {
|
||||
padding: 20rpx 36rpx;
|
||||
font-size: var(--font-size-base);
|
||||
min-height: 80rpx;
|
||||
}
|
||||
.ui-btn--lg {
|
||||
padding: 26rpx 48rpx;
|
||||
font-size: var(--font-size-lg);
|
||||
min-height: 96rpx;
|
||||
}
|
||||
|
||||
/* 撑满 */
|
||||
.ui-btn--block {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 变体 */
|
||||
.ui-btn--primary {
|
||||
background: var(--color-primary);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.ui-btn--secondary {
|
||||
background: var(--color-bg-card);
|
||||
color: var(--color-primary);
|
||||
border: 1rpx solid var(--color-primary);
|
||||
}
|
||||
.ui-btn--ghost {
|
||||
background: transparent;
|
||||
color: var(--color-text-primary);
|
||||
border: 1rpx solid var(--color-border);
|
||||
}
|
||||
.ui-btn--danger {
|
||||
background: var(--color-danger);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.ui-btn--text {
|
||||
background: transparent;
|
||||
color: var(--color-primary);
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
/* 状态 */
|
||||
.ui-btn--disabled,
|
||||
.ui-btn--loading {
|
||||
opacity: 0.55;
|
||||
}
|
||||
.ui-btn--disabled.ui-btn--primary,
|
||||
.ui-btn--disabled.ui-btn--danger {
|
||||
background: var(--color-text-disabled);
|
||||
}
|
||||
.ui-btn--disabled.ui-btn--secondary,
|
||||
.ui-btn--disabled.ui-btn--ghost {
|
||||
color: var(--color-text-disabled);
|
||||
border-color: var(--color-text-disabled);
|
||||
}
|
||||
|
||||
.ui-btn--hover {
|
||||
opacity: 0.85;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
/* Loading spinner */
|
||||
.ui-btn__spinner {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
margin-right: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.ui-btn__spinner-dot {
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 50%;
|
||||
border: 3rpx solid currentColor;
|
||||
border-top-color: transparent;
|
||||
animation: ui-btn-spin 0.7s linear infinite;
|
||||
}
|
||||
@keyframes ui-btn-spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
Reference in New Issue
Block a user