tang-ui-x 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/TActionSheet/index.uvue +80 -56
- package/components/TActionSheet/type.uts +13 -13
- package/components/TAvatar/index.uvue +60 -33
- package/components/TAvatar/type.uts +16 -10
- package/components/TBadge/index.uvue +73 -64
- package/components/TBadge/type.uts +2 -2
- package/components/TButton/index.uvue +19 -12
- package/components/TButton/type.uts +1 -1
- package/components/TCard/index.uvue +69 -50
- package/components/TCell/index.uvue +10 -0
- package/components/TCell/type.uts +1 -1
- package/components/TCheckbox/index.uvue +31 -12
- package/components/TCheckbox/type.uts +2 -2
- package/components/TCheckboxGroup/index.uvue +64 -39
- package/components/TCheckboxGroup/type.uts +2 -2
- package/components/TCol/index.uvue +6 -6
- package/components/TCol/type.uts +1 -1
- package/components/TCollapse/index.uvue +16 -16
- package/components/TCollapseItem/index.uvue +12 -12
- package/components/TDateTimePicker/index.uvue +282 -145
- package/components/TDateTimePicker/type.uts +26 -8
- package/components/TDialog/index.uvue +86 -50
- package/components/TDivider/index.uvue +21 -17
- package/components/TDivider/type.uts +1 -1
- package/components/TEmpty/index.uvue +41 -25
- package/components/TEmpty/type.uts +1 -1
- package/components/TErrorState/index.uvue +4 -4
- package/components/TErrorState/type.uts +1 -1
- package/components/TForm/index.uvue +420 -243
- package/components/TForm/type.uts +3 -3
- package/components/TGrid/index.uvue +65 -18
- package/components/TGrid/type.uts +1 -1
- package/components/TGridItem/index.uvue +108 -77
- package/components/TGridItem/type.uts +1 -1
- package/components/TIcon/index.uvue +15 -15
- package/components/TIcon/type.uts +9 -3
- package/components/TImage/index.uvue +69 -58
- package/components/TImage/type.uts +19 -14
- package/components/TInput/index.uvue +127 -106
- package/components/TInput/type.uts +1 -1
- package/components/TList/index.uvue +3 -3
- package/components/TListItem/index.uvue +31 -31
- package/components/TLoading/index.uvue +16 -13
- package/components/TNavBar/index.uvue +22 -10
- package/components/TNavBar/type.uts +1 -1
- package/components/TNoticeBar/index.uvue +33 -33
- package/components/TNoticeBar/type.uts +2 -2
- package/components/TNumberInput/index.uvue +106 -72
- package/components/TNumberInput/type.uts +1 -1
- package/components/TPicker/index.uvue +101 -72
- package/components/TPicker/type.uts +33 -30
- package/components/TPopup/index.uvue +140 -81
- package/components/TPopup/type.uts +7 -1
- package/components/TProgress/index.uvue +37 -34
- package/components/TProgress/type.uts +1 -1
- package/components/TRadioButton/index.uvue +73 -43
- package/components/TRadioButton/type.uts +4 -3
- package/components/TRadioGroup/index.uvue +48 -42
- package/components/TRadioGroup/type.uts +7 -7
- package/components/TRate/index.uvue +86 -82
- package/components/TRate/type.uts +1 -1
- package/components/TRow/index.uvue +6 -6
- package/components/TRow/type.uts +1 -1
- package/components/TSearchBar/index.uvue +92 -60
- package/components/TSearchBar/type.uts +18 -17
- package/components/TSelect/index.uvue +574 -340
- package/components/TSelect/type.uts +4 -4
- package/components/TSlider/index.uvue +26 -7
- package/components/TSlider/type.uts +1 -1
- package/components/TSwiper/index.uvue +25 -20
- package/components/TSwitch/index.uvue +46 -22
- package/components/TText/README.md +7 -7
- package/components/TText/index.uvue +97 -81
- package/components/TText/type.uts +6 -6
- package/components/TTextarea/index.uvue +61 -53
- package/components/TTextarea/type.uts +11 -11
- package/components/Tabs/README.md +4 -4
- package/components/Tabs/index.uvue +125 -101
- package/components/Tabs/type.uts +4 -4
- package/components/Tags/README.md +4 -4
- package/components/Tags/index.uvue +163 -133
- package/components/Tags/type.uts +3 -3
- package/composables/i18n/manager.uts +97 -103
- package/composables/i18n/types.uts +5 -5
- package/composables/useI18n.uts +78 -71
- package/composables/useModal.uts +21 -5
- package/composables/useTheme.uts +264 -296
- package/composables/useToast.uts +165 -147
- package/index.uts +1 -2
- package/locales/en-US/actionSheet.json +2 -2
- package/locales/en-US/common.json +16 -16
- package/locales/en-US/dialog.json +4 -4
- package/locales/en-US/empty.json +5 -5
- package/locales/en-US/errorState.json +4 -4
- package/locales/en-US/examplePages.json +15 -12
- package/locales/en-US/examples.json +222 -222
- package/locales/en-US/form.json +20 -20
- package/locales/en-US/input.json +2 -2
- package/locales/en-US/list.json +4 -4
- package/locales/en-US/loading.json +2 -2
- package/locales/en-US/navBar.json +3 -3
- package/locales/en-US/noticeBar.json +2 -2
- package/locales/en-US/picker.json +4 -4
- package/locales/en-US/searchBar.json +3 -3
- package/locales/en-US/textarea.json +2 -2
- package/locales/en-US/toast.json +5 -5
- package/locales/index.uts +75 -76
- package/locales/loader.uts +255 -258
- package/locales/zh-CN/actionSheet.json +2 -2
- package/locales/zh-CN/common.json +16 -16
- package/locales/zh-CN/dialog.json +4 -4
- package/locales/zh-CN/empty.json +5 -5
- package/locales/zh-CN/errorState.json +4 -4
- package/locales/zh-CN/examplePages.json +15 -12
- package/locales/zh-CN/examples.json +222 -222
- package/locales/zh-CN/form.json +20 -20
- package/locales/zh-CN/input.json +2 -2
- package/locales/zh-CN/list.json +4 -4
- package/locales/zh-CN/loading.json +2 -2
- package/locales/zh-CN/navBar.json +3 -3
- package/locales/zh-CN/noticeBar.json +2 -2
- package/locales/zh-CN/picker.json +4 -4
- package/locales/zh-CN/searchBar.json +3 -3
- package/locales/zh-CN/textarea.json +2 -2
- package/locales/zh-CN/toast.json +5 -5
- package/locales/zh-TW/actionSheet.json +2 -2
- package/locales/zh-TW/common.json +14 -14
- package/locales/zh-TW/dialog.json +4 -4
- package/locales/zh-TW/empty.json +5 -5
- package/locales/zh-TW/errorState.json +4 -4
- package/locales/zh-TW/examplePages.json +700 -698
- package/locales/zh-TW/examples.json +222 -222
- package/locales/zh-TW/form.json +17 -17
- package/locales/zh-TW/input.json +2 -2
- package/locales/zh-TW/list.json +4 -4
- package/locales/zh-TW/loading.json +2 -2
- package/locales/zh-TW/navBar.json +3 -3
- package/locales/zh-TW/noticeBar.json +2 -2
- package/locales/zh-TW/picker.json +4 -4
- package/locales/zh-TW/searchBar.json +3 -3
- package/locales/zh-TW/textarea.json +2 -2
- package/locales/zh-TW/toast.json +5 -5
- package/package.json +47 -15
- package/static/logo.png +0 -0
- package/static/tailwind.css +752 -1550
- package/static/theme.scss +35 -197
- package/types/index.uts +19 -6
- package/uni.scss +0 -2
- package/utils/color.uts +0 -92
- package/utils/common.uts +0 -245
- package/utils/dom.uts +0 -275
- package/utils/index.uts +0 -11
- package/utils/request/index.uts +0 -375
- package/utils/request/type.uts +0 -87
- package/utils/validator.uts +0 -155
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
<script setup lang="uts">
|
|
2
|
-
import { computed } from 'vue'
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
<script setup lang="uts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import type { Ref } from 'vue'
|
|
4
|
+
import TPopup from '../TPopup/index.uvue'
|
|
5
|
+
import type { ActionSheetAction } from './type.uts'
|
|
5
6
|
import { useI18n } from '../../composables/useI18n.uts'
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -9,10 +10,18 @@ import { useI18n } from '../../composables/useI18n.uts'
|
|
|
9
10
|
* @description 底部弹出的动作菜单,基于 TPopup 组件实现
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
type ActionSheetViewProps = {
|
|
14
|
+
actions?: ActionSheetAction[]
|
|
15
|
+
title?: string
|
|
16
|
+
description?: string
|
|
17
|
+
cancelText?: string
|
|
18
|
+
closeOnClickAction?: boolean
|
|
19
|
+
closeOnClickOverlay?: boolean
|
|
20
|
+
customClass?: string
|
|
21
|
+
customStyle?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const props = withDefaults(defineProps<ActionSheetViewProps>(), {
|
|
16
25
|
actions: () => [] as ActionSheetAction[],
|
|
17
26
|
title: '',
|
|
18
27
|
description: '',
|
|
@@ -22,8 +31,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
22
31
|
customStyle: ''
|
|
23
32
|
})
|
|
24
33
|
|
|
25
|
-
// 使用 defineModel 管理显示状态 (v-model)
|
|
26
|
-
const visible = defineModel({ default: false })
|
|
34
|
+
// 使用 defineModel 管理显示状态 (v-model)
|
|
35
|
+
const visible = defineModel({ default: false }) as Ref<boolean>
|
|
27
36
|
|
|
28
37
|
const emit = defineEmits<{
|
|
29
38
|
select: [action: ActionSheetAction, index: number]
|
|
@@ -34,39 +43,58 @@ const emit = defineEmits<{
|
|
|
34
43
|
// 使用 i18n
|
|
35
44
|
const { $t } = useI18n()
|
|
36
45
|
|
|
37
|
-
const hasTextValue = (value: string | null
|
|
38
|
-
return value !==
|
|
46
|
+
const hasTextValue = (value: string | null): boolean => {
|
|
47
|
+
return value !== null && value !== ''
|
|
39
48
|
}
|
|
40
49
|
|
|
41
|
-
const hasTitle = computed(() => {
|
|
50
|
+
const hasTitle = computed((): boolean => {
|
|
42
51
|
return hasTextValue(props.title)
|
|
43
52
|
})
|
|
44
53
|
|
|
45
|
-
const hasDescription = computed(() => {
|
|
54
|
+
const hasDescription = computed((): boolean => {
|
|
46
55
|
return hasTextValue(props.description)
|
|
47
56
|
})
|
|
48
57
|
|
|
49
|
-
const showHeader = computed(() => {
|
|
58
|
+
const showHeader = computed((): boolean => {
|
|
50
59
|
return hasTitle.value || hasDescription.value
|
|
51
60
|
})
|
|
52
|
-
|
|
53
|
-
// 优先使用用户传入的值,否则使用翻译
|
|
54
|
-
const displayCancelText = computed(() => {
|
|
55
|
-
// 如果用户明确传入了 cancelText(即使是空字符串),使用用户的值
|
|
56
|
-
// 否则使用翻译
|
|
57
|
-
return props.cancelText !==
|
|
58
|
-
? props.cancelText
|
|
59
|
-
: $t('actionSheet.cancelText')
|
|
60
|
-
})
|
|
61
|
+
|
|
62
|
+
// 优先使用用户传入的值,否则使用翻译
|
|
63
|
+
const displayCancelText = computed((): string => {
|
|
64
|
+
// 如果用户明确传入了 cancelText(即使是空字符串),使用用户的值
|
|
65
|
+
// 否则使用翻译
|
|
66
|
+
return props.cancelText !== null && props.cancelText !== ''
|
|
67
|
+
? props.cancelText as string
|
|
68
|
+
: $t('actionSheet.cancelText', {})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
const canCloseOnClickAction = computed((): boolean => {
|
|
72
|
+
return props.closeOnClickAction == true
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const getActionClass = (action: ActionSheetAction): string => {
|
|
76
|
+
let className = 't-action-sheet__action flex items-center justify-center border-b border-border-soft p-4 text-center'
|
|
77
|
+
if (action.disabled == true || action.loading == true) {
|
|
78
|
+
className = className + ' opacity-50'
|
|
79
|
+
}
|
|
80
|
+
return className
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const getActionTextStyle = (action: ActionSheetAction): string => {
|
|
84
|
+
if (action.color !== null && action.color !== '') {
|
|
85
|
+
return `color: ${action.color}`
|
|
86
|
+
}
|
|
87
|
+
return ''
|
|
88
|
+
}
|
|
61
89
|
|
|
62
90
|
const handleSelect = (action: ActionSheetAction, index: number): void => {
|
|
63
|
-
if (action.disabled || action.loading) return
|
|
64
|
-
|
|
65
|
-
emit('select', action, index)
|
|
66
|
-
if (
|
|
67
|
-
visible.value = false
|
|
68
|
-
}
|
|
69
|
-
}
|
|
91
|
+
if (action.disabled == true || action.loading == true) return
|
|
92
|
+
|
|
93
|
+
emit('select', action, index)
|
|
94
|
+
if (canCloseOnClickAction.value) {
|
|
95
|
+
visible.value = false
|
|
96
|
+
}
|
|
97
|
+
}
|
|
70
98
|
|
|
71
99
|
const handleCancel = (): void => {
|
|
72
100
|
emit('cancel')
|
|
@@ -91,36 +119,32 @@ const handleClose = (): void => {
|
|
|
91
119
|
>
|
|
92
120
|
<view class="t-action-sheet bg-transparent p-0" :class="customClass" :style="customStyle">
|
|
93
121
|
<!-- 头部:标题和描述 -->
|
|
94
|
-
<view v-if="showHeader" class="t-action-sheet__header border-b border-
|
|
95
|
-
<text v-if="hasTitle" class="t-action-sheet__title mb-2
|
|
96
|
-
<text v-if="hasDescription" class="t-action-sheet__description
|
|
122
|
+
<view v-if="showHeader" class="t-action-sheet__header border-b border-border-soft p-4 text-center">
|
|
123
|
+
<text v-if="hasTitle" class="t-action-sheet__title mb-2 text-base font-medium text-title">{{ title }}</text>
|
|
124
|
+
<text v-if="hasDescription" class="t-action-sheet__description text-sm text-desc">{{ description }}</text>
|
|
97
125
|
</view>
|
|
98
|
-
|
|
99
|
-
<!-- 操作列表 -->
|
|
100
|
-
<view class="t-action-sheet__actions max-h-
|
|
101
|
-
<view
|
|
102
|
-
v-for="(action, index) in actions"
|
|
103
|
-
:key="index"
|
|
104
|
-
class="
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<text
|
|
112
|
-
class="t-action-sheet__action-text text-base text-[#323233]"
|
|
113
|
-
:style="action.color ? `color: ${action.color}` : ''"
|
|
114
|
-
>
|
|
126
|
+
|
|
127
|
+
<!-- 操作列表 -->
|
|
128
|
+
<view class="t-action-sheet__actions max-h-actions overflow-y-auto">
|
|
129
|
+
<view
|
|
130
|
+
v-for="(action, index) in actions"
|
|
131
|
+
:key="index"
|
|
132
|
+
:class="getActionClass(action)"
|
|
133
|
+
@click="handleSelect(action, index)"
|
|
134
|
+
>
|
|
135
|
+
<text
|
|
136
|
+
class="t-action-sheet__action-text text-base text-title"
|
|
137
|
+
:style="getActionTextStyle(action)"
|
|
138
|
+
>
|
|
115
139
|
{{ action.name }}
|
|
116
140
|
</text>
|
|
117
141
|
</view>
|
|
118
142
|
</view>
|
|
119
|
-
|
|
120
|
-
<!-- 取消按钮 -->
|
|
121
|
-
<view class="t-action-sheet__cancel flex items-center justify-center border-t-
|
|
122
|
-
<text class="t-action-sheet__cancel-text text-base text-
|
|
123
|
-
</view>
|
|
143
|
+
|
|
144
|
+
<!-- 取消按钮 -->
|
|
145
|
+
<view class="t-action-sheet__cancel flex items-center justify-center border-t-8 border-action-divider p-4 text-center" @click="handleCancel">
|
|
146
|
+
<text class="t-action-sheet__cancel-text text-base text-title">{{ displayCancelText }}</text>
|
|
147
|
+
</view>
|
|
124
148
|
</view>
|
|
125
149
|
</TPopup>
|
|
126
150
|
</template>
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* TActionSheet 组件类型定义
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
name: string
|
|
7
|
-
color?: string
|
|
8
|
-
disabled?: boolean
|
|
9
|
-
loading?: boolean
|
|
10
|
-
}
|
|
5
|
+
export type ActionSheetAction = {
|
|
6
|
+
name: string
|
|
7
|
+
color?: string
|
|
8
|
+
disabled?: boolean
|
|
9
|
+
loading?: boolean
|
|
10
|
+
}
|
|
11
11
|
|
|
12
|
-
export
|
|
12
|
+
export type TActionSheetProps = {
|
|
13
13
|
show?: boolean
|
|
14
14
|
actions?: ActionSheetAction[]
|
|
15
15
|
title?: string
|
|
@@ -21,9 +21,9 @@ export interface TActionSheetProps {
|
|
|
21
21
|
customStyle?: string
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export
|
|
25
|
-
'update:show': (value: boolean) => void
|
|
26
|
-
select: (action: ActionSheetAction, index: number) => void
|
|
27
|
-
cancel: () => void
|
|
28
|
-
close: () => void
|
|
29
|
-
}
|
|
24
|
+
export type TActionSheetEmits = {
|
|
25
|
+
'update:show': (value: boolean) => void
|
|
26
|
+
select: (action: ActionSheetAction, index: number) => void
|
|
27
|
+
cancel: () => void
|
|
28
|
+
close: () => void
|
|
29
|
+
}
|
|
@@ -8,11 +8,12 @@ import type { TAvatarProps } from './type.uts'
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
// 定义 props
|
|
11
|
-
const props = withDefaults(defineProps<TAvatarProps>(), {
|
|
12
|
-
src: '',
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
const props = withDefaults(defineProps<TAvatarProps>(), {
|
|
12
|
+
src: '',
|
|
13
|
+
errorImage: '',
|
|
14
|
+
size: 'medium',
|
|
15
|
+
shape: 'circle',
|
|
16
|
+
alt: '',
|
|
16
17
|
bgColor: 'var(--tui-border-strong)',
|
|
17
18
|
color: 'var(--tui-text-inverse)',
|
|
18
19
|
fit: 'cover'
|
|
@@ -23,48 +24,62 @@ const emit = defineEmits<{
|
|
|
23
24
|
click: []
|
|
24
25
|
error: []
|
|
25
26
|
}>()
|
|
26
|
-
|
|
27
|
+
|
|
27
28
|
// 图片加载失败标记
|
|
28
29
|
const hasLoadError = ref(false)
|
|
30
|
+
const hasErrorImageLoadError = ref(false)
|
|
29
31
|
|
|
30
|
-
const hasTextValue = (value: string | null
|
|
31
|
-
return value !==
|
|
32
|
+
const hasTextValue = (value: string | null): boolean => {
|
|
33
|
+
return value !== null && value !== ''
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
const hasSrc = computed(() => {
|
|
35
37
|
return hasTextValue(props.src)
|
|
36
38
|
})
|
|
37
39
|
|
|
40
|
+
const hasErrorImage = computed(() => {
|
|
41
|
+
return hasTextValue(props.errorImage)
|
|
42
|
+
})
|
|
43
|
+
|
|
38
44
|
const hasAlt = computed(() => {
|
|
39
45
|
return hasTextValue(props.alt)
|
|
40
46
|
})
|
|
47
|
+
|
|
48
|
+
const displaySrc = computed((): string => {
|
|
49
|
+
if (hasSrc.value && !hasLoadError.value) {
|
|
50
|
+
return props.src
|
|
51
|
+
}
|
|
52
|
+
if (hasErrorImage.value && !hasErrorImageLoadError.value) {
|
|
53
|
+
return props.errorImage
|
|
54
|
+
}
|
|
55
|
+
return ''
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const hasDisplaySrc = computed((): boolean => {
|
|
59
|
+
return hasTextValue(displaySrc.value)
|
|
60
|
+
})
|
|
41
61
|
|
|
42
62
|
/**
|
|
43
63
|
* 计算头像大小
|
|
44
64
|
*/
|
|
45
|
-
const avatarSize = computed(() => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const sizeMap = {
|
|
51
|
-
small: 32,
|
|
52
|
-
medium: 40,
|
|
53
|
-
large: 56
|
|
65
|
+
const avatarSize = computed((): number => {
|
|
66
|
+
const size = props.size
|
|
67
|
+
if (typeof size === 'number') {
|
|
68
|
+
return size as number
|
|
54
69
|
}
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
if (
|
|
58
|
-
return
|
|
70
|
+
|
|
71
|
+
if (size == 'small') return 32
|
|
72
|
+
if (size == 'large') return 56
|
|
73
|
+
return 40
|
|
59
74
|
})
|
|
60
75
|
|
|
61
76
|
/**
|
|
62
77
|
* 计算头像样式类
|
|
63
78
|
*/
|
|
64
|
-
const avatarClass = computed(() => {
|
|
65
|
-
const classes: string[] = ['t-avatar
|
|
66
|
-
|
|
67
|
-
if (props.shape
|
|
79
|
+
const avatarClass = computed((): string => {
|
|
80
|
+
const classes: string[] = ['t-avatar flex items-center justify-center overflow-hidden relative']
|
|
81
|
+
|
|
82
|
+
if (props.shape == 'square') {
|
|
68
83
|
classes.push('rounded')
|
|
69
84
|
} else {
|
|
70
85
|
classes.push('rounded-full')
|
|
@@ -83,7 +98,7 @@ const avatarStyle = computed(() => {
|
|
|
83
98
|
styles.push(`width: ${size}px`)
|
|
84
99
|
styles.push(`height: ${size}px`)
|
|
85
100
|
|
|
86
|
-
if (!
|
|
101
|
+
if (!hasDisplaySrc.value) {
|
|
87
102
|
styles.push(`background-color: ${props.bgColor}`)
|
|
88
103
|
}
|
|
89
104
|
|
|
@@ -112,10 +127,22 @@ const handleClick = (): void => {
|
|
|
112
127
|
/**
|
|
113
128
|
* 处理图片加载失败
|
|
114
129
|
*/
|
|
115
|
-
const handleError = (): void => {
|
|
116
|
-
hasLoadError.value = true
|
|
117
|
-
emit('error')
|
|
118
|
-
}
|
|
130
|
+
const handleError = (): void => {
|
|
131
|
+
hasLoadError.value = true
|
|
132
|
+
emit('error')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const handleErrorImageError = (): void => {
|
|
136
|
+
hasErrorImageLoadError.value = true
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const handleImageError = (): void => {
|
|
140
|
+
if (hasLoadError.value) {
|
|
141
|
+
handleErrorImageError()
|
|
142
|
+
} else {
|
|
143
|
+
handleError()
|
|
144
|
+
}
|
|
145
|
+
}
|
|
119
146
|
|
|
120
147
|
/**
|
|
121
148
|
* 获取显示的文字(取首字符)
|
|
@@ -131,11 +158,11 @@ const displayText = computed(() => {
|
|
|
131
158
|
<template>
|
|
132
159
|
<view :class="avatarClass" :style="avatarStyle" @click="handleClick">
|
|
133
160
|
<image
|
|
134
|
-
v-if="
|
|
161
|
+
v-if="hasDisplaySrc"
|
|
135
162
|
class="t-avatar__image h-full w-full"
|
|
136
|
-
:src="
|
|
163
|
+
:src="displaySrc"
|
|
137
164
|
:mode="fit"
|
|
138
|
-
@error="
|
|
165
|
+
@error="handleImageError"
|
|
139
166
|
/>
|
|
140
167
|
<text v-else-if="hasAlt" class="t-avatar__text text-center font-medium" :style="textStyle">
|
|
141
168
|
{{ displayText }}
|
|
@@ -2,15 +2,21 @@
|
|
|
2
2
|
* TAvatar 头像组件属性类型定义
|
|
3
3
|
*/
|
|
4
4
|
export type TAvatarProps = {
|
|
5
|
-
/**
|
|
6
|
-
* 头像图片地址
|
|
7
|
-
*/
|
|
8
|
-
src?: string
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
* @default "
|
|
13
|
-
*/
|
|
5
|
+
/**
|
|
6
|
+
* 头像图片地址
|
|
7
|
+
*/
|
|
8
|
+
src?: string
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 图片加载失败时显示的兜底图片地址
|
|
12
|
+
* @default ""
|
|
13
|
+
*/
|
|
14
|
+
errorImage?: string
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 头像大小
|
|
18
|
+
* @default "medium"
|
|
19
|
+
*/
|
|
14
20
|
size?: 'small' | 'medium' | 'large' | number
|
|
15
21
|
|
|
16
22
|
/**
|
|
@@ -51,4 +57,4 @@ export type TAvatarEmits = {
|
|
|
51
57
|
* 图片加载失败时触发
|
|
52
58
|
*/
|
|
53
59
|
error: () => void
|
|
54
|
-
}
|
|
60
|
+
}
|
|
@@ -16,14 +16,14 @@ const props = withDefaults(defineProps<TBadgeProps>(), {
|
|
|
16
16
|
type: 'danger',
|
|
17
17
|
bgColor: '',
|
|
18
18
|
color: '',
|
|
19
|
-
offset: ()
|
|
19
|
+
offset: () : number[] => [0, 0]
|
|
20
20
|
})
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* 计算显示的内容
|
|
24
24
|
*/
|
|
25
|
-
const displayValue = computed(() => {
|
|
26
|
-
if (props.isDot) {
|
|
25
|
+
const displayValue = computed((): string => {
|
|
26
|
+
if (props.isDot == true) {
|
|
27
27
|
return ''
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -32,82 +32,91 @@ const displayValue = computed(() => {
|
|
|
32
32
|
return `${props.max}+`
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
return
|
|
35
|
+
return val !== null ? val.toString() : ''
|
|
36
36
|
})
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* 计算徽标样式类
|
|
40
40
|
*/
|
|
41
|
-
const badgeClass = computed(() => {
|
|
42
|
-
const classes: string[] = [
|
|
43
|
-
't-badge__content absolute right-0 -top-3 z-
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
if (props.isDot) {
|
|
47
|
-
classes.push('h-2 w-2 rounded-full p-0')
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
case '
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
default:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return classes.join(' ')
|
|
69
|
-
})
|
|
41
|
+
const badgeClass = computed((): string => {
|
|
42
|
+
const classes: string[] = [
|
|
43
|
+
't-badge__content absolute right-0 -top-3 z-10 translate-x-1/2 -translate-y-1/2 whitespace-nowrap rounded-lg px-2 py-1 text-xs leading-relaxed',
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
if (props.isDot == true) {
|
|
47
|
+
classes.push('h-2 w-2 rounded-full p-0')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return classes.join(' ')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const getTypeBackgroundColor = (): string => {
|
|
54
|
+
switch (props.type) {
|
|
55
|
+
case 'primary':
|
|
56
|
+
return '#3b82f6'
|
|
57
|
+
case 'success':
|
|
58
|
+
return '#22c55e'
|
|
59
|
+
case 'warning':
|
|
60
|
+
return '#fb923c'
|
|
61
|
+
case 'info':
|
|
62
|
+
return '#909399'
|
|
63
|
+
default:
|
|
64
|
+
return '#f87171'
|
|
65
|
+
}
|
|
66
|
+
}
|
|
70
67
|
|
|
71
68
|
/**
|
|
72
69
|
* 计算徽标样式
|
|
73
70
|
*/
|
|
74
|
-
const badgeStyle = computed(() => {
|
|
75
|
-
const styles: string[] = []
|
|
76
|
-
|
|
77
|
-
if (props.bgColor != '') {
|
|
78
|
-
styles.push(`background-color: ${props.bgColor}`)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
})
|
|
71
|
+
const badgeStyle = computed((): string => {
|
|
72
|
+
const styles: string[] = []
|
|
73
|
+
|
|
74
|
+
if (props.bgColor != '') {
|
|
75
|
+
styles.push(`background-color: ${props.bgColor}`)
|
|
76
|
+
} else {
|
|
77
|
+
styles.push(`background-color: ${getTypeBackgroundColor()}`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (props.color != '') {
|
|
81
|
+
styles.push(`color: ${props.color}`)
|
|
82
|
+
} else {
|
|
83
|
+
styles.push('color: #ffffff')
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (props.offset != null && props.offset.length == 2) {
|
|
87
|
+
const x = props.offset[0] as number
|
|
88
|
+
const y = props.offset[1] as number
|
|
89
|
+
if (x != 0) {
|
|
90
|
+
styles.push(`right: ${-x}px`)
|
|
91
|
+
}
|
|
92
|
+
if (y != 0) {
|
|
93
|
+
styles.push(`top: ${y}px`)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return styles.join('; ')
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
const badgeTextStyle = computed((): string => {
|
|
101
|
+
if (props.color != '') {
|
|
102
|
+
return `color: ${props.color}`
|
|
103
|
+
}
|
|
104
|
+
return 'color: #ffffff'
|
|
105
|
+
})
|
|
97
106
|
|
|
98
107
|
/**
|
|
99
108
|
* 是否显示徽标
|
|
100
109
|
*/
|
|
101
|
-
const showBadge = computed(() => {
|
|
102
|
-
return
|
|
103
|
-
})
|
|
110
|
+
const showBadge = computed((): boolean => {
|
|
111
|
+
return props.hidden != true && (props.isDot == true || (props.value != '' && props.value != 0))
|
|
112
|
+
})
|
|
104
113
|
</script>
|
|
105
114
|
|
|
106
115
|
<template>
|
|
107
116
|
<view class="t-badge relative inline-block overflow-visible">
|
|
108
117
|
<slot></slot>
|
|
109
|
-
<view v-if="showBadge" :class="badgeClass" :style="badgeStyle">
|
|
110
|
-
<text v-if="
|
|
111
|
-
</view>
|
|
112
|
-
</view>
|
|
113
|
-
</template>
|
|
118
|
+
<view v-if="showBadge" :class="badgeClass" :style="badgeStyle">
|
|
119
|
+
<text v-if="isDot != true" class="t-badge__text text-xs" :style="badgeTextStyle">{{ displayValue }}</text>
|
|
120
|
+
</view>
|
|
121
|
+
</view>
|
|
122
|
+
</template>
|
|
@@ -51,7 +51,7 @@ const buttonClasses = computed((): string => {
|
|
|
51
51
|
|
|
52
52
|
switch (props.shape) {
|
|
53
53
|
case 'round':
|
|
54
|
-
classes.push('rounded-
|
|
54
|
+
classes.push('rounded-full')
|
|
55
55
|
break
|
|
56
56
|
case 'circle':
|
|
57
57
|
classes.push('rounded-full p-0')
|
|
@@ -87,40 +87,40 @@ const buttonClasses = computed((): string => {
|
|
|
87
87
|
case 'primary':
|
|
88
88
|
classes.push(
|
|
89
89
|
props.plain
|
|
90
|
-
? 'border-
|
|
91
|
-
: 'border-
|
|
90
|
+
? 'border-blue-200 bg-blue-50 text-blue-500'
|
|
91
|
+
: 'border-blue-500 bg-blue-500 text-white'
|
|
92
92
|
)
|
|
93
93
|
break
|
|
94
94
|
case 'success':
|
|
95
95
|
classes.push(
|
|
96
96
|
props.plain
|
|
97
|
-
? 'border-
|
|
98
|
-
: 'border-
|
|
97
|
+
? 'border-green-200 bg-green-50 text-green-500'
|
|
98
|
+
: 'border-green-500 bg-green-500 text-white'
|
|
99
99
|
)
|
|
100
100
|
break
|
|
101
101
|
case 'warning':
|
|
102
102
|
classes.push(
|
|
103
103
|
props.plain
|
|
104
|
-
? 'border-
|
|
105
|
-
: 'border-
|
|
104
|
+
? 'border-orange-200 bg-orange-50 text-orange-400'
|
|
105
|
+
: 'border-orange-400 bg-orange-400 text-white'
|
|
106
106
|
)
|
|
107
107
|
break
|
|
108
108
|
case 'danger':
|
|
109
109
|
classes.push(
|
|
110
110
|
props.plain
|
|
111
|
-
? 'border-
|
|
112
|
-
: 'border-
|
|
111
|
+
? 'border-red-200 bg-red-50 text-red-400'
|
|
112
|
+
: 'border-red-400 bg-red-400 text-white'
|
|
113
113
|
)
|
|
114
114
|
break
|
|
115
115
|
case 'info':
|
|
116
116
|
classes.push(
|
|
117
117
|
props.plain
|
|
118
|
-
? 'border-
|
|
119
|
-
: 'border-
|
|
118
|
+
? 'border-zinc-300 bg-zinc-100 text-zinc-400'
|
|
119
|
+
: 'border-zinc-400 bg-zinc-400 text-white'
|
|
120
120
|
)
|
|
121
121
|
break
|
|
122
122
|
default:
|
|
123
|
-
classes.push('border-
|
|
123
|
+
classes.push('border-gray-300 bg-white text-gray-600')
|
|
124
124
|
break
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -185,3 +185,10 @@ const handleClick = () => {
|
|
|
185
185
|
</view>
|
|
186
186
|
</button>
|
|
187
187
|
</template>
|
|
188
|
+
|
|
189
|
+
<style>
|
|
190
|
+
.transition-all {
|
|
191
|
+
transition-property: all;
|
|
192
|
+
transition-duration: 300ms;
|
|
193
|
+
}
|
|
194
|
+
</style>
|