oxy-uni-ui 1.2.3 → 2.1.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 (246) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/abstracts/variable.scss +512 -343
  3. package/components/common/util.ts +185 -32
  4. package/components/composables/index.ts +1 -0
  5. package/components/composables/usePopover.ts +24 -20
  6. package/components/composables/useVirtualScroll.ts +48 -21
  7. package/components/composables/useWindowResize.ts +35 -0
  8. package/components/oxy-action-sheet/index.scss +24 -11
  9. package/components/oxy-action-sheet/oxy-action-sheet.vue +27 -19
  10. package/components/oxy-action-sheet/types.ts +7 -0
  11. package/components/oxy-backtop/index.scss +4 -4
  12. package/components/oxy-backtop/oxy-backtop.vue +9 -6
  13. package/components/oxy-backtop/types.ts +7 -7
  14. package/components/oxy-badge/index.scss +4 -4
  15. package/components/oxy-badge/oxy-badge.vue +3 -3
  16. package/components/oxy-badge/types.ts +2 -2
  17. package/components/oxy-button/index.scss +5 -5
  18. package/components/oxy-button/oxy-button.vue +5 -1
  19. package/components/oxy-calendar/index.scss +15 -15
  20. package/components/oxy-calendar/oxy-calendar.vue +1 -0
  21. package/components/oxy-calendar/types.ts +5 -0
  22. package/components/oxy-calendar-view/month/index.scss +4 -4
  23. package/components/oxy-calendar-view/month/types.ts +36 -0
  24. package/components/oxy-calendar-view/monthPanel/index.scss +7 -8
  25. package/components/oxy-calendar-view/monthPanel/month-panel.vue +14 -8
  26. package/components/oxy-calendar-view/year/index.scss +5 -5
  27. package/components/oxy-calendar-view/yearPanel/index.scss +4 -4
  28. package/components/oxy-calendar-view/yearPanel/year-panel.vue +21 -5
  29. package/components/oxy-card/index.scss +2 -2
  30. package/components/oxy-cell/index.scss +8 -8
  31. package/components/oxy-checkbox/index.scss +12 -12
  32. package/components/oxy-checkbox-group/index.scss +2 -2
  33. package/components/oxy-circle/oxy-circle.vue +10 -7
  34. package/components/oxy-circle/types.ts +5 -5
  35. package/components/oxy-col/oxy-col.vue +2 -2
  36. package/components/oxy-col-picker/index.scss +4 -4
  37. package/components/oxy-col-picker/oxy-col-picker.vue +6 -5
  38. package/components/oxy-col-picker/types.ts +7 -2
  39. package/components/oxy-collapse/index.scss +2 -2
  40. package/components/oxy-collapse-item/oxy-collapse-item.vue +3 -3
  41. package/components/oxy-corner/index.scss +33 -33
  42. package/components/oxy-count-to/oxy-count-to.vue +3 -3
  43. package/components/oxy-curtain/index.scss +15 -15
  44. package/components/oxy-curtain/oxy-curtain.vue +4 -2
  45. package/components/oxy-curtain/types.ts +6 -1
  46. package/components/oxy-date-strip/oxy-date-strip.vue +2 -2
  47. package/components/oxy-date-strip/types.ts +1 -1
  48. package/components/oxy-date-strip-item/index.scss +3 -3
  49. package/components/oxy-datetime-picker/index.scss +11 -11
  50. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +1 -0
  51. package/components/oxy-datetime-picker/types.ts +5 -0
  52. package/components/oxy-drop-menu/index.scss +5 -5
  53. package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -3
  54. package/components/oxy-drop-menu-item/index.scss +3 -3
  55. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +4 -3
  56. package/components/oxy-drop-menu-item/types.ts +5 -0
  57. package/components/oxy-echarts/types.ts +6 -0
  58. package/components/oxy-fab/index.scss +8 -8
  59. package/components/oxy-fab/oxy-fab.vue +22 -3
  60. package/components/oxy-file-list/index.scss +30 -29
  61. package/components/oxy-file-list/oxy-file-list.vue +2 -2
  62. package/components/oxy-floating-panel/oxy-floating-panel.vue +13 -9
  63. package/components/oxy-floating-panel/{type.ts → types.ts} +8 -8
  64. package/components/oxy-footer/index.scss +19 -0
  65. package/components/oxy-footer/oxy-footer.vue +78 -0
  66. package/components/oxy-footer/types.ts +17 -0
  67. package/components/oxy-form-item/types.ts +22 -1
  68. package/components/oxy-gap/oxy-gap.vue +2 -2
  69. package/components/oxy-gap/types.ts +2 -2
  70. package/components/oxy-grid/oxy-grid.vue +1 -1
  71. package/components/oxy-grid/types.ts +1 -1
  72. package/components/oxy-grid-item/index.scss +1 -1
  73. package/components/oxy-grid-item/oxy-grid-item.vue +7 -5
  74. package/components/oxy-grid-item/types.ts +1 -1
  75. package/components/oxy-guidance/index.scss +75 -0
  76. package/components/oxy-guidance/oxy-guidance.vue +201 -0
  77. package/components/oxy-guidance/types.ts +33 -0
  78. package/components/oxy-icon/oxy-icon.vue +2 -2
  79. package/components/oxy-icon/types.ts +1 -1
  80. package/components/oxy-img/oxy-img.vue +4 -4
  81. package/components/oxy-img/types.ts +3 -3
  82. package/components/oxy-img-cropper/index.scss +23 -23
  83. package/components/oxy-img-cropper/oxy-img-cropper.vue +97 -52
  84. package/components/oxy-img-cropper/types.ts +2 -2
  85. package/components/oxy-img-lazy/oxy-img-lazy.vue +3 -3
  86. package/components/oxy-img-lazy/types.ts +3 -3
  87. package/components/oxy-index-anchor/index.scss +2 -2
  88. package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
  89. package/components/oxy-index-anchor/{type.ts → types.ts} +3 -0
  90. package/components/oxy-index-bar/index.scss +3 -3
  91. package/components/oxy-index-bar/oxy-index-bar.vue +3 -3
  92. package/components/oxy-index-bar/{type.ts → types.ts} +2 -2
  93. package/components/oxy-input/index.scss +1 -1
  94. package/components/oxy-input-number/index.scss +5 -5
  95. package/components/oxy-input-number/oxy-input-number.vue +2 -2
  96. package/components/oxy-input-number/types.ts +3 -2
  97. package/components/oxy-keyboard/index.scss +5 -5
  98. package/components/oxy-keyboard/key/index.scss +3 -3
  99. package/components/oxy-keyboard/key/index.vue +2 -2
  100. package/components/oxy-keyboard/key/types.ts +15 -0
  101. package/components/oxy-keyboard/oxy-keyboard.vue +1 -0
  102. package/components/oxy-keyboard/types.ts +5 -0
  103. package/components/oxy-link/index.scss +2 -2
  104. package/components/oxy-list/oxy-list.vue +4 -3
  105. package/components/oxy-loading/oxy-loading.vue +8 -4
  106. package/components/oxy-loading/types.ts +1 -1
  107. package/components/oxy-loadmore/index.scss +3 -3
  108. package/components/oxy-long-press-menu/index.scss +93 -0
  109. package/components/oxy-long-press-menu/oxy-long-press-menu.vue +338 -0
  110. package/components/oxy-long-press-menu/types.ts +34 -0
  111. package/components/oxy-message-box/index.scss +12 -11
  112. package/components/oxy-message-box/oxy-message-box.vue +9 -2
  113. package/components/oxy-message-box/types.ts +9 -0
  114. package/components/oxy-navbar/index.scss +2 -2
  115. package/components/oxy-navbar/oxy-navbar.vue +58 -13
  116. package/components/oxy-navbar/types.ts +8 -1
  117. package/components/oxy-navbar-capsule/types.ts +3 -0
  118. package/components/oxy-notice-bar/index.scss +3 -3
  119. package/components/oxy-notice-bar/oxy-notice-bar.vue +9 -5
  120. package/components/oxy-notice-bar/types.ts +3 -3
  121. package/components/oxy-notify/index.ts +1 -0
  122. package/components/oxy-notify/oxy-notify.vue +3 -2
  123. package/components/oxy-notify/types.ts +7 -0
  124. package/components/oxy-pagination/index.scss +6 -5
  125. package/components/oxy-password-input/oxy-password-input.vue +2 -2
  126. package/components/oxy-password-input/types.ts +1 -1
  127. package/components/oxy-picker/index.scss +45 -2
  128. package/components/oxy-picker/oxy-picker.vue +100 -14
  129. package/components/oxy-picker/types.ts +29 -1
  130. package/components/oxy-picker-view/index.scss +4 -4
  131. package/components/oxy-picker-view/oxy-picker-view.vue +4 -4
  132. package/components/oxy-popover/index.scss +13 -13
  133. package/components/oxy-popup/index.scss +4 -4
  134. package/components/oxy-popup/oxy-popup.vue +35 -2
  135. package/components/oxy-popup/types.ts +8 -1
  136. package/components/oxy-progress/index.scss +3 -3
  137. package/components/oxy-qrcode/draw.ts +398 -0
  138. package/components/oxy-qrcode/index.scss +2 -0
  139. package/components/oxy-qrcode/oxy-qrcode.vue +124 -0
  140. package/components/oxy-qrcode/qrcode.ts +936 -0
  141. package/components/oxy-qrcode/types.ts +42 -0
  142. package/components/oxy-radio/index.scss +25 -19
  143. package/components/oxy-radio-group/index.scss +2 -2
  144. package/components/oxy-rate/types.ts +4 -4
  145. package/components/oxy-resize/index.scss +2 -2
  146. package/components/oxy-resize/oxy-resize.vue +4 -4
  147. package/components/oxy-resize/types.ts +3 -0
  148. package/components/oxy-rich-text/index.scss +37 -36
  149. package/components/oxy-rich-text/mp-html/card/card.vue +3 -3
  150. package/components/oxy-rich-text/mp-html/mp-html.vue +33 -24
  151. package/components/oxy-rich-text/mp-html/node/node.vue +30 -19
  152. package/components/oxy-rich-text/oxy-rich-text.vue +31 -31
  153. package/components/oxy-rich-text/types.ts +6 -1
  154. package/components/oxy-row/oxy-row.vue +3 -3
  155. package/components/oxy-row/types.ts +1 -1
  156. package/components/oxy-search/index.scss +7 -7
  157. package/components/oxy-segmented/index.scss +19 -16
  158. package/components/oxy-segmented/oxy-segmented.vue +23 -3
  159. package/components/oxy-select/index.scss +213 -89
  160. package/components/oxy-select/oxy-select.vue +106 -58
  161. package/components/oxy-select/types.ts +13 -1
  162. package/components/oxy-select-picker/index.scss +7 -7
  163. package/components/oxy-select-picker/oxy-select-picker.vue +1 -0
  164. package/components/oxy-select-picker/types.ts +2 -0
  165. package/components/oxy-sidebar-item/index.scss +2 -2
  166. package/components/oxy-signature/oxy-signature.vue +18 -10
  167. package/components/oxy-signature/types.ts +106 -13
  168. package/components/oxy-skeleton/index.scss +1 -1
  169. package/components/oxy-skeleton/oxy-skeleton.vue +6 -6
  170. package/components/oxy-skeleton/types.ts +1 -1
  171. package/components/oxy-slider/index.scss +6 -6
  172. package/components/oxy-sort-button/index.scss +8 -8
  173. package/components/oxy-splitter/index.scss +19 -0
  174. package/components/oxy-splitter/oxy-splitter.vue +409 -0
  175. package/components/oxy-splitter/types.ts +75 -0
  176. package/components/oxy-splitter-panel/index.scss +366 -0
  177. package/components/oxy-splitter-panel/oxy-splitter-panel.vue +432 -0
  178. package/components/oxy-splitter-panel/types.ts +63 -0
  179. package/components/oxy-status-tip/index.scss +4 -4
  180. package/components/oxy-status-tip/oxy-status-tip.vue +5 -5
  181. package/components/oxy-status-tip/types.ts +3 -3
  182. package/components/oxy-step/index.scss +16 -16
  183. package/components/oxy-sticky/oxy-sticky.vue +6 -6
  184. package/components/oxy-stream-render/oxy-stream-render.vue +230 -4
  185. package/components/oxy-stream-render/types.ts +4 -1
  186. package/components/oxy-swipe-action/oxy-swipe-action.vue +27 -2
  187. package/components/oxy-swiper/oxy-swiper.vue +6 -6
  188. package/components/oxy-swiper/types.ts +5 -5
  189. package/components/oxy-swiper-nav/index.scss +3 -3
  190. package/components/oxy-switch/index.scss +10 -10
  191. package/components/oxy-switch/oxy-switch.vue +2 -2
  192. package/components/oxy-switch/types.ts +1 -1
  193. package/components/oxy-tab/index.scss +11 -1
  194. package/components/oxy-tabbar/index.scss +2 -2
  195. package/components/oxy-tabbar/oxy-tabbar.vue +39 -10
  196. package/components/oxy-table/index.scss +8 -8
  197. package/components/oxy-table/oxy-table.vue +8 -6
  198. package/components/oxy-table/types.ts +2 -2
  199. package/components/oxy-table-col/index.scss +3 -3
  200. package/components/oxy-table-col/oxy-table-col.vue +3 -3
  201. package/components/oxy-table-col/types.ts +2 -2
  202. package/components/oxy-tabs/index.scss +52 -22
  203. package/components/oxy-tabs/oxy-tabs.vue +53 -19
  204. package/components/oxy-tabs/types.ts +15 -3
  205. package/components/oxy-tag/index.scss +111 -36
  206. package/components/oxy-text/index.scss +5 -1
  207. package/components/oxy-text/oxy-text.vue +76 -7
  208. package/components/oxy-text/types.ts +12 -0
  209. package/components/oxy-textarea/index.scss +6 -6
  210. package/components/oxy-toast/oxy-toast.vue +24 -8
  211. package/components/oxy-tooltip/index.scss +9 -9
  212. package/components/oxy-tree/index.scss +51 -15
  213. package/components/oxy-tree/oxy-tree.vue +13 -9
  214. package/components/oxy-tree/types.ts +12 -9
  215. package/components/oxy-upload/index.scss +23 -23
  216. package/components/oxy-upload/types.ts +2 -2
  217. package/components/oxy-verification-code/index.scss +6 -0
  218. package/components/oxy-verification-code/oxy-verification-code.vue +187 -0
  219. package/components/oxy-verification-code/types.ts +82 -0
  220. package/components/oxy-video-preview/index.scss +4 -4
  221. package/components/oxy-virtual-scroll/index.scss +5 -5
  222. package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +11 -7
  223. package/components/oxy-virtual-scroll/types.ts +14 -14
  224. package/components/oxy-voice-player/index.scss +937 -0
  225. package/components/oxy-voice-player/oxy-voice-player.vue +821 -0
  226. package/components/oxy-voice-player/types.ts +567 -0
  227. package/components/oxy-waterfall/oxy-waterfall.vue +6 -6
  228. package/components/oxy-waterfall/types.ts +6 -6
  229. package/components/oxy-watermark/oxy-watermark.vue +35 -13
  230. package/components/oxy-watermark/types.ts +14 -14
  231. package/global.d.ts +4 -0
  232. package/locale/lang/ar-SA.ts +3 -0
  233. package/locale/lang/en-US.ts +3 -0
  234. package/locale/lang/zh-CN.ts +3 -0
  235. package/package.json +97 -1
  236. package/tags.json +1 -1
  237. package/web-types.json +1 -1
  238. package/components/oxy-number-keyboard/index.scss +0 -78
  239. package/components/oxy-number-keyboard/key/index.scss +0 -81
  240. package/components/oxy-number-keyboard/key/index.vue +0 -78
  241. package/components/oxy-number-keyboard/key/types.ts +0 -11
  242. package/components/oxy-number-keyboard/oxy-number-keyboard.vue +0 -151
  243. package/components/oxy-number-keyboard/types.ts +0 -83
  244. package/components/oxy-tree/components/tree-node-content.vue +0 -72
  245. package/components/oxy-tree/index.ts +0 -51
  246. package/oxy-uni-ui.zip +0 -0
@@ -17,13 +17,16 @@
17
17
 
18
18
  <view v-if="data.length" class="oxy-tree__virtual-scroll" :style="{ height: height }">
19
19
  <scroll-view class="oxy-tree__view" scroll-y :scroll-x="true" :scroll-top="scrollTop" @scroll="handleScroll">
20
- <view class="oxy-tree__container" :style="{ height: totalHeight + 'px' }">
21
- <view class="oxy-tree__items" :style="{ transform: `translateY(${virtualOffsetY}px)` }">
20
+ <view class="oxy-tree__container" :style="{ height: unitConvert(totalHeight, 0, { output: 'px' }) }">
21
+ <view class="oxy-tree__items" :style="{ transform: `translateY(${unitConvert(virtualOffsetY, 0, { output: 'px' })})` }">
22
22
  <view v-for="(item, index) in virtualData" :key="index">
23
23
  <view class="oxy-tree-node-content" :style="getNodeStyle(item)" :class="getNodeClass(item)" @click="handleNodeClick(item)">
24
24
  <!-- 兼容支付宝、微信小程序 -->
25
- <view @tap.stop="handleClickExpand(item)">
26
- <oxy-icon name="fill-arrow-down" custom-class="oxy-tree-node-icon" size="22px"></oxy-icon>
25
+ <view class="oxy-tree-node-toggle" @tap.stop="handleClickExpand(item)">
26
+ <oxy-icon
27
+ :name="expandedKeySet.has(item.key) ? 'chevron-down-circle' : 'chevron-right-circle'"
28
+ custom-class="oxy-tree-node-icon"
29
+ ></oxy-icon>
27
30
  </view>
28
31
  <oxy-checkbox
29
32
  v-if="showCheckbox"
@@ -49,7 +52,7 @@
49
52
 
50
53
  <!-- 回到顶部按钮 -->
51
54
  <view v-if="showBackToTop && showBackTopBtn" class="oxy-virtual-scroll__back-top" @click="scrollToTop">
52
- <oxy-icon name="backtop" color="#fff" size="20px"></oxy-icon>
55
+ <oxy-icon name="backtop" color="#fff" size="40rpx"></oxy-icon>
53
56
  </view>
54
57
  </view>
55
58
  </template>
@@ -71,6 +74,7 @@ import type { RawTreeNode, Tree, TreeInstance, TreeNode } from './types'
71
74
  import { treeProps, type TreeExpose } from './types'
72
75
  import { isSetsEqual, useTreeMethods } from './utils'
73
76
  import { useVirtualScroll } from '../composables/useVirtualScroll'
77
+ import { withDefaultUnit, unitConvert, unitConvertWithDefault } from '../common/util'
74
78
 
75
79
  // 获取组件的 props 和 emit 函数
76
80
  const props = defineProps(treeProps)
@@ -334,8 +338,8 @@ const updateValue = () => {
334
338
  }
335
339
  const getNodeStyle = (item: TreeNode) => {
336
340
  return {
337
- height: itemHeight.value,
338
- paddingLeft: `${(item.level - 1) * (props.indent || 16)}px`
341
+ height: withDefaultUnit(itemHeight.value, 'rpx'),
342
+ paddingLeft: withDefaultUnit((item.level - 1) * (props.indent || 16))
339
343
  }
340
344
  }
341
345
  const getNodeClass = (item: TreeNode) => {
@@ -384,8 +388,8 @@ const scrollToTop = () => {
384
388
  }
385
389
  const scrollToBottom = () => {
386
390
  const visibleCount = flattenTree.value.length
387
- const containerHeight = parseFloat(height.value || '0')
388
- const targetScrollTop = Math.max(visibleCount * parseFloat(itemHeight.value) - containerHeight, 0)
391
+ const containerHeight = unitConvert(height.value)
392
+ const targetScrollTop = Math.max(visibleCount * unitConvertWithDefault(itemHeight.value, { defaultUnit: 'rpx' }) - containerHeight, 0)
389
393
  virtualScrollToPosition(targetScrollTop)
390
394
  }
391
395
  const scrollToPosition = (position: number | string) => {
@@ -48,7 +48,7 @@ export const treeProps = {
48
48
  default: ''
49
49
  },
50
50
  emptyText: makeStringProp('暂无数据'),
51
- height: makeStringProp('300px'),
51
+ height: makeStringProp('600rpx'),
52
52
  /**
53
53
  * 是否显示回到顶部按钮
54
54
  * 类型:boolean
@@ -57,17 +57,20 @@ export const treeProps = {
57
57
  showBackToTop: makeBooleanProp(false),
58
58
  /**
59
59
  * 滚动多远显示backToTop
60
- * 类型:number
61
- * 默认值:'300px'
60
+ * 类型:string(支持 `px/rpx`,纯数字字符串按 rpx 处理)
61
+ * 默认值:'600rpx'
62
62
  */
63
- backToTopThreshold: makeStringProp('300px'),
63
+ backToTopThreshold: makeStringProp('600rpx'),
64
64
  /**
65
- * 单个项目高度
66
- * 类型:number
67
- * 默认值:'44px'
65
+ * 列表项的预估高度,需带单位
66
+ * @description 虚拟列表会根据此值计算占位高度,越准确滚动越平滑。支持如 '44px' 或 '88rpx',纯数字字符串按 rpx 处理。
67
+ * 默认值:'88rpx'
68
68
  */
69
- itemHeight: makeStringProp('44px'),
70
- indent: makeNumberProp(16),
69
+ itemHeight: makeStringProp('88rpx'),
70
+ /**
71
+ * 相邻级节点间的水平缩进,number 类型按 `rpx` 语义处理
72
+ */
73
+ indent: makeNumberProp(32),
71
74
  selectionLeafOnly: makeBooleanProp(false),
72
75
  filterMethod: {
73
76
  type: Function as PropType<(keyword: string, node: RawTreeNode) => boolean>,
@@ -39,7 +39,7 @@
39
39
  font-size: $-upload-evoke-icon-size;
40
40
  background-color: $-upload-evoke-bg;
41
41
  color: $-upload-evoke-color;
42
- margin-bottom: 12px;
42
+ margin-bottom: 28rpx;
43
43
 
44
44
  @include when(disabled) {
45
45
  color: $-upload-evoke-disabled-color;
@@ -47,18 +47,18 @@
47
47
  }
48
48
 
49
49
  @include e(evoke-file) {
50
- border-radius: 8px;
50
+ border-radius: $-upload-file-radius;
51
51
  }
52
52
 
53
53
  @include e(evoke-num) {
54
- font-size: 14px;
55
- line-height: 14px;
56
- margin-top: 8px;
54
+ font-size: $-fs-content;
55
+ line-height: $-fs-content;
56
+ margin-top: 20rpx;
57
57
  }
58
58
 
59
59
  @include edeep(evoke-icon) {
60
- width: 32px;
61
- height: 32px;
60
+ width: 64rpx;
61
+ height: 64rpx;
62
62
  }
63
63
 
64
64
  @include e(input) {
@@ -75,7 +75,7 @@
75
75
  position: relative;
76
76
  width: $-upload-size;
77
77
  height: $-upload-size;
78
- margin: 0 12px 12px 0;
78
+ margin: 0 24rpx 28rpx 0;
79
79
  }
80
80
 
81
81
  @include e(preview-list) {
@@ -106,9 +106,9 @@
106
106
  font-size: $-upload-file-fs;
107
107
  color: $-upload-file-color;
108
108
  box-sizing: border-box;
109
- padding: 0 4px;
109
+ padding: 0 12rpx;
110
110
  text-align: center;
111
- margin-top: 8px;
111
+ margin-top: 20rpx;
112
112
  @include lineEllipsis()
113
113
  }
114
114
 
@@ -117,11 +117,11 @@
117
117
  top: 50%;
118
118
  left: 50%;
119
119
  transform: translate(-50%, -50%);
120
- font-size: 24px;
120
+ font-size: $-upload-preview-icon-size;
121
121
  color: $-color-white;
122
122
 
123
123
  &::before {
124
- background-color: rgba(0, 0, 0, 0.5);
124
+ background-color: $-upload-video-play-bg;
125
125
  border-radius: 50%;
126
126
  }
127
127
  }
@@ -159,7 +159,7 @@
159
159
  @include e(progress-txt) {
160
160
  font-size: $-upload-progress-fs;
161
161
  line-height: $-upload-progress-fs;
162
- margin-top: 9px;
162
+ margin-top: 20rpx;
163
163
  color: $-color-white;
164
164
  }
165
165
 
@@ -178,21 +178,21 @@
178
178
  }
179
179
 
180
180
  @include e(preview-file) {
181
- margin-bottom: 32px;
181
+ margin-bottom: 64rpx;
182
182
  .oxy-upload__status-content:not(.oxy-upload__mask) {
183
183
  border: 1px solid $-color-border;
184
184
  box-sizing: border-box;
185
- border-radius: 8px;
185
+ border-radius: $-upload-file-radius;
186
186
  .oxy-upload__picture {
187
- border-radius: 8px;
187
+ border-radius: $-upload-file-radius;
188
188
  }
189
189
  .oxy-upload__picture-icon {
190
- width: 32px;
191
- height: 32px;
190
+ width: 64rpx;
191
+ height: 64rpx;
192
192
  }
193
193
  }
194
194
  .oxy-upload__mask {
195
- border-radius: 8px;
195
+ border-radius: $-upload-file-radius;
196
196
  }
197
197
  :deep(.oxy-tooltip) {
198
198
  width: 100%;
@@ -205,12 +205,12 @@
205
205
  .oxy-upload____status-content-name {
206
206
  display: block;
207
207
  width: 100%;
208
- font-size: $-upload-file-fs;
208
+ font-size: $-upload-preview-name-fs;
209
209
  color: $-upload-file-color;
210
210
  box-sizing: border-box;
211
- padding: 0 4px;
211
+ padding: 0 12rpx;
212
212
  text-align: center;
213
- margin-top: 8px;
213
+ margin-top: 20rpx;
214
214
  white-space: nowrap;
215
215
  overflow: hidden;
216
216
  text-overflow: ellipsis;
@@ -219,7 +219,7 @@
219
219
 
220
220
  &.oxy-upload__position-right {
221
221
  .oxy-upload__evoke {
222
- margin-right: 12px;
222
+ margin-right: 24rpx;
223
223
  }
224
224
  }
225
225
  }
@@ -283,9 +283,9 @@ export const uploadProps = {
283
283
  /**
284
284
  * 加载中图标尺寸
285
285
  * 类型:string
286
- * 默认值:'24px'
286
+ * 默认值:'48rpx'
287
287
  */
288
- loadingSize: makeStringProp('24px'),
288
+ loadingSize: makeStringProp('48rpx'),
289
289
  /**
290
290
  * 是否压缩视频,当 accept 为 video 时生效。
291
291
  * 类型:boolean
@@ -0,0 +1,6 @@
1
+ @import './../common/abstracts/_mixin.scss';
2
+ @import './../common/abstracts/variable.scss';
3
+
4
+ @include b(verification-code) {
5
+ display: inline-block;
6
+ }
@@ -0,0 +1,187 @@
1
+ <template>
2
+ <view :class="`oxy-verification-code ${customClass}`" :style="customStyle">
3
+ <!-- #ifdef MP-WEIXIN -->
4
+ <canvas :style="canvasStyle" :id="canvasId" :canvas-id="canvasId" type="2d" @tap="drawTap"></canvas>
5
+ <!-- #endif -->
6
+ <!-- #ifndef MP-WEIXIN -->
7
+ <canvas :width="canvasWidth" :height="canvasHeight" :style="canvasStyle" :id="canvasId" :canvas-id="canvasId" @tap="drawTap"></canvas>
8
+ <!-- #endif -->
9
+ </view>
10
+ </template>
11
+
12
+ <script lang="ts">
13
+ export default {
14
+ name: 'oxy-verification-code',
15
+ options: {
16
+ addGlobalClass: true,
17
+ virtualHost: true,
18
+ styleIsolation: 'shared'
19
+ }
20
+ }
21
+ </script>
22
+ <script lang="ts" setup>
23
+ import { computed, getCurrentInstance, ref, watch, onMounted } from 'vue'
24
+ import { objToStyle, unitConvert, unitConvertWithDefault, uuid } from '../common/util'
25
+ import { verificationCodeProps } from './types'
26
+ // #ifdef MP-WEIXIN
27
+ import { canvas2dAdapter } from '../common/canvasHelper'
28
+ // #endif
29
+
30
+ const props = defineProps(verificationCodeProps)
31
+ const { proxy } = getCurrentInstance() as any
32
+
33
+ const emit = defineEmits(['refresh'])
34
+
35
+ const pixelRatio = ref<number>(1) // 像素比
36
+ const canvasId = ref<string>(`oxy-verification-code${uuid()}`)
37
+ let ctx: UniApp.CanvasContext | null = null
38
+ const identifyCode = ref('')
39
+ const numberList = ref([1, 2, 3, 4, 5, 6, 7, 8, 9])
40
+ const letterList = ref(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'])
41
+ const canvasWidth = computed(() => unitConvertWithDefault(props.width, { defaultUnit: 'rpx' }))
42
+ const canvasHeight = computed(() => unitConvertWithDefault(props.height, { defaultUnit: 'rpx' }))
43
+
44
+ const canvasStyle = computed(() => {
45
+ const style = {
46
+ width: unitConvert(canvasWidth.value, 0, { output: 'px' }),
47
+ height: unitConvert(canvasHeight.value, 0, { output: 'px' })
48
+ }
49
+ return `${objToStyle(style)}`
50
+ })
51
+
52
+ watch(
53
+ () => props.securityCode,
54
+ (val) => {
55
+ if (val) drawPic()
56
+ },
57
+ { immediate: true }
58
+ )
59
+
60
+ function verification(code: string) {
61
+ if (props.isCaseCheck) {
62
+ return identifyCode.value == code
63
+ } else {
64
+ return identifyCode.value.toLowerCase() == code.toLowerCase()
65
+ }
66
+ }
67
+
68
+ function getCode() {
69
+ return identifyCode.value
70
+ }
71
+
72
+ function randomNum(min: number, max: number) {
73
+ return Math.floor(Math.random() * (max - min) + min)
74
+ }
75
+
76
+ function getcheckCode() {
77
+ let code = ''
78
+ const codeLength = props.codeLength
79
+ const random =
80
+ props.codeType === 'number' ? numberList.value : props.codeType === 'letter' ? letterList.value : [...numberList.value, ...letterList.value]
81
+ for (let i = 0; i < codeLength; i++) {
82
+ let index = Math.floor(Math.random() * random.length)
83
+ code += random[index]
84
+ }
85
+ identifyCode.value = code
86
+ }
87
+
88
+ function drawTap() {
89
+ if (props.securityCode) {
90
+ emit('refresh')
91
+ } else {
92
+ drawPic()
93
+ }
94
+ }
95
+
96
+ function getContext() {
97
+ return new Promise<UniApp.CanvasContext>((resolve) => {
98
+ if (ctx) {
99
+ return resolve(ctx)
100
+ }
101
+ // #ifndef MP-WEIXIN
102
+ ctx = uni.createCanvasContext(canvasId.value, proxy)
103
+ resolve(ctx)
104
+ // #endif
105
+ // #ifdef MP-WEIXIN
106
+ uni
107
+ .createSelectorQuery()
108
+ .in(proxy)
109
+ .select(`#${canvasId.value}`)
110
+ .node((res) => {
111
+ if (res && res.node) {
112
+ const canvas = res.node
113
+ ctx = canvas2dAdapter(canvas.getContext('2d') as CanvasRenderingContext2D)
114
+ canvas.width = canvasWidth.value * pixelRatio.value
115
+ canvas.height = canvasHeight.value * pixelRatio.value
116
+ ctx.scale(pixelRatio.value, pixelRatio.value)
117
+ resolve(ctx)
118
+ }
119
+ })
120
+ .exec()
121
+ // #endif
122
+ })
123
+ }
124
+
125
+ function drawPic() {
126
+ if (props.securityCode) {
127
+ identifyCode.value = props.securityCode
128
+ } else {
129
+ getcheckCode()
130
+ }
131
+ getContext().then((context) => {
132
+ context.setTextBaseline('bottom')
133
+ context.setFillStyle(props.backgroundColor)
134
+ context.fillRect(0, 0, canvasWidth.value, canvasHeight.value)
135
+ for (let i = 0; i < identifyCode.value.length; i++) {
136
+ drawText(context, identifyCode.value[i], i)
137
+ }
138
+ drawLine(context)
139
+ context.draw()
140
+ })
141
+ }
142
+
143
+ function drawText(context: any, txt: string, i: number) {
144
+ let a = Math.floor(Math.random() * props.colors.length)
145
+ context.setFillStyle(props.colors[a])
146
+
147
+ let fontSize = Math.trunc(canvasWidth.value / identifyCode.value.length)
148
+ context.setFontSize(randomNum(fontSize, fontSize))
149
+ let x = i * (canvasWidth.value / (identifyCode.value.length + 1)) + Math.trunc(fontSize / 2)
150
+ let y = randomNum(fontSize, canvasHeight.value - 5)
151
+ var deg = randomNum(-10, 10)
152
+
153
+ context.translate(x, y)
154
+ context.rotate((deg * Math.PI) / 180)
155
+ context.fillText(txt, 0, 0)
156
+
157
+ context.rotate((-deg * Math.PI) / 180)
158
+ context.translate(-x, -y)
159
+ }
160
+
161
+ function drawLine(context: any) {
162
+ for (let i = 0; i < props.lineLength; i++) {
163
+ let a = Math.floor(Math.random() * props.lineColors.length)
164
+ context.setStrokeStyle(props.lineColors[a])
165
+ context.beginPath()
166
+ let startX = randomNum(0, canvasWidth.value)
167
+ let startY = randomNum(0, canvasHeight.value)
168
+ let endX = randomNum(0, canvasWidth.value)
169
+ let endY = randomNum(0, canvasHeight.value)
170
+ context.moveTo(startX, startY)
171
+ context.lineTo(endX, endY)
172
+ context.stroke()
173
+ }
174
+ }
175
+
176
+ onMounted(() => {
177
+ drawPic()
178
+ })
179
+
180
+ defineExpose({
181
+ getCode,
182
+ verification
183
+ })
184
+ </script>
185
+ <style lang="scss" scoped>
186
+ @import './index.scss';
187
+ </style>
@@ -0,0 +1,82 @@
1
+ import type { PropType } from 'vue'
2
+ import { baseProps, makeBooleanProp, makeNumberProp, makeNumericProp, makeStringProp } from '../common/props'
3
+
4
+ export type VerificationCodeType = '' | 'number' | 'letter'
5
+
6
+ export const verificationCodeProps = {
7
+ ...baseProps,
8
+
9
+ /**
10
+ * 验证码值,如果是通过接口调用的验证码需要在这里传入,不传入则自动生成验证
11
+ * 类型: string
12
+ * 默认值: ''
13
+ */
14
+ securityCode: makeStringProp(''),
15
+
16
+ /**
17
+ * 是否校验字母大小写
18
+ * 类型: boolean
19
+ * 默认值: true
20
+ */
21
+ isCaseCheck: makeBooleanProp(true),
22
+
23
+ /**
24
+ * 验证码类型
25
+ * 类型: string
26
+ * 默认值: ''
27
+ */
28
+ codeType: makeStringProp<VerificationCodeType>(''),
29
+
30
+ /**
31
+ * 自动生成验证码数量
32
+ * 类型: number
33
+ * 默认值: 4
34
+ */
35
+ codeLength: makeNumberProp(4),
36
+
37
+ /**
38
+ * 画板宽度,支持 number / string(如 `240rpx`、`120px`),number 与纯数字字符串按 rpx 处理
39
+ * 类型: number | string
40
+ * 默认值: 240
41
+ */
42
+ width: makeNumericProp(240),
43
+
44
+ /**
45
+ * 画板高度,支持 number / string(如 `120rpx`、`60px`),number 与纯数字字符串按 rpx 处理
46
+ * 类型: number | string
47
+ * 默认值: 120
48
+ */
49
+ height: makeNumericProp(120),
50
+
51
+ /**
52
+ * 干扰线数量
53
+ * 类型: number
54
+ * 默认值: 8
55
+ */
56
+ lineLength: makeNumberProp(8),
57
+
58
+ /**
59
+ * 画板背景色
60
+ * 类型: string
61
+ * 默认值: 'rgba(238, 226, 224, 1)'
62
+ */
63
+ backgroundColor: makeStringProp('rgba(238, 226, 224, 1)'),
64
+
65
+ /**
66
+ * 干扰线可选颜色组(颜色会随机选择这些颜色,需要固定颜色传一种颜色即可)
67
+ * 类型: array
68
+ */
69
+ lineColors: {
70
+ type: Array as PropType<string[]>,
71
+ default: () => ['rgba(238, 0, 0, 0.5)', 'rgba(0, 170, 255, 0.5)', 'rgba(0, 170, 0, 0.5)', 'rgba(0, 0, 0, 0.5)', 'rgba(153, 146, 255, 0.5)']
72
+ },
73
+
74
+ /**
75
+ * 文字可选颜色组(颜色会随机选择这些颜色,需要固定颜色传一种颜色即可)
76
+ * 类型: array
77
+ */
78
+ colors: {
79
+ type: Array as PropType<string[]>,
80
+ default: () => ['rgba(238, 0, 0, 1)', 'rgba(0, 170, 255, 1)', 'rgba(0, 170, 0, 1)', 'rgba(0, 0, 0, 1)', 'rgba(153, 146, 255, 1)']
81
+ }
82
+ }
@@ -16,16 +16,16 @@
16
16
 
17
17
  @include e(video) {
18
18
  width: 100%;
19
- height: 242px;
19
+ height: 484rpx;
20
20
  transition: all 0.3s ease;
21
21
  }
22
22
 
23
23
  @include edeep(close) {
24
24
  position: absolute;
25
25
  box-sizing: border-box;
26
- top: 0px;
27
- right: 0px;
28
- padding: 12px;
26
+ top: 0;
27
+ right: 0;
28
+ padding: 24rpx;
29
29
  text-align: center;
30
30
  cursor: pointer;
31
31
  font-size: $-video-preview-close-font-size;
@@ -20,11 +20,11 @@
20
20
 
21
21
  @include e(back-top) {
22
22
  position: absolute;
23
- right: 20px;
24
- bottom: 20px;
25
- width: 40px;
26
- height: 40px;
27
- background: rgba(0, 0, 0, 0.6);
23
+ right: 40rpx;
24
+ bottom: 40rpx;
25
+ width: 80rpx;
26
+ height: 80rpx;
27
+ background: $-virtual-scroll-back-top-bg;
28
28
  border-radius: 50%;
29
29
  display: flex;
30
30
  align-items: center;
@@ -7,10 +7,10 @@
7
7
  class="oxy-virtual-scroll__view"
8
8
  :scroll-y="scrollY"
9
9
  :scroll-x="scrollX"
10
- :upper-threshold="upperThreshold"
11
- :lower-threshold="lowerThreshold"
10
+ :upper-threshold="upperThresholdInPx"
11
+ :lower-threshold="lowerThresholdInPx"
12
12
  :scroll-top="scrollTop"
13
- :scroll-left="scrollLeft"
13
+ :scroll-left="scrollLeftInPx"
14
14
  :scroll-with-animation="scrollWithAnimation"
15
15
  :enable-back-to-top="enableBackToTop"
16
16
  :show-scrollbar="showScrollbar"
@@ -25,8 +25,8 @@
25
25
  @scrolltoupper="onScrollUpper"
26
26
  @scrolltolower="onScrollLower"
27
27
  >
28
- <view class="oxy-virtual-scroll__container" :style="{ height: totalHeight + 'px' }">
29
- <view class="oxy-virtual-scroll__items" :style="{ transform: `translateY(${virtualOffsetY}px)` }">
28
+ <view class="oxy-virtual-scroll__container" :style="{ height: unitConvert(totalHeight, 0, { output: 'px' }) }">
29
+ <view class="oxy-virtual-scroll__items" :style="{ transform: `translateY(${unitConvert(virtualOffsetY, 0, { output: 'px' })})` }">
30
30
  <view v-for="(item, index) in virtualData" :key="index">
31
31
  <slot name="item" :item="item" :index="startIndex + index"></slot>
32
32
  </view>
@@ -41,7 +41,7 @@
41
41
 
42
42
  <!-- 回到顶部按钮 -->
43
43
  <view v-if="showBackToTop && showBackTopBtn" class="oxy-virtual-scroll__back-top" @click="scrollToTop">
44
- <oxy-icon name="backtop" color="#fff" size="20px"></oxy-icon>
44
+ <oxy-icon name="backtop" color="#fff" size="40rpx"></oxy-icon>
45
45
  </view>
46
46
  </view>
47
47
  </template>
@@ -58,13 +58,17 @@ export default {
58
58
  </script>
59
59
 
60
60
  <script lang="ts" setup>
61
- import { toRefs } from 'vue'
61
+ import { computed, toRefs } from 'vue'
62
62
  import type { ScrollViewOnScrollEvent, ScrollViewOnScrolltolowerEvent, ScrollViewOnScrolltoupperEvent } from '@uni-helper/uni-app-types'
63
63
  import { virtualScrollProps, type VirtualScrollExpose } from './types'
64
64
  import { useVirtualScroll } from '../composables/useVirtualScroll'
65
+ import { unitConvert, unitConvertWithDefault } from '../common/util'
65
66
 
66
67
  const props = defineProps(virtualScrollProps)
67
68
  const emit = defineEmits(['scroll', 'scroll-to-upper', 'scroll-to-lower'])
69
+ const upperThresholdInPx = computed(() => unitConvertWithDefault(props.upperThreshold, { defaultUnit: 'rpx' }))
70
+ const lowerThresholdInPx = computed(() => unitConvertWithDefault(props.lowerThreshold, { defaultUnit: 'rpx' }))
71
+ const scrollLeftInPx = computed(() => unitConvertWithDefault(props.scrollLeft, { defaultUnit: 'rpx' }))
68
72
 
69
73
  // 解构props用于组合式函数
70
74
  const { data, virtual, height, itemHeight, idKey, showBackToTop, backToTopThreshold } = toRefs(props)
@@ -30,16 +30,16 @@ export const virtualScrollProps = {
30
30
  showBackToTop: makeBooleanProp(false),
31
31
  /**
32
32
  * 滚动多远显示backToTop
33
- * 类型:number
34
- * 默认值:'300px'
33
+ * 类型:string(支持 `px/rpx`,纯数字字符串按 rpx 处理)
34
+ * 默认值:'600rpx'
35
35
  */
36
- backToTopThreshold: makeStringProp('300px'),
36
+ backToTopThreshold: makeStringProp('600rpx'),
37
37
  /**
38
- * 单个项目高度
39
- * 类型:number
40
- * 默认值:'44px'
38
+ * 列表项的预估高度,需带单位
39
+ * @description 虚拟列表会根据此值计算占位高度,越准确滚动越平滑。支持如 '44px' 或 '88rpx',纯数字字符串按 rpx 处理。
40
+ * 默认值:'88rpx'
41
41
  */
42
- itemHeight: makeStringProp('44px'),
42
+ itemHeight: makeStringProp('88rpx'),
43
43
  /**
44
44
  * 是否开启水平滚动
45
45
  * 类型:boolean
@@ -53,19 +53,19 @@ export const virtualScrollProps = {
53
53
  */
54
54
  scrollY: makeBooleanProp(true),
55
55
  /**
56
- * 距顶部/左边多远时(单位px),触发 scrolltoupper 事件
56
+ * 距顶部/左边多远时触发 scrolltoupper 事件,支持 `px/rpx`,number 与纯数字字符串按 rpx 处理
57
57
  * 类型:number | string
58
- * 默认值:50
58
+ * 默认值:100
59
59
  */
60
- upperThreshold: makeNumericProp(50),
60
+ upperThreshold: makeNumericProp(100),
61
61
  /**
62
- * 距底部/右边多远时(单位px),触发 scrolltolower 事件
62
+ * 距底部/右边多远时触发 scrolltolower 事件,支持 `px/rpx`,number 与纯数字字符串按 rpx 处理
63
63
  * 类型:number | string
64
- * 默认值:50
64
+ * 默认值:100
65
65
  */
66
- lowerThreshold: makeNumericProp(50),
66
+ lowerThreshold: makeNumericProp(100),
67
67
  /**
68
- * 设置横向滚动条位置
68
+ * 设置横向滚动条位置,支持 `px/rpx`,number 与纯数字字符串按 rpx 处理
69
69
  * 类型:number | string
70
70
  * 默认值:0
71
71
  */