init
This commit is contained in:
139
uni_modules/nutui-uni/components/button/button.ts
Normal file
139
uni_modules/nutui-uni/components/button/button.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
import type { ButtonLang, ButtonOnAddgroupappEvent, ButtonOnAgreeprivacyauthorizationEvent, ButtonOnChooseaddressEvent, ButtonOnChooseavatarEvent, ButtonOnChooseinvoicetitleEvent, ButtonOnErrorEvent, ButtonOnGetphonenumberEvent, ButtonOnLaunchappEvent, ButtonOnLoginEvent, ButtonOnOpensettingEvent, ButtonOnSubscribeEvent, ButtonOpenType } from '@uni-helper/uni-app-types'
|
||||
import type { ExtractPropTypes, PropType } from 'vue'
|
||||
import { CLICK_EVENT } from '../_constants'
|
||||
import { commonProps, makeNumberProp, makeStringProp } from '../_utils'
|
||||
import type { ButtonFormType, ButtonShape, ButtonSize, ButtonType } from './type'
|
||||
|
||||
export const buttonProps = {
|
||||
...commonProps,
|
||||
/**
|
||||
* @description 指定按钮按下去的样式类
|
||||
*/
|
||||
hoverClass: makeStringProp('button-hover'),
|
||||
/**
|
||||
* @description 按住后多久出现点击态,单位毫秒
|
||||
*/
|
||||
hoverStartTime: makeNumberProp(20),
|
||||
/**
|
||||
* @description 手指松开后点击态保留时间,单位毫秒
|
||||
*/
|
||||
hoverStayTime: makeNumberProp(70),
|
||||
/**
|
||||
* @description 按钮颜色,支持传入 `linear-gradient` 渐变色
|
||||
*/
|
||||
customColor: String,
|
||||
/**
|
||||
* @description 形状,可选值为 `square` `round`
|
||||
*/
|
||||
shape: makeStringProp<ButtonShape>('round'),
|
||||
/**
|
||||
* @description 是否为朴素按钮
|
||||
*/
|
||||
plain: Boolean,
|
||||
/**
|
||||
* @description 按钮 `loading` 状态
|
||||
*/
|
||||
loading: Boolean,
|
||||
/**
|
||||
* @description 是否禁用按钮
|
||||
*/
|
||||
disabled: Boolean,
|
||||
/**
|
||||
* @description 按钮类型,可选值为 `primary` `info` `warning` `danger` `success` `default`
|
||||
*/
|
||||
type: makeStringProp<ButtonType>('default'),
|
||||
/**
|
||||
* @description 表单类型,可选值 `button` `submit` `reset`
|
||||
*/
|
||||
formType: makeStringProp<ButtonFormType>('button'),
|
||||
/**
|
||||
* @description 尺寸,可选值为 `large` `small` `mini` `normal`
|
||||
*/
|
||||
size: makeStringProp<ButtonSize>('normal'),
|
||||
/**
|
||||
* @description 是否为块级元素
|
||||
*/
|
||||
block: Boolean,
|
||||
/**
|
||||
* @description 小程序开放能力
|
||||
*/
|
||||
openType: String as PropType<ButtonOpenType>,
|
||||
/**
|
||||
* @description 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
|
||||
*/
|
||||
lang: makeStringProp<ButtonLang>('en'),
|
||||
/**
|
||||
* @description 会话来源,openType="contact"时有效
|
||||
*/
|
||||
sessionFrom: String,
|
||||
/**
|
||||
* @description 会话内消息卡片标题,openType="contact"时有效
|
||||
*/
|
||||
sendMessageTitle: String,
|
||||
/**
|
||||
* @description 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
|
||||
*/
|
||||
sendMessagePath: String,
|
||||
/**
|
||||
* @description 会话内消息卡片图片,openType="contact"时有效
|
||||
*/
|
||||
sendMessageImg: String,
|
||||
/**
|
||||
* @description 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效
|
||||
*/
|
||||
showMessageCard: Boolean,
|
||||
/**
|
||||
* @description 打开群资料卡时,传递的群号,openType="openGroupProfile"时有效
|
||||
*/
|
||||
groupId: String,
|
||||
/**
|
||||
* @description 打开频道页面时,传递的频道号 openType="openGuildProfile"时有效
|
||||
*/
|
||||
guildId: makeStringProp(''),
|
||||
/**
|
||||
* @description 打开公众号资料卡时,传递的号码 openType="openPublicProfile"时有效
|
||||
*/
|
||||
publicId: String,
|
||||
/**
|
||||
* @description 客服的抖音号,openType="im"时有效
|
||||
*/
|
||||
dataImId: String,
|
||||
/**
|
||||
* @description IM卡片类型,openType="im"时有效
|
||||
*/
|
||||
dataImType: String,
|
||||
/**
|
||||
* @description 商品的id,仅支持泛知识课程库和生活服务商品库中的商品,openType="im"时有效
|
||||
*/
|
||||
dataGoodsId: String,
|
||||
/**
|
||||
* @description 订单的id,仅支持交易2.0订单, openType="im"时有效
|
||||
*/
|
||||
dataOrderId: String,
|
||||
/**
|
||||
* @description 商品类型,“1”代表生活服务,“2”代表泛知识。openType="im"时有效
|
||||
*/
|
||||
dataBizLine: String,
|
||||
} as const
|
||||
|
||||
export type ButtonProps = ExtractPropTypes<typeof buttonProps>
|
||||
|
||||
export const buttonEmits = {
|
||||
[CLICK_EVENT]: (evt: MouseEvent) => evt instanceof Object,
|
||||
getphonenumber: (evt: ButtonOnGetphonenumberEvent) => evt instanceof Object,
|
||||
getuserinfo: (evt: any) => evt instanceof Object,
|
||||
error: (evt: ButtonOnErrorEvent) => evt instanceof Object,
|
||||
opensetting: (evt: ButtonOnOpensettingEvent) => evt instanceof Object,
|
||||
launchapp: (evt: ButtonOnLaunchappEvent) => evt instanceof Object,
|
||||
contact: (evt: any) => evt instanceof Object,
|
||||
chooseavatar: (evt: ButtonOnChooseavatarEvent) => evt instanceof Object,
|
||||
agreeprivacyauthorization: (evt: ButtonOnAgreeprivacyauthorizationEvent) => evt instanceof Object,
|
||||
addgroupapp: (evt: ButtonOnAddgroupappEvent) => evt instanceof Object,
|
||||
chooseaddress: (evt: ButtonOnChooseaddressEvent) => evt instanceof Object,
|
||||
chooseinvoicetitle: (evt: ButtonOnChooseinvoicetitleEvent) => evt instanceof Object,
|
||||
subscribe: (evt: ButtonOnSubscribeEvent) => evt instanceof Object,
|
||||
login: (evt: ButtonOnLoginEvent) => evt instanceof Object,
|
||||
im: (evt: any) => evt instanceof Object,
|
||||
}
|
||||
|
||||
export type ButtonEmits = typeof buttonEmits
|
||||
121
uni_modules/nutui-uni/components/button/button.vue
Normal file
121
uni_modules/nutui-uni/components/button/button.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<script lang="ts" setup>
|
||||
import type { CSSProperties } from 'vue'
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { CLICK_EVENT, PREFIX } from '../_constants'
|
||||
import { getMainClass, getMainStyle } from '../_utils'
|
||||
import Icon from '../icon/icon.vue'
|
||||
import { buttonEmits, buttonProps } from './button'
|
||||
|
||||
const props = defineProps(buttonProps)
|
||||
|
||||
const emit = defineEmits(buttonEmits)
|
||||
|
||||
const classes = computed(() => {
|
||||
return getMainClass(props, componentName, {
|
||||
[`${componentName}--${props.type}`]: !!props.type,
|
||||
[`${componentName}--${props.size}`]: !!props.size,
|
||||
[`${componentName}--${props.shape}`]: !!props.shape,
|
||||
[`${componentName}--plain`]: props.plain,
|
||||
[`${componentName}--block`]: props.block,
|
||||
[`${componentName}--disabled`]: props.disabled,
|
||||
[`${componentName}--loading`]: props.loading,
|
||||
[`${componentName}--hovercls`]: props.hoverClass !== 'button-hover',
|
||||
})
|
||||
})
|
||||
|
||||
const styles = computed(() => {
|
||||
const value: CSSProperties = {}
|
||||
|
||||
if (props.customColor) {
|
||||
if (props.plain) {
|
||||
value.color = props.customColor
|
||||
value.background = '#fff'
|
||||
|
||||
if (!props.customColor.includes('gradient'))
|
||||
value.borderColor = props.customColor
|
||||
}
|
||||
else {
|
||||
value.color = '#fff'
|
||||
value.background = props.customColor
|
||||
}
|
||||
}
|
||||
|
||||
return getMainStyle(props, value)
|
||||
})
|
||||
|
||||
function handleClick(event: any) {
|
||||
if (props.disabled || props.loading)
|
||||
return
|
||||
|
||||
emit(CLICK_EVENT, event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
const componentName = `${PREFIX}-button`
|
||||
|
||||
export default defineComponent({
|
||||
name: componentName,
|
||||
options: {
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
// #ifndef H5
|
||||
styleIsolation: 'shared',
|
||||
// #endif
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
:class="classes"
|
||||
:style="styles"
|
||||
:form-type="props.formType === 'button' ? undefined : props.formType"
|
||||
:open-type="props.disabled || props.loading ? undefined : props.openType"
|
||||
:hover-class="props.hoverClass"
|
||||
:hover-start-time="props.hoverStartTime"
|
||||
:hover-stay-time="props.hoverStayTime"
|
||||
hover-stop-propagation
|
||||
:lang="props.lang"
|
||||
:session-from="props.sessionFrom"
|
||||
:send-message-title="props.sendMessageTitle"
|
||||
:send-message-path="props.sendMessagePath"
|
||||
:send-message-img="props.sendMessageImg"
|
||||
:show-message-card="props.showMessageCard"
|
||||
:group-id="props.groupId"
|
||||
:guild-id="props.guildId"
|
||||
:public-id="props.publicId"
|
||||
:data-im-id="props.dataImId"
|
||||
:data-im-type="props.dataImType"
|
||||
:data-goods-id="props.dataGoodsId"
|
||||
:data-order-id="props.dataOrderId"
|
||||
:data-biz-line="props.dataBizLine"
|
||||
@click="handleClick"
|
||||
@getphonenumber="emit('getphonenumber', $event)"
|
||||
@getuserinfo="emit('getuserinfo', $event)"
|
||||
@error="emit('error', $event)"
|
||||
@opensetting="emit('opensetting', $event)"
|
||||
@addgroupapp="emit('addgroupapp', $event)"
|
||||
@chooseaddress="emit('chooseaddress', $event)"
|
||||
@chooseavatar="emit('chooseavatar', $event)"
|
||||
@chooseinvoicetitle="emit('chooseinvoicetitle', $event)"
|
||||
@launchapp="emit('launchapp', $event)"
|
||||
@login="emit('login', $event)"
|
||||
@subscribe="emit('subscribe', $event)"
|
||||
@contact="emit('contact', $event)"
|
||||
@agreeprivacyauthorization="emit('agreeprivacyauthorization', $event)"
|
||||
@im="emit('im', $event)"
|
||||
>
|
||||
<view class="nut-button__wrap">
|
||||
<Icon v-if="loading" name="loading" class="nut-icon-loading" />
|
||||
<slot v-if="$slots.icon && !loading" name="icon" />
|
||||
<view v-if="$slots.default" :class="{ 'nut-button__text': $slots.icon || loading }">
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './index';
|
||||
</style>
|
||||
292
uni_modules/nutui-uni/components/button/index.scss
Normal file
292
uni_modules/nutui-uni/components/button/index.scss
Normal file
@@ -0,0 +1,292 @@
|
||||
.nut-theme-dark {
|
||||
.nut-button {
|
||||
&--default {
|
||||
color: $dark-color3;
|
||||
background: $dark-background2;
|
||||
border: $button-border-width solid $dark-background2;
|
||||
}
|
||||
|
||||
&--plain {
|
||||
background: $dark-background2;
|
||||
}
|
||||
|
||||
&:not(.nut-button--hovercls) {
|
||||
.nut-button--plain:not([disabled]):active {
|
||||
background: $dark-background2;
|
||||
}
|
||||
|
||||
.nut-button--default:not([disabled]):active {
|
||||
color: $dark-color3;
|
||||
background: $dark-background2;
|
||||
border: $button-border-width solid $dark-background2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nut-button {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
width: auto;
|
||||
height: $button-default-height;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: $button-default-font-size;
|
||||
line-height: $button-default-line-height;
|
||||
text-align: center;
|
||||
vertical-align: bottom;
|
||||
appearance: none;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: opacity 0.2s;
|
||||
-webkit-tap-highlight-color: rgb(0 0 0 / 0%);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
|
||||
.nut-button__text {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
content: "";
|
||||
background-color: $black;
|
||||
border: inherit;
|
||||
border-color: $black;
|
||||
border-radius: inherit;
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:not(.nut-button--hovercls) {
|
||||
&:active::before {
|
||||
opacity: 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&--loading,
|
||||
&--disabled {
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&--default {
|
||||
color: $button-default-color;
|
||||
background: $button-default-bg-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid $button-default-border-color;
|
||||
}
|
||||
|
||||
&--primary {
|
||||
color: $button-primary-color;
|
||||
background: $button-primary-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
&--info {
|
||||
color: $button-info-color;
|
||||
background: $button-info-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
&--success {
|
||||
color: $button-success-color;
|
||||
background: $button-success-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
&--danger {
|
||||
color: $button-danger-color;
|
||||
background: $button-danger-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
&--warning {
|
||||
color: $button-warning-color;
|
||||
background: $button-warning-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
&--plain {
|
||||
background: $button-plain-background-color;
|
||||
background-origin: border-box;
|
||||
|
||||
&.nut-button--primary {
|
||||
color: $button-primary-border-color;
|
||||
border-color: $button-primary-border-color;
|
||||
}
|
||||
|
||||
&.nut-button--info {
|
||||
color: $button-info-border-color;
|
||||
border-color: $button-info-border-color;
|
||||
}
|
||||
|
||||
&.nut-button--success {
|
||||
color: $button-success-border-color;
|
||||
border-color: $button-success-border-color;
|
||||
}
|
||||
|
||||
&.nut-button--danger {
|
||||
color: $button-danger-border-color;
|
||||
border-color: $button-danger-border-color;
|
||||
}
|
||||
|
||||
&.nut-button--warning {
|
||||
color: $button-warning-border-color;
|
||||
border-color: $button-warning-border-color;
|
||||
}
|
||||
|
||||
&:not(.nut-button--hovercls) {
|
||||
&.nut-button--primary:not([disabled]):active {
|
||||
color: $button-primary-border-color;
|
||||
border-color: $button-primary-border-color;
|
||||
}
|
||||
|
||||
&.nut-button--info:not([disabled]):active {
|
||||
color: $button-info-border-color;
|
||||
border-color: $button-info-border-color;
|
||||
}
|
||||
|
||||
&.nut-button--success:not([disabled]):active {
|
||||
color: $button-success-border-color;
|
||||
border-color: $button-success-border-color;
|
||||
}
|
||||
|
||||
&.nut-button--danger:not([disabled]):active {
|
||||
color: $button-danger-border-color;
|
||||
border-color: $button-danger-border-color;
|
||||
}
|
||||
|
||||
&.nut-button--warning:not([disabled]):active {
|
||||
color: $button-warning-border-color;
|
||||
border-color: $button-warning-border-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--large {
|
||||
width: 100%;
|
||||
height: $button-large-height;
|
||||
font-size: $button-large-font-size;
|
||||
line-height: $button-large-line-height;
|
||||
}
|
||||
|
||||
&--normal {
|
||||
padding: $button-default-padding;
|
||||
font-size: $button-default-font-size;
|
||||
}
|
||||
|
||||
&--small {
|
||||
height: $button-small-height;
|
||||
padding: $button-small-padding;
|
||||
font-size: $button-small-font-size;
|
||||
line-height: $button-small-line-height;
|
||||
|
||||
&.nut-button--round {
|
||||
border-radius: $button-small-round-border-radius;
|
||||
}
|
||||
}
|
||||
|
||||
&--mini {
|
||||
height: $button-mini-height;
|
||||
padding: $button-mini-padding;
|
||||
font-size: $button-mini-font-size;
|
||||
line-height: $button-mini-line-height;
|
||||
}
|
||||
|
||||
&--block {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: $button-disabled-opacity;
|
||||
}
|
||||
|
||||
&--loading {
|
||||
cursor: default;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&--round {
|
||||
border-radius: $button-border-radius;
|
||||
}
|
||||
|
||||
&--square {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&:not(.nut-button--hovercls) {
|
||||
.nut-button--default:not([disabled]):active {
|
||||
color: $button-default-color;
|
||||
background: $button-default-bg-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid $button-default-border-color;
|
||||
}
|
||||
|
||||
.nut-button--primary:not([disabled]):active {
|
||||
color: $button-primary-color;
|
||||
background: $button-primary-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
.nut-button--info:not([disabled]):active {
|
||||
color: $button-info-color;
|
||||
background: $button-info-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
.nut-button--success:not([disabled]):active {
|
||||
color: $button-success-color;
|
||||
background: $button-success-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
.nut-button--danger:not([disabled]):active {
|
||||
color: $button-danger-color;
|
||||
background: $button-danger-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
.nut-button--warning:not([disabled]):active {
|
||||
color: $button-warning-color;
|
||||
background: $button-warning-background-color;
|
||||
background-origin: border-box;
|
||||
border: $button-border-width solid transparent;
|
||||
}
|
||||
|
||||
.nut-button--plain:not([disabled]):active {
|
||||
background: $button-plain-background-color;
|
||||
background-origin: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
uni_modules/nutui-uni/components/button/index.ts
Normal file
2
uni_modules/nutui-uni/components/button/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './button'
|
||||
export * from './type'
|
||||
8
uni_modules/nutui-uni/components/button/type.ts
Normal file
8
uni_modules/nutui-uni/components/button/type.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export const buttonType = ['default', 'primary', 'info', 'success', 'warning', 'danger'] as const
|
||||
export type ButtonType = (typeof buttonType)[number]
|
||||
export const buttonSize = ['large', 'normal', 'small', 'mini'] as const
|
||||
export type ButtonSize = (typeof buttonSize)[number]
|
||||
export const buttonShape = ['square', 'round'] as const
|
||||
export type ButtonShape = (typeof buttonShape)[number]
|
||||
export const buttonFormType = ['button', 'submit', 'reset'] as const
|
||||
export type ButtonFormType = (typeof buttonFormType)[number]
|
||||
Reference in New Issue
Block a user