@atooyu/uxto-ui 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.
Files changed (141) hide show
  1. package/README.md +259 -0
  2. package/dist/index.js +5055 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.mjs +5055 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/dist/style.css +2528 -0
  7. package/package.json +93 -0
  8. package/src/components/index.ts +51 -0
  9. package/src/components/u-avatar/u-avatar.vue +205 -0
  10. package/src/components/u-badge/u-badge.vue +145 -0
  11. package/src/components/u-button/u-button.vue +239 -0
  12. package/src/components/u-cell/u-cell.vue +179 -0
  13. package/src/components/u-cell-group/u-cell-group.vue +46 -0
  14. package/src/components/u-checkbox/u-checkbox.vue +174 -0
  15. package/src/components/u-checkbox-group/u-checkbox-group.vue +72 -0
  16. package/src/components/u-code-input/u-code-input.vue +248 -0
  17. package/src/components/u-count-down/u-count-down.vue +182 -0
  18. package/src/components/u-datetime-picker/u-datetime-picker.vue +377 -0
  19. package/src/components/u-divider/u-divider.vue +71 -0
  20. package/src/components/u-empty/u-empty.vue +98 -0
  21. package/src/components/u-grid/u-grid.vue +63 -0
  22. package/src/components/u-grid-item/u-grid-item.vue +170 -0
  23. package/src/components/u-icon/icons/account.svg +3 -0
  24. package/src/components/u-icon/icons/arrow-down.svg +3 -0
  25. package/src/components/u-icon/icons/arrow-left.svg +3 -0
  26. package/src/components/u-icon/icons/arrow-right.svg +3 -0
  27. package/src/components/u-icon/icons/arrow-up.svg +3 -0
  28. package/src/components/u-icon/icons/bell.svg +3 -0
  29. package/src/components/u-icon/icons/bookmark-o.svg +3 -0
  30. package/src/components/u-icon/icons/bookmark.svg +3 -0
  31. package/src/components/u-icon/icons/chat.svg +3 -0
  32. package/src/components/u-icon/icons/check-circle.svg +3 -0
  33. package/src/components/u-icon/icons/check.svg +3 -0
  34. package/src/components/u-icon/icons/chevron-left.svg +3 -0
  35. package/src/components/u-icon/icons/chevron-right.svg +3 -0
  36. package/src/components/u-icon/icons/clear-o.svg +3 -0
  37. package/src/components/u-icon/icons/clear.svg +3 -0
  38. package/src/components/u-icon/icons/clipboard.svg +3 -0
  39. package/src/components/u-icon/icons/clock.svg +3 -0
  40. package/src/components/u-icon/icons/close.svg +3 -0
  41. package/src/components/u-icon/icons/code.svg +3 -0
  42. package/src/components/u-icon/icons/copy.svg +3 -0
  43. package/src/components/u-icon/icons/delete.svg +3 -0
  44. package/src/components/u-icon/icons/download.svg +3 -0
  45. package/src/components/u-icon/icons/edit.svg +3 -0
  46. package/src/components/u-icon/icons/email.svg +3 -0
  47. package/src/components/u-icon/icons/error-o.svg +3 -0
  48. package/src/components/u-icon/icons/error.svg +3 -0
  49. package/src/components/u-icon/icons/exit-fullscreen.svg +3 -0
  50. package/src/components/u-icon/icons/expand-less.svg +3 -0
  51. package/src/components/u-icon/icons/expand-more.svg +3 -0
  52. package/src/components/u-icon/icons/eye-off.svg +3 -0
  53. package/src/components/u-icon/icons/eye.svg +3 -0
  54. package/src/components/u-icon/icons/flag-o.svg +3 -0
  55. package/src/components/u-icon/icons/flag.svg +3 -0
  56. package/src/components/u-icon/icons/fullscreen.svg +3 -0
  57. package/src/components/u-icon/icons/grid.svg +3 -0
  58. package/src/components/u-icon/icons/group.svg +3 -0
  59. package/src/components/u-icon/icons/heart-o.svg +3 -0
  60. package/src/components/u-icon/icons/heart.svg +3 -0
  61. package/src/components/u-icon/icons/info-o.svg +3 -0
  62. package/src/components/u-icon/icons/info.svg +3 -0
  63. package/src/components/u-icon/icons/keyboard-arrow-down.svg +3 -0
  64. package/src/components/u-icon/icons/keyboard-arrow-left.svg +3 -0
  65. package/src/components/u-icon/icons/keyboard-arrow-right.svg +3 -0
  66. package/src/components/u-icon/icons/keyboard-arrow-up.svg +3 -0
  67. package/src/components/u-icon/icons/like-o.svg +3 -0
  68. package/src/components/u-icon/icons/like.svg +3 -0
  69. package/src/components/u-icon/icons/link.svg +3 -0
  70. package/src/components/u-icon/icons/list.svg +3 -0
  71. package/src/components/u-icon/icons/loading.svg +3 -0
  72. package/src/components/u-icon/icons/lock.svg +3 -0
  73. package/src/components/u-icon/icons/menu-o.svg +3 -0
  74. package/src/components/u-icon/icons/menu.svg +3 -0
  75. package/src/components/u-icon/icons/message.svg +3 -0
  76. package/src/components/u-icon/icons/minus.svg +3 -0
  77. package/src/components/u-icon/icons/notification.svg +3 -0
  78. package/src/components/u-icon/icons/phone.svg +3 -0
  79. package/src/components/u-icon/icons/plus.svg +3 -0
  80. package/src/components/u-icon/icons/question.svg +3 -0
  81. package/src/components/u-icon/icons/redo.svg +3 -0
  82. package/src/components/u-icon/icons/refresh-o.svg +3 -0
  83. package/src/components/u-icon/icons/refresh.svg +3 -0
  84. package/src/components/u-icon/icons/reload.svg +3 -0
  85. package/src/components/u-icon/icons/search-o.svg +3 -0
  86. package/src/components/u-icon/icons/search.svg +3 -0
  87. package/src/components/u-icon/icons/setting.svg +3 -0
  88. package/src/components/u-icon/icons/share.svg +3 -0
  89. package/src/components/u-icon/icons/smile-o.svg +3 -0
  90. package/src/components/u-icon/icons/smile.svg +3 -0
  91. package/src/components/u-icon/icons/star-o.svg +3 -0
  92. package/src/components/u-icon/icons/star.svg +3 -0
  93. package/src/components/u-icon/icons/success-o.svg +3 -0
  94. package/src/components/u-icon/icons/success.svg +3 -0
  95. package/src/components/u-icon/icons/sync.svg +3 -0
  96. package/src/components/u-icon/icons/tick.svg +3 -0
  97. package/src/components/u-icon/icons/undo.svg +3 -0
  98. package/src/components/u-icon/icons/unlock.svg +3 -0
  99. package/src/components/u-icon/icons/upload.svg +3 -0
  100. package/src/components/u-icon/icons/user.svg +3 -0
  101. package/src/components/u-icon/icons/warning-o.svg +3 -0
  102. package/src/components/u-icon/icons/warning.svg +3 -0
  103. package/src/components/u-icon/icons/zoom-in.svg +3 -0
  104. package/src/components/u-icon/icons/zoom-out.svg +3 -0
  105. package/src/components/u-icon/index.ts +219 -0
  106. package/src/components/u-icon/u-icon.vue +117 -0
  107. package/src/components/u-image/u-image.vue +106 -0
  108. package/src/components/u-input/u-input.vue +208 -0
  109. package/src/components/u-keyboard/u-keyboard.vue +213 -0
  110. package/src/components/u-layout/u-layout.vue +58 -0
  111. package/src/components/u-line-progress/u-line-progress.vue +156 -0
  112. package/src/components/u-link/u-link.vue +113 -0
  113. package/src/components/u-list/u-list.vue +148 -0
  114. package/src/components/u-list-item/u-list-item.vue +180 -0
  115. package/src/components/u-loading/u-loading.vue +80 -0
  116. package/src/components/u-loading-page/u-loading-page.vue +94 -0
  117. package/src/components/u-modal/u-modal.vue +159 -0
  118. package/src/components/u-notice-bar/u-notice-bar.vue +113 -0
  119. package/src/components/u-number-box/u-number-box.vue +262 -0
  120. package/src/components/u-parse/u-parse.vue +197 -0
  121. package/src/components/u-picker/u-picker.vue +219 -0
  122. package/src/components/u-popup/u-popup.vue +257 -0
  123. package/src/components/u-radio/u-radio.vue +159 -0
  124. package/src/components/u-radio-group/u-radio-group.vue +61 -0
  125. package/src/components/u-rate/u-rate.vue +187 -0
  126. package/src/components/u-read-more/u-read-more.vue +117 -0
  127. package/src/components/u-search/u-search.vue +238 -0
  128. package/src/components/u-skeleton/u-skeleton.vue +192 -0
  129. package/src/components/u-slider/u-slider.vue +453 -0
  130. package/src/components/u-swiper/u-swiper.vue +301 -0
  131. package/src/components/u-swiper-item/u-swiper-item.vue +82 -0
  132. package/src/components/u-switch/u-switch.vue +105 -0
  133. package/src/components/u-tabbar/u-tabbar.vue +221 -0
  134. package/src/components/u-tag/u-tag.vue +144 -0
  135. package/src/components/u-textarea/u-textarea.vue +189 -0
  136. package/src/components/u-toast/u-toast.vue +186 -0
  137. package/src/components/u-tooltip/u-tooltip.vue +364 -0
  138. package/src/components/u-transition/u-transition.vue +216 -0
  139. package/src/components/u-upload/u-upload.vue +403 -0
  140. package/src/styles/index.scss +59 -0
  141. package/src/styles/variables.scss +68 -0
@@ -0,0 +1,248 @@
1
+ <template>
2
+ <view class="u-code-input">
3
+ <view class="u-code-input__wrapper">
4
+ <view
5
+ v-for="i in length"
6
+ :key="i"
7
+ class="u-code-input__item"
8
+ :class="itemClass(i)"
9
+ :style="itemStyle"
10
+ >
11
+ <text v-if="values[i - 1] && !password" class="u-code-input__char">{{ values[i - 1] }}</text>
12
+ <view v-else-if="values[i - 1] && password" class="u-code-input__dot" />
13
+ <view v-else class="u-code-input__placeholder">{{ placeholderChar }}</view>
14
+ <view v-if="focus && i - 1 === currentIndex" class="u-code-input__cursor" />
15
+ </view>
16
+ </view>
17
+ <input
18
+ class="u-code-input__input"
19
+ type="text"
20
+ :value="innerValue"
21
+ :maxlength="length"
22
+ :disabled="disabled"
23
+ :focus="focus"
24
+ :password="password"
25
+ @input="handleInput"
26
+ @focus="handleFocus"
27
+ @blur="handleBlur"
28
+ />
29
+ </view>
30
+ </template>
31
+
32
+ <script setup lang="ts">
33
+ import { ref, computed, watch } from 'vue'
34
+
35
+ interface Props {
36
+ value?: string
37
+ length?: number
38
+ size?: number
39
+ gap?: number
40
+ plain?: boolean
41
+ disabled?: boolean
42
+ password?: boolean
43
+ focus?: boolean
44
+ borderColor?: string
45
+ activeBorderColor?: string
46
+ placeholderChar?: string
47
+ }
48
+
49
+ const props = withDefaults(defineProps<Props>(), {
50
+ value: '',
51
+ length: 6,
52
+ size: 40,
53
+ gap: 10,
54
+ plain: false,
55
+ disabled: false,
56
+ password: false,
57
+ focus: false,
58
+ borderColor: '#dcdee0',
59
+ activeBorderColor: '#1989fa',
60
+ placeholderChar: '·'
61
+ })
62
+
63
+ const emit = defineEmits<{
64
+ 'update:value': [value: string]
65
+ 'update:modelValue': [value: string]
66
+ input: [value: string]
67
+ complete: [value: string]
68
+ focus: []
69
+ blur: []
70
+ }>()
71
+
72
+ const innerValue = ref(props.value)
73
+
74
+ watch(() => props.value, (val) => {
75
+ innerValue.value = val
76
+ })
77
+
78
+ const values = computed(() => {
79
+ const chars = innerValue.value.split('')
80
+ return chars
81
+ })
82
+
83
+ const currentIndex = computed(() => {
84
+ return Math.min(values.value.length, props.length - 1)
85
+ })
86
+
87
+ const itemStyle = computed(() => {
88
+ return {
89
+ width: `${props.size}px`,
90
+ height: `${props.size}px`,
91
+ marginRight: `${props.gap}px`
92
+ }
93
+ })
94
+
95
+ const itemClass = (i: number) => {
96
+ const classes: string[] = []
97
+
98
+ if (props.plain) {
99
+ classes.push('u-code-input__item--plain')
100
+ }
101
+
102
+ if (!props.plain) {
103
+ classes.push('u-code-input__item--filled')
104
+ }
105
+
106
+ if (values.value[i - 1]) {
107
+ classes.push('u-code-input__item--active')
108
+ }
109
+
110
+ if (props.focus && i - 1 === currentIndex.value) {
111
+ classes.push('u-code-input__item--focused')
112
+ }
113
+
114
+ if (props.disabled) {
115
+ classes.push('u-code-input__item--disabled')
116
+ }
117
+
118
+ return classes
119
+ }
120
+
121
+ const handleInput = (e: any) => {
122
+ const val = e.detail.value.replace(/\D/g, '').slice(0, props.length)
123
+ innerValue.value = val
124
+
125
+ emit('update:value', val)
126
+ emit('update:modelValue', val)
127
+ emit('input', val)
128
+
129
+ if (val.length === props.length) {
130
+ emit('complete', val)
131
+ }
132
+ }
133
+
134
+ const handleFocus = () => {
135
+ emit('focus')
136
+ }
137
+
138
+ const handleBlur = () => {
139
+ emit('blur')
140
+ }
141
+ </script>
142
+
143
+ <script lang="ts">
144
+ export default {
145
+ options: {
146
+ virtualHost: true,
147
+ styleIsolation: 'shared'
148
+ }
149
+ }
150
+ </script>
151
+
152
+ <style lang="scss" scoped>
153
+ .u-code-input {
154
+ position: relative;
155
+ -webkit-user-select: none;
156
+ -moz-user-select: none;
157
+ -ms-user-select: none;
158
+ user-select: none;
159
+
160
+ &__wrapper {
161
+ display: flex;
162
+ flex-direction: row;
163
+ }
164
+
165
+ &__item {
166
+ display: flex;
167
+ align-items: center;
168
+ justify-content: center;
169
+ font-size: 20px;
170
+ font-weight: 500;
171
+ line-height: 1;
172
+ position: relative;
173
+ flex-shrink: 0;
174
+
175
+ &:last-child {
176
+ margin-right: 0 !important;
177
+ }
178
+
179
+ &--filled {
180
+ background-color: $--bg-color;
181
+ border: 1px solid $--border-color;
182
+ border-radius: $--radius-sm;
183
+ }
184
+
185
+ &--plain {
186
+ border-bottom: 2px solid $--border-color;
187
+ background-color: transparent;
188
+ }
189
+
190
+ &--active {
191
+ border-color: $--color-primary;
192
+ }
193
+
194
+ &--focused {
195
+ border-color: $--color-primary;
196
+ }
197
+
198
+ &--disabled {
199
+ opacity: 0.5;
200
+ }
201
+ }
202
+
203
+ &__char {
204
+ color: $--text-color;
205
+ }
206
+
207
+ &__dot {
208
+ width: 8px;
209
+ height: 8px;
210
+ border-radius: 50%;
211
+ background-color: $--text-color;
212
+ }
213
+
214
+ &__placeholder {
215
+ color: $--text-color-3;
216
+ font-size: 24px;
217
+ }
218
+
219
+ &__cursor {
220
+ position: absolute;
221
+ left: 0;
222
+ top: 10%;
223
+ height: 80%;
224
+ width: 2px;
225
+ background-color: $--color-primary;
226
+ animation: u-code-input-cursor 1s infinite;
227
+ }
228
+
229
+ @keyframes u-code-input-cursor {
230
+ 0%, 50% {
231
+ opacity: 1;
232
+ }
233
+ 51%, 100% {
234
+ opacity: 0;
235
+ }
236
+ }
237
+
238
+ &__input {
239
+ position: absolute;
240
+ top: 0;
241
+ left: 0;
242
+ width: 200%;
243
+ height: 100%;
244
+ opacity: 0;
245
+ z-index: 2;
246
+ }
247
+ }
248
+ </style>
@@ -0,0 +1,182 @@
1
+ <template>
2
+ <view class="u-count-down">
3
+ <slot :time="timeData" :current="current">
4
+ <text class="u-count-down__text" :style="textStyle">{{ formattedTime }}</text>
5
+ </slot>
6
+ </view>
7
+ </template>
8
+
9
+ <script setup lang="ts">
10
+ import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
11
+
12
+ interface TimeData {
13
+ days: number
14
+ hours: number
15
+ minutes: number
16
+ seconds: number
17
+ milliseconds: number
18
+ total: number
19
+ }
20
+
21
+ interface Props {
22
+ time: number
23
+ format?: string
24
+ millisecond?: boolean
25
+ autoStart?: boolean
26
+ fontSize?: number | string
27
+ color?: string
28
+ }
29
+
30
+ const props = withDefaults(defineProps<Props>(), {
31
+ time: 0,
32
+ format: 'HH:mm:ss',
33
+ millisecond: false,
34
+ autoStart: true,
35
+ fontSize: 14,
36
+ color: ''
37
+ })
38
+
39
+ const emit = defineEmits<{
40
+ finish: []
41
+ change: [timeData: TimeData]
42
+ }>()
43
+
44
+ const current = ref(props.time)
45
+ const counting = ref(false)
46
+ let timer: ReturnType<typeof setInterval> | null = null
47
+
48
+ const textStyle = computed(() => {
49
+ const fontSize = typeof props.fontSize === 'number' ? `${props.fontSize}px` : props.fontSize
50
+ return {
51
+ fontSize,
52
+ color: props.color || undefined
53
+ }
54
+ })
55
+
56
+ const padZero = (num: number, length: number = 2): string => {
57
+ return String(num).padStart(length, '0')
58
+ }
59
+
60
+ const timeData = computed<TimeData>(() => {
61
+ const total = current.value
62
+ const days = Math.floor(total / (1000 * 60 * 60 * 24))
63
+ const hours = Math.floor((total % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
64
+ const minutes = Math.floor((total % (1000 * 60 * 60)) / (1000 * 60))
65
+ const seconds = Math.floor((total % (1000 * 60)) / 1000)
66
+ const milliseconds = total % 1000
67
+
68
+ return {
69
+ days,
70
+ hours,
71
+ minutes,
72
+ seconds,
73
+ milliseconds,
74
+ total
75
+ }
76
+ })
77
+
78
+ const formattedTime = computed(() => {
79
+ const data = timeData.value
80
+ let result = props.format
81
+
82
+ // 按照从长到短的顺序替换,避免错误替换
83
+ const replacements: [string, string][] = [
84
+ ['DD', padZero(data.days)],
85
+ ['D', String(data.days)],
86
+ ['HH', padZero(data.hours)],
87
+ ['H', String(data.hours)],
88
+ ['mm', padZero(data.minutes)],
89
+ ['m', String(data.minutes)],
90
+ ['ss', padZero(data.seconds)],
91
+ ['s', String(data.seconds)],
92
+ ['SSS', padZero(data.milliseconds, 3)],
93
+ ['S', String(Math.floor(data.milliseconds / 100))]
94
+ ]
95
+
96
+ replacements.forEach(([key, value]) => {
97
+ result = result.replace(new RegExp(key, 'g'), value)
98
+ })
99
+
100
+ return result
101
+ })
102
+
103
+ const tick = () => {
104
+ if (current.value <= 0) {
105
+ stop()
106
+ emit('finish')
107
+ return
108
+ }
109
+
110
+ const interval = props.millisecond ? 10 : 1000
111
+ current.value = Math.max(0, current.value - interval)
112
+ emit('change', timeData.value)
113
+ }
114
+
115
+ const start = () => {
116
+ if (counting.value || current.value <= 0) return
117
+ counting.value = true
118
+ const interval = props.millisecond ? 10 : 1000
119
+ timer = setInterval(tick, interval)
120
+ }
121
+
122
+ const stop = () => {
123
+ if (timer) {
124
+ clearInterval(timer)
125
+ timer = null
126
+ }
127
+ counting.value = false
128
+ }
129
+
130
+ const pause = () => {
131
+ stop()
132
+ }
133
+
134
+ const reset = (newTime?: number) => {
135
+ stop()
136
+ current.value = newTime !== undefined ? newTime : props.time
137
+ if (props.autoStart) {
138
+ start()
139
+ }
140
+ }
141
+
142
+ watch(() => props.time, (val) => {
143
+ reset(val)
144
+ })
145
+
146
+ onMounted(() => {
147
+ if (props.autoStart) {
148
+ start()
149
+ }
150
+ })
151
+
152
+ onUnmounted(() => {
153
+ stop()
154
+ })
155
+
156
+ defineExpose({
157
+ start,
158
+ stop,
159
+ pause,
160
+ reset,
161
+ timeData
162
+ })
163
+ </script>
164
+
165
+ <script lang="ts">
166
+ export default {
167
+ options: {
168
+ virtualHost: true,
169
+ styleIsolation: 'shared'
170
+ }
171
+ }
172
+ </script>
173
+
174
+ <style lang="scss" scoped>
175
+ .u-count-down {
176
+ display: inline-block;
177
+
178
+ &__text {
179
+ font-variant-numeric: tabular-nums;
180
+ }
181
+ }
182
+ </style>