tang-ui-x 1.0.0
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/LICENSE +21 -0
- package/README.md +141 -0
- package/components/TActionSheet/index.uvue +170 -0
- package/components/TActionSheet/type.uts +29 -0
- package/components/TAvatar/index.uvue +156 -0
- package/components/TAvatar/type.uts +54 -0
- package/components/TBadge/index.uvue +152 -0
- package/components/TBadge/type.uts +48 -0
- package/components/TButton/README.md +111 -0
- package/components/TButton/index.uvue +380 -0
- package/components/TButton/type.uts +95 -0
- package/components/TCard/index.uvue +174 -0
- package/components/TCard/type.uts +50 -0
- package/components/TCell/index.uvue +49 -0
- package/components/TCheckbox/index.uvue +187 -0
- package/components/TCheckboxGroup/index.uvue +139 -0
- package/components/TCheckboxGroup/type.uts +26 -0
- package/components/TCol/index.uvue +82 -0
- package/components/TCol/type.uts +30 -0
- package/components/TCollapse/index.uvue +93 -0
- package/components/TCollapse/type.uts +36 -0
- package/components/TCollapseItem/index.uvue +194 -0
- package/components/TCollapseItem/type.uts +25 -0
- package/components/TDialog/index.uvue +386 -0
- package/components/TDialog/type.uts +84 -0
- package/components/TDivider/index.uvue +235 -0
- package/components/TDivider/type.uts +91 -0
- package/components/TEmpty/index.uvue +128 -0
- package/components/TErrorState/index.uvue +57 -0
- package/components/TGrid/index.uvue +115 -0
- package/components/TGrid/type.uts +77 -0
- package/components/TGridItem/index.uvue +243 -0
- package/components/TGridItem/type.uts +64 -0
- package/components/TIcon/index.uvue +96 -0
- package/components/TImage/index.uvue +255 -0
- package/components/TImage/type.uts +146 -0
- package/components/TInput/README.md +119 -0
- package/components/TInput/index.uvue +376 -0
- package/components/TInput/type.uts +138 -0
- package/components/TList/index.uvue +82 -0
- package/components/TList/type.uts +68 -0
- package/components/TListItem/index.uvue +161 -0
- package/components/TListItem/type.uts +49 -0
- package/components/TLoading/index.uvue +153 -0
- package/components/TLoading/type.uts +43 -0
- package/components/TNavBar/index.uvue +120 -0
- package/components/TNavBar/type.uts +22 -0
- package/components/TNoticeBar/index.uvue +106 -0
- package/components/TNoticeBar/type.uts +21 -0
- package/components/TNumberInput/index.uvue +226 -0
- package/components/TPicker/index.uvue +276 -0
- package/components/TPicker/type.uts +105 -0
- package/components/TPopup/index.uvue +442 -0
- package/components/TProgress/index.uvue +103 -0
- package/components/TProgress/type.uts +64 -0
- package/components/TRadioButton/index.uvue +232 -0
- package/components/TRadioGroup/index.uvue +117 -0
- package/components/TRadioGroup/type.uts +25 -0
- package/components/TRate/index.uvue +182 -0
- package/components/TRow/index.uvue +105 -0
- package/components/TRow/type.uts +52 -0
- package/components/TSearchBar/index.uvue +255 -0
- package/components/TSearchBar/type.uts +140 -0
- package/components/TSelect/index.uvue +655 -0
- package/components/TSelect/type.uts +57 -0
- package/components/TSlider/index.uvue +72 -0
- package/components/TSlider/type.uts +21 -0
- package/components/TSwiper/index.uvue +222 -0
- package/components/TSwiper/type.uts +77 -0
- package/components/TSwitch/index.uvue +177 -0
- package/components/TSwitch/type.uts +52 -0
- package/components/TText/README.md +124 -0
- package/components/TText/index.uvue +257 -0
- package/components/TText/type.uts +114 -0
- package/components/TTextarea/index.uvue +239 -0
- package/components/TTextarea/type.uts +106 -0
- package/components/TToast/type.uts +14 -0
- package/components/Tabs/README.md +297 -0
- package/components/Tabs/index.uvue +383 -0
- package/components/Tabs/type.uts +10 -0
- package/components/Tags/README.md +297 -0
- package/components/Tags/index.uvue +383 -0
- package/components/Tags/type.uts +10 -0
- package/components/VbenFrom/index.uvue +392 -0
- package/composables/useModal.uts +294 -0
- package/composables/useTheme.uts +235 -0
- package/composables/useToast.uts +322 -0
- package/index.js +62 -0
- package/package.json +48 -0
- package/style/colors/index.scss +157 -0
- package/style/index.scss +399 -0
- package/types/index.uts +52 -0
- package/uni.scss +79 -0
- package/utils/color.uts +92 -0
- package/utils/common.uts +245 -0
- package/utils/dom.uts +275 -0
- package/utils/index.uts +10 -0
- package/utils/validator.uts +155 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 主题管理组合式函数
|
|
3
|
+
* @module composables/useTheme
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ref, reactive, computed, watch } from 'vue'
|
|
7
|
+
import type { ThemeConfig } from '../types/index.uts'
|
|
8
|
+
|
|
9
|
+
/** 默认主题配置 */
|
|
10
|
+
const defaultTheme: ThemeConfig = {
|
|
11
|
+
primaryColor: '#007aff',
|
|
12
|
+
successColor: '#4cd964',
|
|
13
|
+
warningColor: '#f0ad4e',
|
|
14
|
+
dangerColor: '#dd524d',
|
|
15
|
+
infoColor: '#909399',
|
|
16
|
+
textColor: '#303133',
|
|
17
|
+
borderColor: '#dcdfe6',
|
|
18
|
+
backgroundColor: '#f5f7fa',
|
|
19
|
+
borderRadius: '8rpx',
|
|
20
|
+
fontSize: '28rpx'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** 当前主题配置 */
|
|
24
|
+
const currentTheme = reactive<ThemeConfig>({ ...defaultTheme })
|
|
25
|
+
|
|
26
|
+
/** 是否深色模式 */
|
|
27
|
+
const isDarkMode = ref(false)
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 主题管理组合式函数
|
|
31
|
+
* @returns {Object} 主题管理对象
|
|
32
|
+
*/
|
|
33
|
+
export function useTheme() {
|
|
34
|
+
/**
|
|
35
|
+
* 设置主题
|
|
36
|
+
* @param {Partial<ThemeConfig>} theme - 主题配置
|
|
37
|
+
*/
|
|
38
|
+
const setTheme = (theme: Partial<ThemeConfig>) => {
|
|
39
|
+
Object.assign(currentTheme, theme)
|
|
40
|
+
applyTheme()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 重置主题
|
|
45
|
+
*/
|
|
46
|
+
const resetTheme = () => {
|
|
47
|
+
Object.assign(currentTheme, defaultTheme)
|
|
48
|
+
applyTheme()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 切换深色模式
|
|
53
|
+
* @param {boolean} dark - 是否深色模式
|
|
54
|
+
*/
|
|
55
|
+
const toggleDarkMode = (dark?: boolean) => {
|
|
56
|
+
isDarkMode.value = dark !== undefined ? dark : !isDarkMode.value
|
|
57
|
+
|
|
58
|
+
if (isDarkMode.value) {
|
|
59
|
+
applyDarkTheme()
|
|
60
|
+
} else {
|
|
61
|
+
applyLightTheme()
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 应用主题到页面
|
|
67
|
+
*/
|
|
68
|
+
const applyTheme = () => {
|
|
69
|
+
try {
|
|
70
|
+
// 在 H5 平台应用 CSS 变量
|
|
71
|
+
// #ifdef H5
|
|
72
|
+
const root = document.documentElement
|
|
73
|
+
if (root) {
|
|
74
|
+
root.style.setProperty('--primary-color', currentTheme.primaryColor)
|
|
75
|
+
root.style.setProperty('--success-color', currentTheme.successColor)
|
|
76
|
+
root.style.setProperty('--warning-color', currentTheme.warningColor)
|
|
77
|
+
root.style.setProperty('--danger-color', currentTheme.dangerColor)
|
|
78
|
+
root.style.setProperty('--info-color', currentTheme.infoColor)
|
|
79
|
+
root.style.setProperty('--text-color', currentTheme.textColor)
|
|
80
|
+
root.style.setProperty('--border-color', currentTheme.borderColor)
|
|
81
|
+
root.style.setProperty('--bg-color', currentTheme.backgroundColor)
|
|
82
|
+
root.style.setProperty('--border-radius', currentTheme.borderRadius)
|
|
83
|
+
root.style.setProperty('--font-size', currentTheme.fontSize)
|
|
84
|
+
}
|
|
85
|
+
// #endif
|
|
86
|
+
|
|
87
|
+
// 存储到本地
|
|
88
|
+
uni.setStorageSync('theme-config', JSON.stringify(currentTheme))
|
|
89
|
+
} catch (e) {
|
|
90
|
+
console.error('应用主题失败:', e)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* 应用深色主题
|
|
96
|
+
*/
|
|
97
|
+
const applyDarkTheme = () => {
|
|
98
|
+
const darkTheme: Partial<ThemeConfig> = {
|
|
99
|
+
primaryColor: '#409eff',
|
|
100
|
+
successColor: '#67c23a',
|
|
101
|
+
warningColor: '#e6a23c',
|
|
102
|
+
dangerColor: '#f56c6c',
|
|
103
|
+
infoColor: '#909399',
|
|
104
|
+
textColor: '#f0f0f0',
|
|
105
|
+
borderColor: '#4c4c4c',
|
|
106
|
+
backgroundColor: '#1a1a1a',
|
|
107
|
+
borderRadius: '8rpx',
|
|
108
|
+
fontSize: '28rpx'
|
|
109
|
+
}
|
|
110
|
+
setTheme(darkTheme)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 应用浅色主题
|
|
115
|
+
*/
|
|
116
|
+
const applyLightTheme = () => {
|
|
117
|
+
resetTheme()
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 从本地存储加载主题
|
|
122
|
+
*/
|
|
123
|
+
const loadTheme = () => {
|
|
124
|
+
try {
|
|
125
|
+
const savedTheme = uni.getStorageSync('theme-config')
|
|
126
|
+
if (savedTheme) {
|
|
127
|
+
const theme = JSON.parse(savedTheme)
|
|
128
|
+
Object.assign(currentTheme, theme)
|
|
129
|
+
applyTheme()
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const savedDarkMode = uni.getStorageSync('dark-mode')
|
|
133
|
+
if (savedDarkMode !== '') {
|
|
134
|
+
isDarkMode.value = savedDarkMode === 'true'
|
|
135
|
+
}
|
|
136
|
+
} catch (e) {
|
|
137
|
+
console.error('加载主题失败:', e)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 获取主题颜色
|
|
143
|
+
* @param {string} type - 颜色类型
|
|
144
|
+
* @returns {string} 颜色值
|
|
145
|
+
*/
|
|
146
|
+
const getColor = (type: string): string => {
|
|
147
|
+
switch (type) {
|
|
148
|
+
case 'primary':
|
|
149
|
+
return currentTheme.primaryColor
|
|
150
|
+
case 'success':
|
|
151
|
+
return currentTheme.successColor
|
|
152
|
+
case 'warning':
|
|
153
|
+
return currentTheme.warningColor
|
|
154
|
+
case 'danger':
|
|
155
|
+
return currentTheme.dangerColor
|
|
156
|
+
case 'info':
|
|
157
|
+
return currentTheme.infoColor
|
|
158
|
+
case 'text':
|
|
159
|
+
return currentTheme.textColor
|
|
160
|
+
case 'border':
|
|
161
|
+
return currentTheme.borderColor
|
|
162
|
+
case 'bg':
|
|
163
|
+
case 'background':
|
|
164
|
+
return currentTheme.backgroundColor
|
|
165
|
+
default:
|
|
166
|
+
return currentTheme.primaryColor
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* 获取计算后的主题
|
|
172
|
+
*/
|
|
173
|
+
const computedTheme = computed(() => currentTheme)
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* 监听系统主题变化
|
|
177
|
+
*/
|
|
178
|
+
const watchSystemTheme = () => {
|
|
179
|
+
// #ifdef H5
|
|
180
|
+
if (window.matchMedia) {
|
|
181
|
+
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
|
182
|
+
mediaQuery.addListener((e) => {
|
|
183
|
+
if (e.matches) {
|
|
184
|
+
toggleDarkMode(true)
|
|
185
|
+
} else {
|
|
186
|
+
toggleDarkMode(false)
|
|
187
|
+
}
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
// #endif
|
|
191
|
+
|
|
192
|
+
// #ifdef APP-PLUS
|
|
193
|
+
plus.globalEvent.addEventListener('ThemeChange', (e: any) => {
|
|
194
|
+
toggleDarkMode(e.dark)
|
|
195
|
+
})
|
|
196
|
+
// #endif
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// 监听深色模式变化
|
|
200
|
+
watch(isDarkMode, (newValue) => {
|
|
201
|
+
uni.setStorageSync('dark-mode', String(newValue))
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
// 初始化加载主题
|
|
205
|
+
loadTheme()
|
|
206
|
+
watchSystemTheme()
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
// 状态
|
|
210
|
+
theme: computedTheme,
|
|
211
|
+
isDarkMode,
|
|
212
|
+
|
|
213
|
+
// 方法
|
|
214
|
+
setTheme,
|
|
215
|
+
resetTheme,
|
|
216
|
+
toggleDarkMode,
|
|
217
|
+
getColor,
|
|
218
|
+
loadTheme,
|
|
219
|
+
|
|
220
|
+
// 常量
|
|
221
|
+
defaultTheme
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* 获取主题实例(单例模式)
|
|
227
|
+
*/
|
|
228
|
+
let themeInstance: ReturnType<typeof useTheme> | null = null
|
|
229
|
+
|
|
230
|
+
export function getThemeInstance() {
|
|
231
|
+
if (!themeInstance) {
|
|
232
|
+
themeInstance = useTheme()
|
|
233
|
+
}
|
|
234
|
+
return themeInstance
|
|
235
|
+
}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Toast 提示管理组合式函数
|
|
3
|
+
* @module composables/useToast
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ref } from 'vue'
|
|
7
|
+
import type { ToastOptions, ComponentType, PositionType } from '@/types/index.uts'
|
|
8
|
+
|
|
9
|
+
/** Toast 队列 */
|
|
10
|
+
const toastQueue = ref<ToastOptions[]>([])
|
|
11
|
+
|
|
12
|
+
/** 当前显示的 Toast */
|
|
13
|
+
const currentToast = ref<ToastOptions | null>(null)
|
|
14
|
+
|
|
15
|
+
/** 是否正在显示 */
|
|
16
|
+
const isShowing = ref(false)
|
|
17
|
+
|
|
18
|
+
/** 默认配置 */
|
|
19
|
+
const defaultOptions: Partial<ToastOptions> = {
|
|
20
|
+
duration: 2000,
|
|
21
|
+
position: 'center',
|
|
22
|
+
type: 'default',
|
|
23
|
+
mask: false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Toast 管理组合式函数
|
|
28
|
+
* @returns {Object} Toast 管理对象
|
|
29
|
+
*/
|
|
30
|
+
export function useToast() {
|
|
31
|
+
/**
|
|
32
|
+
* 显示 Toast
|
|
33
|
+
* @param {string | ToastOptions} options - 提示内容或配置
|
|
34
|
+
* @returns {void}
|
|
35
|
+
*/
|
|
36
|
+
const show = (options: string | ToastOptions): void => {
|
|
37
|
+
try {
|
|
38
|
+
// 处理参数
|
|
39
|
+
const toastOptions: ToastOptions = typeof options === 'string'
|
|
40
|
+
? { message: options }
|
|
41
|
+
: options
|
|
42
|
+
|
|
43
|
+
// 合并默认配置
|
|
44
|
+
const config = { ...defaultOptions, ...toastOptions }
|
|
45
|
+
|
|
46
|
+
// 添加到队列
|
|
47
|
+
toastQueue.value.push(config)
|
|
48
|
+
|
|
49
|
+
// 如果当前没有显示,则开始显示
|
|
50
|
+
if (!isShowing.value) {
|
|
51
|
+
showNext()
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('显示 Toast 失败:', error)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 显示成功提示
|
|
60
|
+
* @param {string} message - 提示内容
|
|
61
|
+
* @param {number} duration - 显示时长
|
|
62
|
+
*/
|
|
63
|
+
const success = (message: string, duration?: number): void => {
|
|
64
|
+
show({
|
|
65
|
+
message,
|
|
66
|
+
type: 'success',
|
|
67
|
+
duration: duration || defaultOptions.duration
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 显示错误提示
|
|
73
|
+
* @param {string} message - 提示内容
|
|
74
|
+
* @param {number} duration - 显示时长
|
|
75
|
+
*/
|
|
76
|
+
const error = (message: string, duration?: number): void => {
|
|
77
|
+
show({
|
|
78
|
+
message,
|
|
79
|
+
type: 'danger',
|
|
80
|
+
duration: duration || defaultOptions.duration
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 显示警告提示
|
|
86
|
+
* @param {string} message - 提示内容
|
|
87
|
+
* @param {number} duration - 显示时长
|
|
88
|
+
*/
|
|
89
|
+
const warning = (message: string, duration?: number): void => {
|
|
90
|
+
show({
|
|
91
|
+
message,
|
|
92
|
+
type: 'warning',
|
|
93
|
+
duration: duration || defaultOptions.duration
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 显示信息提示
|
|
99
|
+
* @param {string} message - 提示内容
|
|
100
|
+
* @param {number} duration - 显示时长
|
|
101
|
+
*/
|
|
102
|
+
const info = (message: string, duration?: number): void => {
|
|
103
|
+
show({
|
|
104
|
+
message,
|
|
105
|
+
type: 'info',
|
|
106
|
+
duration: duration || defaultOptions.duration
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 显示加载提示
|
|
112
|
+
* @param {string} message - 提示内容
|
|
113
|
+
* @returns {Function} 关闭函数
|
|
114
|
+
*/
|
|
115
|
+
const loading = (message: string = '加载中...'): (() => void) => {
|
|
116
|
+
uni.showToast({
|
|
117
|
+
title: message,
|
|
118
|
+
icon: 'loading',
|
|
119
|
+
duration: 100000, // 设置一个很长的时间
|
|
120
|
+
mask: true
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
return () => {
|
|
124
|
+
uni.hideToast()
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* 显示下一个 Toast
|
|
130
|
+
*/
|
|
131
|
+
const showNext = (): void => {
|
|
132
|
+
if (toastQueue.value.length === 0) {
|
|
133
|
+
isShowing.value = false
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
isShowing.value = true
|
|
138
|
+
currentToast.value = toastQueue.value.shift() || null
|
|
139
|
+
|
|
140
|
+
if (!currentToast.value) {
|
|
141
|
+
isShowing.value = false
|
|
142
|
+
return
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// 根据类型选择图标
|
|
146
|
+
let icon: 'success' | 'error' | 'loading' | 'none' = 'none'
|
|
147
|
+
let image: string | undefined = undefined
|
|
148
|
+
|
|
149
|
+
switch (currentToast.value.type) {
|
|
150
|
+
case 'success':
|
|
151
|
+
icon = 'success'
|
|
152
|
+
break
|
|
153
|
+
case 'danger':
|
|
154
|
+
icon = 'error'
|
|
155
|
+
break
|
|
156
|
+
case 'warning':
|
|
157
|
+
case 'info':
|
|
158
|
+
// 使用自定义图标
|
|
159
|
+
// image = '/static/icons/warning.png' // 需要准备图标文件
|
|
160
|
+
icon = 'none'
|
|
161
|
+
break
|
|
162
|
+
default:
|
|
163
|
+
icon = 'none'
|
|
164
|
+
break
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 处理位置(uni.showToast 不支持自定义位置,这里仅作记录)
|
|
168
|
+
// 实际项目中可以使用自定义组件来支持更多位置选项
|
|
169
|
+
|
|
170
|
+
// 显示 Toast
|
|
171
|
+
uni.showToast({
|
|
172
|
+
title: currentToast.value.message,
|
|
173
|
+
icon,
|
|
174
|
+
image,
|
|
175
|
+
duration: currentToast.value.duration,
|
|
176
|
+
mask: currentToast.value.mask,
|
|
177
|
+
success: () => {
|
|
178
|
+
// 设置定时器,在 duration 后显示下一个
|
|
179
|
+
setTimeout(() => {
|
|
180
|
+
currentToast.value = null
|
|
181
|
+
showNext()
|
|
182
|
+
}, currentToast.value?.duration || 2000)
|
|
183
|
+
},
|
|
184
|
+
fail: (error) => {
|
|
185
|
+
console.error('Toast 显示失败:', error)
|
|
186
|
+
currentToast.value = null
|
|
187
|
+
isShowing.value = false
|
|
188
|
+
|
|
189
|
+
// 尝试显示下一个
|
|
190
|
+
setTimeout(() => showNext(), 100)
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* 隐藏当前 Toast
|
|
197
|
+
*/
|
|
198
|
+
const hide = (): void => {
|
|
199
|
+
uni.hideToast()
|
|
200
|
+
currentToast.value = null
|
|
201
|
+
|
|
202
|
+
// 清理后显示下一个
|
|
203
|
+
if (toastQueue.value.length > 0) {
|
|
204
|
+
setTimeout(() => showNext(), 100)
|
|
205
|
+
} else {
|
|
206
|
+
isShowing.value = false
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* 清空 Toast 队列
|
|
212
|
+
*/
|
|
213
|
+
const clear = (): void => {
|
|
214
|
+
toastQueue.value = []
|
|
215
|
+
currentToast.value = null
|
|
216
|
+
isShowing.value = false
|
|
217
|
+
uni.hideToast()
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* 设置默认配置
|
|
222
|
+
* @param {Partial<ToastOptions>} options - 配置项
|
|
223
|
+
*/
|
|
224
|
+
const setDefaults = (options: Partial<ToastOptions>): void => {
|
|
225
|
+
Object.assign(defaultOptions, options)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* 获取队列长度
|
|
230
|
+
* @returns {number} 队列长度
|
|
231
|
+
*/
|
|
232
|
+
const getQueueLength = (): number => {
|
|
233
|
+
return toastQueue.value.length
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return {
|
|
237
|
+
// 状态
|
|
238
|
+
isShowing,
|
|
239
|
+
currentToast,
|
|
240
|
+
toastQueue,
|
|
241
|
+
|
|
242
|
+
// 方法
|
|
243
|
+
show,
|
|
244
|
+
success,
|
|
245
|
+
error,
|
|
246
|
+
warning,
|
|
247
|
+
info,
|
|
248
|
+
loading,
|
|
249
|
+
hide,
|
|
250
|
+
clear,
|
|
251
|
+
setDefaults,
|
|
252
|
+
getQueueLength
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* 获取 Toast 实例(单例模式)
|
|
258
|
+
*/
|
|
259
|
+
let toastInstance: ReturnType<typeof useToast> | null = null
|
|
260
|
+
|
|
261
|
+
export function getToastInstance() {
|
|
262
|
+
if (!toastInstance) {
|
|
263
|
+
toastInstance = useToast()
|
|
264
|
+
}
|
|
265
|
+
return toastInstance
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* 快捷方法:显示 Toast
|
|
270
|
+
*/
|
|
271
|
+
export function showToast(options: string | ToastOptions): void {
|
|
272
|
+
getToastInstance().show(options)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* 快捷方法:显示成功提示
|
|
277
|
+
*/
|
|
278
|
+
export function showSuccess(message: string, duration?: number): void {
|
|
279
|
+
getToastInstance().success(message, duration)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* 快捷方法:显示错误提示
|
|
284
|
+
*/
|
|
285
|
+
export function showError(message: string, duration?: number): void {
|
|
286
|
+
getToastInstance().error(message, duration)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* 快捷方法:显示警告提示
|
|
291
|
+
*/
|
|
292
|
+
export function showWarning(message: string, duration?: number): void {
|
|
293
|
+
getToastInstance().warning(message, duration)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* 快捷方法:显示信息提示
|
|
298
|
+
*/
|
|
299
|
+
export function showInfo(message: string, duration?: number): void {
|
|
300
|
+
getToastInstance().info(message, duration)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* 快捷方法:显示加载提示
|
|
305
|
+
*/
|
|
306
|
+
export function showLoadingToast(message?: string): () => void {
|
|
307
|
+
return getToastInstance().loading(message)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* 快捷方法:隐藏 Toast
|
|
312
|
+
*/
|
|
313
|
+
export function hideToast(): void {
|
|
314
|
+
getToastInstance().hide()
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* 快捷方法:清空 Toast 队列
|
|
319
|
+
*/
|
|
320
|
+
export function clearToast(): void {
|
|
321
|
+
getToastInstance().clear()
|
|
322
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// UniApp X UI 组件库入口文件
|
|
2
|
+
// 注意:uni-app x 项目通常通过 easycom 自动导入组件,无需手动注册
|
|
3
|
+
|
|
4
|
+
// 导出所有组件(供按需引入使用)
|
|
5
|
+
export { default as TButton } from './components/TButton/TButton.vue'
|
|
6
|
+
export { default as TIcon } from './components/TIcon/TIcon.vue'
|
|
7
|
+
export { default as TText } from './components/TText/TText.vue'
|
|
8
|
+
export { default as TImage } from './components/TImage/TImage.vue'
|
|
9
|
+
export { default as TDivider } from './components/TDivider/TDivider.vue'
|
|
10
|
+
|
|
11
|
+
// 布局组件
|
|
12
|
+
export { default as TCard } from './components/TCard/TCard.vue'
|
|
13
|
+
export { default as TList } from './components/TList/TList.vue'
|
|
14
|
+
export { default as TListItem } from './components/TListItem/TListItem.vue'
|
|
15
|
+
export { default as TCell } from './components/TCell/TCell.vue'
|
|
16
|
+
export { default as TGrid } from './components/TGrid/TGrid.vue'
|
|
17
|
+
export { default as TGridItem } from './components/TGridItem/TGridItem.vue'
|
|
18
|
+
export { default as TRow } from './components/TRow/TRow.vue'
|
|
19
|
+
export { default as TCol } from './components/TCol/TCol.vue'
|
|
20
|
+
|
|
21
|
+
// 表单组件
|
|
22
|
+
export { default as TInput } from './components/TInput/TInput.vue'
|
|
23
|
+
export { default as TNumberInput } from './components/TNumberInput/TNumberInput.vue'
|
|
24
|
+
export { default as TTextarea } from './components/TTextarea/TTextarea.vue'
|
|
25
|
+
export { default as TSearchBar } from './components/TSearchBar/TSearchBar.vue'
|
|
26
|
+
export { default as TSwitch } from './components/TSwitch/TSwitch.vue'
|
|
27
|
+
export { default as TCheckbox } from './components/TCheckbox/TCheckbox.vue'
|
|
28
|
+
export { default as TCheckboxGroup } from './components/TCheckboxGroup/TCheckboxGroup.vue'
|
|
29
|
+
export { default as TRadioButton } from './components/TRadioButton/TRadioButton.vue'
|
|
30
|
+
export { default as TRadioGroup } from './components/TRadioGroup/TRadioGroup.vue'
|
|
31
|
+
export { default as TSelect } from './components/TSelect/TSelect.vue'
|
|
32
|
+
export { default as TSlider } from './components/TSlider/TSlider.vue'
|
|
33
|
+
export { default as TRate } from './components/TRate/TRate.vue'
|
|
34
|
+
|
|
35
|
+
// 数据展示
|
|
36
|
+
export { default as Tags } from './components/Tags/Tags.vue'
|
|
37
|
+
export { default as TBadge } from './components/TBadge/TBadge.vue'
|
|
38
|
+
export { default as TAvatar } from './components/TAvatar/TAvatar.vue'
|
|
39
|
+
export { default as TProgress } from './components/TProgress/TProgress.vue'
|
|
40
|
+
export { default as TNoticeBar } from './components/TNoticeBar/TNoticeBar.vue'
|
|
41
|
+
export { default as TCollapse } from './components/TCollapse/TCollapse.vue'
|
|
42
|
+
export { default as TCollapseItem } from './components/TCollapseItem/TCollapseItem.vue'
|
|
43
|
+
export { default as TEmpty } from './components/TEmpty/TEmpty.vue'
|
|
44
|
+
export { default as TErrorState } from './components/TErrorState/TErrorState.vue'
|
|
45
|
+
export { default as TSwiper } from './components/TSwiper/TSwiper.vue'
|
|
46
|
+
|
|
47
|
+
// 反馈组件
|
|
48
|
+
export { default as TLoading } from './components/TLoading/TLoading.vue'
|
|
49
|
+
export { default as TToast } from './components/TToast/TToast.vue'
|
|
50
|
+
export { default as TDialog } from './components/TDialog/TDialog.vue'
|
|
51
|
+
export { default as TPopup } from './components/TPopup/TPopup.vue'
|
|
52
|
+
export { default as TActionSheet } from './components/TActionSheet/TActionSheet.vue'
|
|
53
|
+
|
|
54
|
+
// 导航组件
|
|
55
|
+
export { default as Tabs } from './components/Tabs/Tabs.vue'
|
|
56
|
+
export { default as TNavBar } from './components/TNavBar/TNavBar.vue'
|
|
57
|
+
|
|
58
|
+
// 导出工具函数(如果有)
|
|
59
|
+
export * from './utils'
|
|
60
|
+
|
|
61
|
+
// 版本信息
|
|
62
|
+
export const version = '1.0.0'
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tang-ui-x",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "UniApp X UI 组件库 - 基于 uni-app x 的移动端 UI 组件库",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"module": "index.js",
|
|
7
|
+
"types": "types/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"components",
|
|
10
|
+
"composables",
|
|
11
|
+
"utils",
|
|
12
|
+
"types",
|
|
13
|
+
"style",
|
|
14
|
+
"uni.scss",
|
|
15
|
+
"index.js",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"uniapp",
|
|
21
|
+
"uni-app-x",
|
|
22
|
+
"uniapp-x",
|
|
23
|
+
"ui",
|
|
24
|
+
"components",
|
|
25
|
+
"mobile",
|
|
26
|
+
"vue3",
|
|
27
|
+
"typescript",
|
|
28
|
+
"tang-ui"
|
|
29
|
+
],
|
|
30
|
+
"author": "sugar258596",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/sugar258596/tang-ui.git"
|
|
35
|
+
},
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/sugar258596/tang-ui/issues"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/sugar258596/tang-ui#readme",
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"vue": "^3.0.0"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"prepublishOnly": "npm run build",
|
|
45
|
+
"build": "echo 'Build completed'",
|
|
46
|
+
"version": "npm run build"
|
|
47
|
+
}
|
|
48
|
+
}
|