@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,3 @@
1
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill="currentColor" d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill="currentColor" d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z"/>
3
+ </svg>
@@ -0,0 +1,219 @@
1
+ // 导入所有 SVG 图标
2
+ import arrowDown from './icons/arrow-down.svg'
3
+ import arrowLeft from './icons/arrow-left.svg'
4
+ import arrowRight from './icons/arrow-right.svg'
5
+ import arrowUp from './icons/arrow-up.svg'
6
+ import check from './icons/check.svg'
7
+ import checkCircle from './icons/check-circle.svg'
8
+ import chevronLeft from './icons/chevron-left.svg'
9
+ import chevronRight from './icons/chevron-right.svg'
10
+ import clear from './icons/clear.svg'
11
+ import clearO from './icons/clear-o.svg'
12
+ import close from './icons/close.svg'
13
+ import code from './icons/code.svg'
14
+ import copy from './icons/copy.svg'
15
+ import deleteIcon from './icons/delete.svg'
16
+ import download from './icons/download.svg'
17
+ import edit from './icons/edit.svg'
18
+ import email from './icons/email.svg'
19
+ import error from './icons/error.svg'
20
+ import errorO from './icons/error-o.svg'
21
+ import expandLess from './icons/expand-less.svg'
22
+ import expandMore from './icons/expand-more.svg'
23
+ import eye from './icons/eye.svg'
24
+ import eyeOff from './icons/eye-off.svg'
25
+ import flag from './icons/flag.svg'
26
+ import flagO from './icons/flag-o.svg'
27
+ import fullscreen from './icons/fullscreen.svg'
28
+ import exitFullscreen from './icons/exit-fullscreen.svg'
29
+ import grid from './icons/grid.svg'
30
+ import heart from './icons/heart.svg'
31
+ import heartO from './icons/heart-o.svg'
32
+ import info from './icons/info.svg'
33
+ import infoO from './icons/info-o.svg'
34
+ import keyboardArrowDown from './icons/keyboard-arrow-down.svg'
35
+ import keyboardArrowLeft from './icons/keyboard-arrow-left.svg'
36
+ import keyboardArrowRight from './icons/keyboard-arrow-right.svg'
37
+ import keyboardArrowUp from './icons/keyboard-arrow-up.svg'
38
+ import like from './icons/like.svg'
39
+ import likeO from './icons/like-o.svg'
40
+ import link from './icons/link.svg'
41
+ import list from './icons/list.svg'
42
+ import lock from './icons/lock.svg'
43
+ import unlock from './icons/unlock.svg'
44
+ import loading from './icons/loading.svg'
45
+ import menu from './icons/menu.svg'
46
+ import menuO from './icons/menu-o.svg'
47
+ import message from './icons/message.svg'
48
+ import minus from './icons/minus.svg'
49
+ import notification from './icons/notification.svg'
50
+ import bell from './icons/bell.svg'
51
+ import phone from './icons/phone.svg'
52
+ import plus from './icons/plus.svg'
53
+ import question from './icons/question.svg'
54
+ import refresh from './icons/refresh.svg'
55
+ import refreshO from './icons/refresh-o.svg'
56
+ import reload from './icons/reload.svg'
57
+ import redo from './icons/redo.svg'
58
+ import undo from './icons/undo.svg'
59
+ import search from './icons/search.svg'
60
+ import searchO from './icons/search-o.svg'
61
+ import setting from './icons/setting.svg'
62
+ import share from './icons/share.svg'
63
+ import smile from './icons/smile.svg'
64
+ import smileO from './icons/smile-o.svg'
65
+ import star from './icons/star.svg'
66
+ import starO from './icons/star-o.svg'
67
+ import success from './icons/success.svg'
68
+ import successO from './icons/success-o.svg'
69
+ import tick from './icons/tick.svg'
70
+ import upload from './icons/upload.svg'
71
+ import user from './icons/user.svg'
72
+ import account from './icons/account.svg'
73
+ import group from './icons/group.svg'
74
+ import warning from './icons/warning.svg'
75
+ import warningO from './icons/warning-o.svg'
76
+ import zoomIn from './icons/zoom-in.svg'
77
+ import zoomOut from './icons/zoom-out.svg'
78
+ import sync from './icons/sync.svg'
79
+ import clock from './icons/clock.svg'
80
+ import bookmark from './icons/bookmark.svg'
81
+ import bookmarkO from './icons/bookmark-o.svg'
82
+ import chat from './icons/chat.svg'
83
+ import clipboard from './icons/clipboard.svg'
84
+
85
+ // 图标映射表
86
+ export const icons: Record<string, string> = {
87
+ // 箭头类
88
+ 'arrow-down': arrowDown,
89
+ 'arrow-left': arrowLeft,
90
+ 'arrow-right': arrowRight,
91
+ 'arrow-up': arrowUp,
92
+ 'chevron-left': chevronLeft,
93
+ 'chevron-right': chevronRight,
94
+ 'expand-less': expandLess,
95
+ 'expand-more': expandMore,
96
+ 'keyboard-arrow-down': keyboardArrowDown,
97
+ 'keyboard-arrow-left': keyboardArrowLeft,
98
+ 'keyboard-arrow-right': keyboardArrowRight,
99
+ 'keyboard-arrow-up': keyboardArrowUp,
100
+
101
+ // 操作类
102
+ 'check': check,
103
+ 'check-circle': checkCircle,
104
+ 'clear': clear,
105
+ 'clear-o': clearO,
106
+ 'close': close,
107
+ 'plus': plus,
108
+ 'minus': minus,
109
+ 'tick': tick,
110
+
111
+ // 编辑类
112
+ 'copy': copy,
113
+ 'cut': copy,
114
+ 'edit': edit,
115
+ 'delete': deleteIcon,
116
+ 'undo': undo,
117
+ 'redo': redo,
118
+
119
+ // 文件类
120
+ 'upload': upload,
121
+ 'download': download,
122
+ 'file': clipboard,
123
+ 'folder': clipboard,
124
+
125
+ // 状态类
126
+ 'success': success,
127
+ 'success-o': successO,
128
+ 'warning': warning,
129
+ 'warning-o': warningO,
130
+ 'error': error,
131
+ 'error-o': errorO,
132
+ 'info': info,
133
+ 'info-o': infoO,
134
+ 'question': question,
135
+ 'loading': loading,
136
+
137
+ // 社交类
138
+ 'heart': heart,
139
+ 'heart-o': heartO,
140
+ 'star': star,
141
+ 'star-o': starO,
142
+ 'like': like,
143
+ 'like-o': likeO,
144
+ 'share': share,
145
+
146
+ // 用户类
147
+ 'user': user,
148
+ 'account': account,
149
+ 'group': group,
150
+ 'smile': smile,
151
+ 'smile-o': smileO,
152
+
153
+ // 安全类
154
+ 'lock': lock,
155
+ 'unlock': unlock,
156
+ 'eye': eye,
157
+ 'eye-off': eyeOff,
158
+
159
+ // 交互类
160
+ 'search': search,
161
+ 'search-o': searchO,
162
+ 'zoom-in': zoomIn,
163
+ 'zoom-out': zoomOut,
164
+ 'refresh': refresh,
165
+ 'refresh-o': refreshO,
166
+ 'reload': reload,
167
+ 'sync': sync,
168
+ 'setting': setting,
169
+ 'fullscreen': fullscreen,
170
+ 'exit-fullscreen': exitFullscreen,
171
+
172
+ // 导航类
173
+ 'menu': menu,
174
+ 'menu-o': menuO,
175
+ 'list': list,
176
+ 'grid': grid,
177
+ 'more': expandMore,
178
+ 'less': expandLess,
179
+
180
+ // 通讯类
181
+ 'email': email,
182
+ 'phone': phone,
183
+ 'message': message,
184
+ 'chat': chat,
185
+ 'notification': notification,
186
+ 'bell': bell,
187
+ 'link': link,
188
+
189
+ // 标记类
190
+ 'flag': flag,
191
+ 'flag-o': flagO,
192
+ 'bookmark': bookmark,
193
+ 'bookmark-o': bookmarkO,
194
+ 'tag': flag,
195
+
196
+ // 其他
197
+ 'code': code,
198
+ 'clock': clock,
199
+ 'time': clock,
200
+ 'calendar': clock,
201
+ }
202
+
203
+ // 获取图标 SVG 内容
204
+ export function getIcon(name: string): string | undefined {
205
+ return icons[name]
206
+ }
207
+
208
+ // 获取所有图标名称
209
+ export function getIconNames(): string[] {
210
+ return Object.keys(icons)
211
+ }
212
+
213
+ // 添加自定义图标
214
+ export function addIcon(name: string, svg: string): void {
215
+ icons[name] = svg
216
+ }
217
+
218
+ // 默认导出所有图标
219
+ export default icons
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <view
3
+ class="u-icon"
4
+ :class="{ 'u-icon--spin': spin }"
5
+ :style="iconStyle"
6
+ @click="handleClick"
7
+ >
8
+ <!-- SVG 图标模式 -->
9
+ <image
10
+ v-if="isSvgIcon && iconSrc"
11
+ class="u-icon__svg"
12
+ :src="iconSrc"
13
+ :style="{ width: sizePx, height: sizePx }"
14
+ mode="aspectFit"
15
+ />
16
+ <!-- Emoji/文字模式 -->
17
+ <text v-else class="u-icon__inner">{{ name }}</text>
18
+ </view>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import { computed } from 'vue'
23
+ import { getIcon } from './index'
24
+
25
+ interface Props {
26
+ name: string
27
+ size?: number | string
28
+ color?: string
29
+ spin?: boolean
30
+ }
31
+
32
+ const props = withDefaults(defineProps<Props>(), {
33
+ size: 16
34
+ })
35
+
36
+ const emit = defineEmits<{
37
+ click: [event: MouseEvent]
38
+ }>()
39
+
40
+ const handleClick = (event: MouseEvent) => {
41
+ emit('click', event)
42
+ }
43
+
44
+ // 判断是否为 SVG 图标
45
+ const isSvgIcon = computed(() => {
46
+ return !!getIcon(props.name)
47
+ })
48
+
49
+ // 获取图标 SVG 资源
50
+ const iconSrc = computed(() => {
51
+ return getIcon(props.name)
52
+ })
53
+
54
+ // 尺寸转换为 px
55
+ const sizePx = computed(() => {
56
+ const size = typeof props.size === 'number' ? props.size : parseInt(props.size)
57
+ return size + 'px'
58
+ })
59
+
60
+ // 图标样式
61
+ const iconStyle = computed(() => {
62
+ const size = typeof props.size === 'number' ? props.size : parseInt(props.size)
63
+ const style: Record<string, string> = {
64
+ fontSize: size + 'px',
65
+ width: size + 'px',
66
+ height: size + 'px'
67
+ }
68
+ // SVG 图标通过 fill="currentColor" 支持颜色
69
+ // 但 image 标签不支持直接设置颜色,需要通过 filter 或特殊处理
70
+ if (props.color && !isSvgIcon.value) {
71
+ style.color = props.color
72
+ }
73
+ return style
74
+ })
75
+ </script>
76
+
77
+ <script lang="ts">
78
+ export default {
79
+ options: {
80
+ virtualHost: true,
81
+ styleIsolation: 'shared'
82
+ }
83
+ }
84
+ </script>
85
+
86
+ <style lang="scss" scoped>
87
+ .u-icon {
88
+ display: inline-flex;
89
+ align-items: center;
90
+ justify-content: center;
91
+ font-style: normal;
92
+ line-height: 1;
93
+
94
+ &--spin {
95
+ animation: u-icon-spin 1s linear infinite;
96
+ }
97
+
98
+ &__inner {
99
+ font-family: inherit;
100
+ line-height: 1;
101
+ }
102
+
103
+ &__svg {
104
+ display: block;
105
+ object-fit: contain;
106
+ }
107
+ }
108
+
109
+ @keyframes u-icon-spin {
110
+ from {
111
+ transform: rotate(0deg);
112
+ }
113
+ to {
114
+ transform: rotate(360deg);
115
+ }
116
+ }
117
+ </style>
@@ -0,0 +1,106 @@
1
+ <template>
2
+ <view class="u-image" :style="{ width: width + 'px', height: height + 'px' }">
3
+ <image
4
+ class="u-image__inner"
5
+ :src="src"
6
+ :mode="mode"
7
+ :lazy-load="lazyLoad"
8
+ :fade="fade"
9
+ @load="handleLoad"
10
+ @error="handleError"
11
+ />
12
+ <view v-if="loading && !loaded" class="u-image__loading">
13
+ <slot name="loading">
14
+ <u-loading :size="20" />
15
+ </slot>
16
+ </view>
17
+ <view v-if="error && !loaded" class="u-image__error">
18
+ <slot name="error">
19
+ <text class="u-image__error-text">加载失败</text>
20
+ </slot>
21
+ </view>
22
+ </view>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import { ref } from 'vue'
27
+
28
+ interface Props {
29
+ src: string
30
+ width?: number | string
31
+ height?: number | string
32
+ mode?: string
33
+ lazyLoad?: boolean
34
+ fade?: boolean
35
+ loading?: boolean
36
+ error?: boolean
37
+ }
38
+
39
+ withDefaults(defineProps<Props>(), {
40
+ width: 100,
41
+ height: 100,
42
+ mode: 'aspectFill',
43
+ lazyLoad: true,
44
+ fade: true,
45
+ loading: true,
46
+ error: true
47
+ })
48
+
49
+ const emit = defineEmits<{
50
+ load: [event: Event]
51
+ error: [event: Event]
52
+ }>()
53
+
54
+ const loaded = ref(false)
55
+
56
+ const handleLoad = (event: Event) => {
57
+ loaded.value = true
58
+ emit('load', event)
59
+ }
60
+
61
+ const handleError = (event: Event) => {
62
+ loaded.value = false
63
+ emit('error', event)
64
+ }
65
+ </script>
66
+
67
+ <script lang="ts">
68
+ export default {
69
+ options: {
70
+ virtualHost: true,
71
+ styleIsolation: 'shared'
72
+ }
73
+ }
74
+ </script>
75
+
76
+ <style lang="scss" scoped>
77
+ .u-image {
78
+ position: relative;
79
+ display: inline-block;
80
+ overflow: hidden;
81
+
82
+ &__inner {
83
+ width: 100%;
84
+ height: 100%;
85
+ display: block;
86
+ }
87
+
88
+ &__loading,
89
+ &__error {
90
+ position: absolute;
91
+ top: 0;
92
+ left: 0;
93
+ right: 0;
94
+ bottom: 0;
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ background-color: $--bg-color;
99
+ }
100
+
101
+ &__error-text {
102
+ font-size: $--font-size-sm;
103
+ color: $--text-color-3;
104
+ }
105
+ }
106
+ </style>
@@ -0,0 +1,208 @@
1
+ <template>
2
+ <view
3
+ class="u-input"
4
+ :class="{
5
+ 'u-input--disabled': disabled,
6
+ 'u-input--error': error,
7
+ 'u-input--focus': isFocus
8
+ }"
9
+ >
10
+ <view v-if="$slots.prefix || prefixIcon" class="u-input__prefix">
11
+ <slot name="prefix">
12
+ <text class="u-input__icon">{{ prefixIcon }}</text>
13
+ </slot>
14
+ </view>
15
+
16
+ <view class="u-input__body">
17
+ <input
18
+ class="u-input__control"
19
+ :type="type"
20
+ :value="modelValue"
21
+ :placeholder="placeholder"
22
+ :placeholder-style="placeholderStyle"
23
+ :placeholder-class="'u-input__placeholder'"
24
+ :disabled="disabled"
25
+ :maxlength="maxlength"
26
+ :focus="focus"
27
+ :confirm-type="confirmType"
28
+ :adjust-position="adjustPosition"
29
+ @input="handleInput"
30
+ @focus="handleFocus"
31
+ @blur="handleBlur"
32
+ @confirm="handleConfirm"
33
+ />
34
+ </view>
35
+
36
+ <view v-if="clearable && modelValue" class="u-input__clear" @click="handleClear">
37
+ <text class="u-input__clear-icon">×</text>
38
+ </view>
39
+
40
+ <view v-if="$slots.suffix || suffixIcon" class="u-input__suffix">
41
+ <slot name="suffix">
42
+ <text class="u-input__icon">{{ suffixIcon }}</text>
43
+ </slot>
44
+ </view>
45
+ </view>
46
+ </template>
47
+
48
+ <script setup lang="ts">
49
+ import { ref, computed } from 'vue'
50
+
51
+ type InputType = 'text' | 'number' | 'idcard' | 'digit' | 'password'
52
+ type ConfirmType = 'send' | 'search' | 'next' | 'go' | 'done'
53
+
54
+ interface Props {
55
+ modelValue?: string | number
56
+ type?: InputType
57
+ placeholder?: string
58
+ placeholderStyle?: string
59
+ disabled?: boolean
60
+ maxlength?: number
61
+ clearable?: boolean
62
+ focus?: boolean
63
+ error?: boolean
64
+ confirmType?: ConfirmType
65
+ adjustPosition?: boolean
66
+ prefixIcon?: string
67
+ suffixIcon?: string
68
+ }
69
+
70
+ const props = withDefaults(defineProps<Props>(), {
71
+ modelValue: '',
72
+ type: 'text',
73
+ placeholder: '请输入',
74
+ disabled: false,
75
+ maxlength: 140,
76
+ clearable: false,
77
+ focus: false,
78
+ error: false,
79
+ confirmType: 'done',
80
+ adjustPosition: true
81
+ })
82
+
83
+ const emit = defineEmits<{
84
+ 'update:modelValue': [value: string]
85
+ input: [value: string]
86
+ focus: [event: FocusEvent]
87
+ blur: [event: FocusEvent]
88
+ confirm: [value: string]
89
+ clear: []
90
+ }>()
91
+
92
+ const isFocus = ref(false)
93
+
94
+ const handleInput = (event: any) => {
95
+ const value = event.detail.value
96
+ emit('update:modelValue', value)
97
+ emit('input', value)
98
+ }
99
+
100
+ const handleFocus = (event: FocusEvent) => {
101
+ isFocus.value = true
102
+ emit('focus', event)
103
+ }
104
+
105
+ const handleBlur = (event: FocusEvent) => {
106
+ isFocus.value = false
107
+ emit('blur', event)
108
+ }
109
+
110
+ const handleConfirm = (event: any) => {
111
+ emit('confirm', event.detail.value)
112
+ }
113
+
114
+ const handleClear = () => {
115
+ emit('update:modelValue', '')
116
+ emit('input', '')
117
+ emit('clear')
118
+ }
119
+ </script>
120
+
121
+ <script lang="ts">
122
+ export default {
123
+ options: {
124
+ virtualHost: true,
125
+ styleIsolation: 'shared'
126
+ }
127
+ }
128
+ </script>
129
+
130
+ <style lang="scss" scoped>
131
+ .u-input {
132
+ display: flex;
133
+ align-items: center;
134
+ width: 100%;
135
+ height: $--input-height;
136
+ padding: 0 $--spacing-md;
137
+ background-color: $--bg-color-2;
138
+ border-radius: $--border-radius-md;
139
+ border: 1px solid $--border-color;
140
+ transition: all $--transition-duration;
141
+
142
+ &--focus {
143
+ border-color: $--color-primary;
144
+ }
145
+
146
+ &--error {
147
+ border-color: $--color-danger;
148
+ }
149
+
150
+ &--disabled {
151
+ background-color: $--bg-color;
152
+ }
153
+
154
+ &__body {
155
+ flex: 1;
156
+ display: flex;
157
+ align-items: center;
158
+ }
159
+
160
+ &__control {
161
+ flex: 1;
162
+ height: 100%;
163
+ font-size: $--font-size-md;
164
+ color: $--text-color;
165
+ background: transparent;
166
+ }
167
+
168
+ &__placeholder {
169
+ color: $--text-color-3;
170
+ }
171
+
172
+ &__prefix,
173
+ &__suffix {
174
+ display: flex;
175
+ align-items: center;
176
+ }
177
+
178
+ &__prefix {
179
+ margin-right: $--spacing-sm;
180
+ }
181
+
182
+ &__suffix {
183
+ margin-left: $--spacing-sm;
184
+ }
185
+
186
+ &__icon {
187
+ color: $--text-color-2;
188
+ font-size: $--font-size-md;
189
+ }
190
+
191
+ &__clear {
192
+ display: flex;
193
+ align-items: center;
194
+ justify-content: center;
195
+ width: 16px;
196
+ height: 16px;
197
+ margin-left: $--spacing-sm;
198
+ background-color: $--text-color-3;
199
+ border-radius: 50%;
200
+ }
201
+
202
+ &__clear-icon {
203
+ color: $--bg-color-2;
204
+ font-size: 12px;
205
+ line-height: 1;
206
+ }
207
+ }
208
+ </style>