更新:登录功能
This commit is contained in:
336
uni_modules/wot-design-uni/components/wd-button/index.scss
Normal file
336
uni_modules/wot-design-uni/components/wd-button/index.scss
Normal file
@@ -0,0 +1,336 @@
|
||||
@import './../common/abstracts/_mixin.scss';
|
||||
@import './../common/abstracts/variable.scss';
|
||||
|
||||
|
||||
.wot-theme-dark {
|
||||
@include b(button) {
|
||||
@include when(info) {
|
||||
background: $-dark-background4;
|
||||
color: $-dark-color3;
|
||||
}
|
||||
|
||||
@include when(plain) {
|
||||
background: transparent;
|
||||
|
||||
@include when(info) {
|
||||
color: $-dark-color;
|
||||
|
||||
&::after {
|
||||
border-color: $-dark-background5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include when(text) {
|
||||
@include when(disabled) {
|
||||
color: $-dark-color-gray;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@include when(icon) {
|
||||
color: $-dark-color;
|
||||
|
||||
@include when(disabled) {
|
||||
color: $-dark-color-gray;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include b(button) {
|
||||
margin-left: initial;
|
||||
margin-right: initial;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
outline: none;
|
||||
-webkit-appearance: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
color: $-button-normal-color;
|
||||
transition: opacity 0.2s;
|
||||
user-select: none;
|
||||
font-weight: normal;
|
||||
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: $-color-black;
|
||||
border: inherit;
|
||||
border-color: $-color-black;
|
||||
border-radius: inherit;
|
||||
transform: translate(-50%, -50%);
|
||||
opacity: 0;
|
||||
content: ' ';
|
||||
}
|
||||
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
@include e(content) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@include m(active) {
|
||||
&:active::before {
|
||||
opacity: 0.15;
|
||||
}
|
||||
}
|
||||
|
||||
@include when(disabled) {
|
||||
opacity: $-button-disabled-opacity;
|
||||
}
|
||||
|
||||
@include e(loading) {
|
||||
margin-right: 5px;
|
||||
animation: wd-rotate 0.8s linear infinite;
|
||||
animation-duration: 2s;
|
||||
}
|
||||
|
||||
@include e(loading-svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
@include when(loading) {}
|
||||
|
||||
@include when(primary) {
|
||||
background: $-button-primary-bg-color;
|
||||
color: $-button-primary-color;
|
||||
}
|
||||
|
||||
@include when(success) {
|
||||
background: $-button-success-bg-color;
|
||||
color: $-button-success-color;
|
||||
}
|
||||
|
||||
@include when(info) {
|
||||
background: $-button-info-bg-color;
|
||||
color: $-button-info-color;
|
||||
}
|
||||
|
||||
@include when(warning) {
|
||||
background: $-button-warning-bg-color;
|
||||
color: $-button-warning-color;
|
||||
}
|
||||
|
||||
@include when(error) {
|
||||
background: $-button-error-bg-color;
|
||||
color: $-button-error-color;
|
||||
}
|
||||
|
||||
@include when(small) {
|
||||
height: $-button-small-height;
|
||||
padding: $-button-small-padding;
|
||||
border-radius: $-button-small-radius;
|
||||
font-size: $-button-small-fs;
|
||||
font-weight: normal;
|
||||
|
||||
.wd-button__loading {
|
||||
width: $-button-small-loading;
|
||||
height: $-button-small-loading;
|
||||
}
|
||||
}
|
||||
|
||||
@include when(medium) {
|
||||
height: $-button-medium-height;
|
||||
padding: $-button-medium-padding;
|
||||
border-radius: $-button-medium-radius;
|
||||
font-size: $-button-medium-fs;
|
||||
min-width: 120px;
|
||||
|
||||
|
||||
@include when(round) {
|
||||
|
||||
@include when(icon) {
|
||||
min-width: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@include when(text) {
|
||||
border-radius: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.wd-button__loading {
|
||||
width: $-button-medium-loading;
|
||||
height: $-button-medium-loading;
|
||||
}
|
||||
}
|
||||
|
||||
@include when(large) {
|
||||
height: $-button-large-height;
|
||||
padding: $-button-large-padding;
|
||||
border-radius: $-button-large-radius;
|
||||
font-size: $-button-large-fs;
|
||||
|
||||
&::after {
|
||||
border-radius: $-button-large-radius;
|
||||
}
|
||||
|
||||
.wd-button__loading {
|
||||
width: $-button-large-loading;
|
||||
height: $-button-large-loading;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@include when(round) {
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
@include when(text) {
|
||||
color: $-button-primary-bg-color;
|
||||
min-width: 0;
|
||||
padding: 4px 0;
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.wd-button--active {
|
||||
opacity: $-button-text-hover-opacity;
|
||||
|
||||
&:active::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@include when(disabled) {
|
||||
color: $-button-normal-disabled-color;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@include when(plain) {
|
||||
background: $-button-plain-bg-color;
|
||||
border: 1px solid currentColor;
|
||||
|
||||
@include when(primary) {
|
||||
color: $-button-primary-bg-color;
|
||||
}
|
||||
|
||||
@include when(success) {
|
||||
color: $-button-success-bg-color;
|
||||
}
|
||||
|
||||
@include when(info) {
|
||||
color: $-button-info-plain-normal-color;
|
||||
border-color: $-button-info-plain-border-color;
|
||||
}
|
||||
|
||||
@include when(warning) {
|
||||
color: $-button-warning-bg-color;
|
||||
}
|
||||
|
||||
@include when(error) {
|
||||
color: $-button-error-bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
@include when(hairline) {
|
||||
border-width: 0;
|
||||
|
||||
&.is-plain {
|
||||
@include halfPixelBorderSurround();
|
||||
|
||||
&::before {
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
&::after {
|
||||
border-color: inherit;
|
||||
}
|
||||
|
||||
&.is-round {
|
||||
&::after {
|
||||
border-radius: inherit !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-large {
|
||||
&::after {
|
||||
border-radius: calc(2 * $-button-large-radius);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-medium {
|
||||
&::after {
|
||||
border-radius: calc(2 * $-button-medium-radius);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-small {
|
||||
&::after {
|
||||
border-radius: calc(2 * $-button-small-radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include when(block) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@include when(icon) {
|
||||
width: $-button-icon-size;
|
||||
height: $-button-icon-size;
|
||||
padding: 0;
|
||||
border-radius: 50%;
|
||||
color: $-button-icon-color;
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:deep(.wd-button__icon) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
@include when(disabled) {
|
||||
color: $-button-icon-disabled-color;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@include edeep(icon) {
|
||||
display: block;
|
||||
margin-right: 6px;
|
||||
font-size: $-button-icon-fs;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@include e(text) {
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes wd-rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
142
uni_modules/wot-design-uni/components/wd-button/types.ts
Normal file
142
uni_modules/wot-design-uni/components/wd-button/types.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* @Author: weisheng
|
||||
* @Date: 2024-03-15 11:36:12
|
||||
* @LastEditTime: 2024-11-04 21:33:52
|
||||
* @LastEditors: weisheng
|
||||
* @Description:
|
||||
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-button\types.ts
|
||||
* 记得注释
|
||||
*/
|
||||
import type { ExtractPropTypes, PropType } from 'vue'
|
||||
import { baseProps, makeBooleanProp, makeStringProp } from '../common/props'
|
||||
|
||||
export type ButtonType = 'primary' | 'success' | 'info' | 'warning' | 'error' | 'default' | 'text' | 'icon'
|
||||
export type ButtonSize = 'small' | 'medium' | 'large'
|
||||
export type ButtonLang = 'zh_CN' | 'zh_TW' | 'en'
|
||||
|
||||
export type ButtonOpenType =
|
||||
| 'feedback'
|
||||
| 'share'
|
||||
| 'getUserInfo'
|
||||
| 'contact'
|
||||
| 'getPhoneNumber'
|
||||
| 'getRealtimePhoneNumber'
|
||||
| 'launchApp'
|
||||
| 'openSetting'
|
||||
| 'chooseAvatar'
|
||||
| 'getAuthorize'
|
||||
| 'lifestyle'
|
||||
| 'contactShare'
|
||||
| 'openGroupProfile'
|
||||
| 'openGuildProfile'
|
||||
| 'openPublicProfile'
|
||||
| 'shareMessageToFriend'
|
||||
| 'addFriend'
|
||||
| 'addColorSign'
|
||||
| 'addGroupApp'
|
||||
| 'addToFavorites'
|
||||
| 'chooseAddress'
|
||||
| 'chooseInvoiceTitle'
|
||||
| 'login'
|
||||
| 'subscribe'
|
||||
| 'favorite'
|
||||
| 'watchLater'
|
||||
| 'openProfile'
|
||||
| 'agreePrivacyAuthorization'
|
||||
|
||||
export type ButtonScope = 'phoneNumber' | 'userInfo'
|
||||
|
||||
export const buttonProps = {
|
||||
...baseProps,
|
||||
/**
|
||||
* 幽灵按钮
|
||||
*/
|
||||
plain: makeBooleanProp(false),
|
||||
/**
|
||||
* 圆角按钮
|
||||
*/
|
||||
round: makeBooleanProp(true),
|
||||
/**
|
||||
* 禁用按钮
|
||||
*/
|
||||
disabled: makeBooleanProp(false),
|
||||
/**
|
||||
* 是否细边框
|
||||
*/
|
||||
hairline: makeBooleanProp(false),
|
||||
/**
|
||||
* 块状按钮
|
||||
*/
|
||||
block: makeBooleanProp(false),
|
||||
/**
|
||||
* 按钮类型,可选值:primary / success / info / warning / error / text / icon
|
||||
*/
|
||||
type: makeStringProp<ButtonType>('primary'),
|
||||
/**
|
||||
* 按钮尺寸,可选值:small / medium / large
|
||||
*/
|
||||
size: makeStringProp<ButtonSize>('medium'),
|
||||
/**
|
||||
* 图标类名
|
||||
*/
|
||||
icon: String,
|
||||
/**
|
||||
* 类名前缀,用于使用自定义图标,用法参考Icon组件
|
||||
*/
|
||||
classPrefix: makeStringProp('wd-icon'),
|
||||
/**
|
||||
* 加载中按钮
|
||||
*/
|
||||
loading: makeBooleanProp(false),
|
||||
/**
|
||||
* 加载图标颜色
|
||||
*/
|
||||
loadingColor: String,
|
||||
/**
|
||||
* 开放能力
|
||||
*/
|
||||
openType: String as PropType<ButtonOpenType>,
|
||||
/**
|
||||
* 指定是否阻止本节点的祖先节点出现点击态
|
||||
*/
|
||||
hoverStopPropagation: Boolean,
|
||||
/**
|
||||
* 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
|
||||
*/
|
||||
lang: String as PropType<ButtonLang>,
|
||||
/**
|
||||
* 会话来源,open-type="contact"时有效
|
||||
*/
|
||||
sessionFrom: String,
|
||||
/**
|
||||
* 会话内消息卡片标题,open-type="contact"时有效
|
||||
*/
|
||||
sendMessageTitle: String,
|
||||
/**
|
||||
* 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效
|
||||
*/
|
||||
sendMessagePath: String,
|
||||
/**
|
||||
* 会话内消息卡片图片,open-type="contact"时有效
|
||||
*/
|
||||
sendMessageImg: String,
|
||||
/**
|
||||
* 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
|
||||
*/
|
||||
appParameter: String,
|
||||
/**
|
||||
* 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,open-type="contact"时有效
|
||||
*/
|
||||
showMessageCard: Boolean,
|
||||
/**
|
||||
* 按钮的唯一标识,可用于设置隐私同意授权按钮的id
|
||||
*/
|
||||
buttonId: String,
|
||||
/**
|
||||
* 支付宝小程序,当 open-type 为 getAuthorize 时有效。
|
||||
* 可选值:'phoneNumber' | 'userInfo'
|
||||
*/
|
||||
scope: String as PropType<ButtonScope>
|
||||
}
|
||||
|
||||
export type ButtonProps = ExtractPropTypes<typeof buttonProps>
|
||||
195
uni_modules/wot-design-uni/components/wd-button/wd-button.vue
Normal file
195
uni_modules/wot-design-uni/components/wd-button/wd-button.vue
Normal file
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<button
|
||||
:id="buttonId"
|
||||
:hover-class="`${disabled || loading ? '' : 'wd-button--active'}`"
|
||||
:style="customStyle"
|
||||
:class="[
|
||||
'wd-button',
|
||||
'is-' + type,
|
||||
'is-' + size,
|
||||
round ? 'is-round' : '',
|
||||
hairline ? 'is-hairline' : '',
|
||||
plain ? 'is-plain' : '',
|
||||
disabled ? 'is-disabled' : '',
|
||||
block ? 'is-block' : '',
|
||||
loading ? 'is-loading' : '',
|
||||
customClass
|
||||
]"
|
||||
:hover-start-time="hoverStartTime"
|
||||
:hover-stay-time="hoverStayTime"
|
||||
:open-type="disabled || loading ? undefined : openType"
|
||||
:send-message-title="sendMessageTitle"
|
||||
:send-message-path="sendMessagePath"
|
||||
:send-message-img="sendMessageImg"
|
||||
:app-parameter="appParameter"
|
||||
:show-message-card="showMessageCard"
|
||||
:session-from="sessionFrom"
|
||||
:lang="lang"
|
||||
:hover-stop-propagation="hoverStopPropagation"
|
||||
:scope="scope"
|
||||
@click="handleClick"
|
||||
@getAuthorize="handleGetAuthorize"
|
||||
@getuserinfo="handleGetuserinfo"
|
||||
@contact="handleConcat"
|
||||
@getphonenumber="handleGetphonenumber"
|
||||
@getrealtimephonenumber="handleGetrealtimephonenumber"
|
||||
@error="handleError"
|
||||
@launchapp="handleLaunchapp"
|
||||
@opensetting="handleOpensetting"
|
||||
@chooseavatar="handleChooseavatar"
|
||||
@agreeprivacyauthorization="handleAgreePrivacyAuthorization"
|
||||
>
|
||||
<view class="wd-button__content">
|
||||
<view v-if="loading" class="wd-button__loading">
|
||||
<view class="wd-button__loading-svg" :style="loadingStyle"></view>
|
||||
</view>
|
||||
<wd-icon v-else-if="icon" custom-class="wd-button__icon" :name="icon" :classPrefix="classPrefix"></wd-icon>
|
||||
<view class="wd-button__text"><slot /></view>
|
||||
</view>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'wd-button',
|
||||
options: {
|
||||
addGlobalClass: true,
|
||||
virtualHost: true,
|
||||
styleIsolation: 'shared'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import wdIcon from '../wd-icon/wd-icon.vue'
|
||||
import { computed, watch } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import base64 from '../common/base64'
|
||||
import { buttonProps } from './types'
|
||||
|
||||
const loadingIcon = (color = '#4D80F0', reverse = true) => {
|
||||
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 42 42"><defs><linearGradient x1="100%" y1="0%" x2="0%" y2="0%" id="a"><stop stop-color="${
|
||||
reverse ? color : '#fff'
|
||||
}" offset="0%" stop-opacity="0"/><stop stop-color="${
|
||||
reverse ? color : '#fff'
|
||||
}" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path d="M21 1c11.046 0 20 8.954 20 20s-8.954 20-20 20S1 32.046 1 21 9.954 1 21 1zm0 7C13.82 8 8 13.82 8 21s5.82 13 13 13 13-5.82 13-13S28.18 8 21 8z" fill="${
|
||||
reverse ? '#fff' : color
|
||||
}"/><path d="M4.599 21c0 9.044 7.332 16.376 16.376 16.376 9.045 0 16.376-7.332 16.376-16.376" stroke="url(#a)" stroke-width="3.5" stroke-linecap="round"/></g></svg>`
|
||||
}
|
||||
const props = defineProps(buttonProps)
|
||||
const emit = defineEmits([
|
||||
'click',
|
||||
'getuserinfo',
|
||||
'contact',
|
||||
'getphonenumber',
|
||||
'getrealtimephonenumber',
|
||||
'error',
|
||||
'launchapp',
|
||||
'opensetting',
|
||||
'chooseavatar',
|
||||
'agreeprivacyauthorization'
|
||||
])
|
||||
|
||||
const hoverStartTime = ref<number>(20)
|
||||
const hoverStayTime = ref<number>(70)
|
||||
const loadingIconSvg = ref<string>('')
|
||||
|
||||
const loadingStyle = computed(() => {
|
||||
return `background-image: url(${loadingIconSvg.value});`
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.loading,
|
||||
() => {
|
||||
buildLoadingSvg()
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
function handleClick(event: any) {
|
||||
if (!props.disabled && !props.loading) {
|
||||
emit('click', event)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝小程序授权
|
||||
* @param event
|
||||
*/
|
||||
function handleGetAuthorize(event: any) {
|
||||
if (props.scope === 'phoneNumber') {
|
||||
handleGetphonenumber(event)
|
||||
} else if (props.scope === 'userInfo') {
|
||||
handleGetuserinfo(event)
|
||||
}
|
||||
}
|
||||
|
||||
function handleGetuserinfo(event: any) {
|
||||
emit('getuserinfo', event.detail)
|
||||
}
|
||||
|
||||
function handleConcat(event: any) {
|
||||
emit('contact', event.detail)
|
||||
}
|
||||
|
||||
function handleGetphonenumber(event: any) {
|
||||
emit('getphonenumber', event.detail)
|
||||
}
|
||||
|
||||
function handleGetrealtimephonenumber(event: any) {
|
||||
emit('getrealtimephonenumber', event.detail)
|
||||
}
|
||||
|
||||
function handleError(event: any) {
|
||||
emit('error', event.detail)
|
||||
}
|
||||
|
||||
function handleLaunchapp(event: any) {
|
||||
emit('launchapp', event.detail)
|
||||
}
|
||||
|
||||
function handleOpensetting(event: any) {
|
||||
emit('opensetting', event.detail)
|
||||
}
|
||||
|
||||
function handleChooseavatar(event: any) {
|
||||
emit('chooseavatar', event.detail)
|
||||
}
|
||||
|
||||
function handleAgreePrivacyAuthorization(event: any) {
|
||||
emit('agreeprivacyauthorization', event.detail)
|
||||
}
|
||||
function buildLoadingSvg() {
|
||||
const { loadingColor, type, plain } = props
|
||||
let color = loadingColor
|
||||
if (!color) {
|
||||
switch (type) {
|
||||
case 'primary':
|
||||
color = '#4D80F0'
|
||||
break
|
||||
case 'success':
|
||||
color = '#34d19d'
|
||||
break
|
||||
case 'info':
|
||||
color = '#333'
|
||||
break
|
||||
case 'warning':
|
||||
color = '#f0883a'
|
||||
break
|
||||
case 'error':
|
||||
color = '#fa4350'
|
||||
break
|
||||
case 'default':
|
||||
color = '#333'
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const svg = loadingIcon(color, !plain)
|
||||
loadingIconSvg.value = `"data:image/svg+xml;base64,${base64(svg)}"`
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './index.scss';
|
||||
</style>
|
||||
Reference in New Issue
Block a user