292 lines
8.1 KiB
TypeScript
292 lines
8.1 KiB
TypeScript
Component({
|
||
options: {
|
||
styleIsolation: 'apply-shared',
|
||
addGlobalClass: true,
|
||
},
|
||
properties: {
|
||
type: {
|
||
type: String,
|
||
value: 'default',
|
||
},
|
||
size: {
|
||
type: String,
|
||
value: 'normal',
|
||
},
|
||
variant: {
|
||
type: String,
|
||
value: 'filled',
|
||
},
|
||
block: {
|
||
type: Boolean,
|
||
value: false,
|
||
},
|
||
disabled: {
|
||
type: Boolean,
|
||
value: false,
|
||
},
|
||
loading: {
|
||
type: Boolean,
|
||
value: false,
|
||
},
|
||
icon: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
iconOnly: {
|
||
type: Boolean,
|
||
value: false,
|
||
},
|
||
iconClassPrefix: {
|
||
type: String,
|
||
value: 'toy-icon',
|
||
},
|
||
iconSize: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
iconColor: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
openType: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
style: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
width: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
height: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
loadingSize: {
|
||
type: String,
|
||
value: '20px',
|
||
},
|
||
sessionFrom: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
sendMessageTitle: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
sendMessagePath: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
sendMessageImg: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
showMessageCard: {
|
||
type: Boolean,
|
||
value: false,
|
||
},
|
||
appParameter: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
ariaLabel: {
|
||
type: String,
|
||
value: '',
|
||
},
|
||
},
|
||
externalClasses: ['custom-class'],
|
||
data: {
|
||
pressed: false,
|
||
rootClassName: '',
|
||
rootStyle: '',
|
||
resolvedIconColor: '',
|
||
resolvedIconSize: '44rpx',
|
||
resolvedLoadingColor: '#ffffff',
|
||
},
|
||
observers: {
|
||
'type,size,variant,block,disabled,loading,iconOnly,style,width,height,iconColor,iconSize,pressed':
|
||
function () {
|
||
this.syncViewState();
|
||
},
|
||
},
|
||
lifetimes: {
|
||
attached() {
|
||
this.syncViewState();
|
||
},
|
||
},
|
||
methods: {
|
||
syncViewState() {
|
||
const {
|
||
type,
|
||
size,
|
||
variant,
|
||
block,
|
||
disabled,
|
||
loading,
|
||
iconOnly,
|
||
style,
|
||
width,
|
||
height,
|
||
iconColor,
|
||
iconSize,
|
||
pressed,
|
||
} = this.data;
|
||
|
||
const visualType = type === 'green' ? 'secondary' : type;
|
||
|
||
const cls = ['toy-btn'];
|
||
cls.push(`toy-btn--${visualType}`);
|
||
cls.push(`toy-btn--${size}`);
|
||
|
||
if (variant !== 'filled') {
|
||
cls.push(`toy-btn--${variant}`);
|
||
}
|
||
if (block) {
|
||
cls.push('toy-btn--block');
|
||
}
|
||
if (iconOnly) {
|
||
cls.push('toy-btn--icon-only');
|
||
}
|
||
if (disabled) {
|
||
cls.push('toy-btn--disabled');
|
||
}
|
||
if (loading) {
|
||
cls.push('toy-btn--loading');
|
||
}
|
||
if (pressed && !disabled && !loading) {
|
||
cls.push('toy-btn--active');
|
||
}
|
||
|
||
const styleParts = [style];
|
||
const w = this.normalizeUnit(width);
|
||
const h = this.normalizeUnit(height);
|
||
if (w) styleParts.push(`width:${w}`);
|
||
if (h) styleParts.push(`height:${h}`);
|
||
|
||
const resolvedIconColor = this.resolveIconColor(
|
||
iconColor,
|
||
visualType,
|
||
variant,
|
||
disabled,
|
||
pressed,
|
||
);
|
||
const resolvedIconSize =
|
||
this.normalizeUnit(iconSize) ||
|
||
this.getDefaultIconSize(size, iconOnly);
|
||
|
||
this.setData({
|
||
rootClassName: cls.join(' '),
|
||
rootStyle: styleParts.filter(Boolean).join(';'),
|
||
resolvedIconColor,
|
||
resolvedIconSize,
|
||
resolvedLoadingColor: resolvedIconColor || '#ffffff',
|
||
});
|
||
},
|
||
|
||
normalizeUnit(value: string) {
|
||
if (!value) return '';
|
||
return /^\d+(\.\d+)?$/.test(value) ? `${value}rpx` : value;
|
||
},
|
||
|
||
getDefaultIconSize(size: string, iconOnly: boolean) {
|
||
if (iconOnly) {
|
||
const map: Record<string, string> = {
|
||
large: '56rpx',
|
||
normal: '48rpx',
|
||
small: '44rpx',
|
||
mini: '40rpx',
|
||
};
|
||
return map[size] || '48rpx';
|
||
}
|
||
const map: Record<string, string> = {
|
||
large: '44rpx',
|
||
normal: '40rpx',
|
||
small: '36rpx',
|
||
mini: '32rpx',
|
||
};
|
||
return map[size] || '40rpx';
|
||
},
|
||
|
||
resolveIconColor(
|
||
iconColor: string,
|
||
type: string,
|
||
variant: string,
|
||
disabled: boolean,
|
||
pressed: boolean,
|
||
) {
|
||
if (disabled) return '#b8b2a6';
|
||
if (iconColor) return iconColor;
|
||
|
||
/* 与 .toy-btn--primary.toy-btn--active 的 color(@btn-primary-pressed-text)一致 */
|
||
if (pressed && variant === 'filled' && type === 'primary') {
|
||
return '#fff2cd';
|
||
}
|
||
|
||
if (variant === 'outlined' || variant === 'ghost') {
|
||
const outlinedMap: Record<string, string> = {
|
||
primary: '#6c5a00',
|
||
secondary: '#5a8c1a',
|
||
error: '#b02500',
|
||
default: '#605b50',
|
||
};
|
||
return outlinedMap[type] || '#605b50';
|
||
}
|
||
|
||
const filledMap: Record<string, string> = {
|
||
primary: '#5b4b00',
|
||
error: '#520c00',
|
||
default: '#322e25',
|
||
white: '#322e25',
|
||
};
|
||
return filledMap[type] || '#ffffff';
|
||
},
|
||
|
||
onTouchStart() {
|
||
if (this.data.disabled || this.data.loading) return;
|
||
this.setData({ pressed: true });
|
||
},
|
||
onTouchEnd() {
|
||
if (!this.data.pressed) return;
|
||
this.setData({ pressed: false });
|
||
},
|
||
onTouchCancel() {
|
||
if (!this.data.pressed) return;
|
||
this.setData({ pressed: false });
|
||
},
|
||
onClick(e: WechatMiniprogram.TouchEvent) {
|
||
if (this.data.disabled || this.data.loading) return;
|
||
this.triggerEvent('click', e);
|
||
},
|
||
onGetUserInfo(e: WechatMiniprogram.CustomEvent) {
|
||
this.triggerEvent('getuserinfo', e.detail);
|
||
},
|
||
onContact(e: WechatMiniprogram.CustomEvent) {
|
||
this.triggerEvent('contact', e.detail);
|
||
},
|
||
onGetPhoneNumber(e: WechatMiniprogram.CustomEvent) {
|
||
this.triggerEvent('getphonenumber', e.detail);
|
||
},
|
||
onGetRealTimePhoneNumber(e: WechatMiniprogram.CustomEvent) {
|
||
this.triggerEvent('getrealtimephonenumber', e.detail);
|
||
},
|
||
onAgreePrivacyAuthorization(e: WechatMiniprogram.CustomEvent) {
|
||
this.triggerEvent('agreeprivacyauthorization', e.detail);
|
||
},
|
||
onError(e: WechatMiniprogram.CustomEvent) {
|
||
this.triggerEvent('error', e.detail);
|
||
},
|
||
onLaunchApp(e: WechatMiniprogram.CustomEvent) {
|
||
this.triggerEvent('launchapp', e.detail);
|
||
},
|
||
onOpenSetting(e: WechatMiniprogram.CustomEvent) {
|
||
this.triggerEvent('opensetting', e.detail);
|
||
},
|
||
onChooseAvatar(e: WechatMiniprogram.CustomEvent) {
|
||
this.triggerEvent('chooseavatar', e.detail);
|
||
},
|
||
},
|
||
});
|