oxy-uni-ui 2.1.2 → 2.1.3

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 (261) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/AbortablePromise.ts +4 -0
  3. package/components/common/abstracts/variable.scss +172 -66
  4. package/components/common/base64.ts +6 -0
  5. package/components/common/clickoutside.ts +5 -0
  6. package/components/common/interceptor.ts +9 -0
  7. package/components/common/path.ts +4 -0
  8. package/components/common/props.ts +23 -0
  9. package/components/common/util.ts +18 -1
  10. package/components/composables/index.ts +2 -0
  11. package/components/composables/useCell.ts +8 -1
  12. package/components/composables/useChildren.ts +27 -1
  13. package/components/composables/useCountDown.ts +10 -1
  14. package/components/composables/useDynamicVirtualScroll.ts +9 -0
  15. package/components/composables/useGlobalLoading.ts +6 -0
  16. package/components/composables/useGlobalMessage.ts +6 -0
  17. package/components/composables/useGlobalToast.ts +6 -0
  18. package/components/composables/useLockScroll.ts +9 -0
  19. package/components/composables/useParent.ts +65 -14
  20. package/components/composables/usePopover.ts +9 -0
  21. package/components/composables/useQueue.ts +8 -0
  22. package/components/composables/useRaf.ts +10 -0
  23. package/components/composables/useSharedState.ts +284 -0
  24. package/components/composables/useTouch.ts +8 -0
  25. package/components/composables/useTranslate.ts +9 -0
  26. package/components/composables/useUpload.ts +83 -11
  27. package/components/composables/useVirtualScroll.ts +7 -0
  28. package/components/composables/useWindowResize.ts +9 -0
  29. package/components/oxy-action-sheet/index.scss +5 -5
  30. package/components/oxy-action-sheet/oxy-action-sheet.vue +11 -0
  31. package/components/oxy-backtop/index.scss +2 -2
  32. package/components/oxy-backtop/oxy-backtop.vue +2 -0
  33. package/components/oxy-badge/oxy-badge.vue +2 -0
  34. package/components/oxy-badge/types.ts +3 -0
  35. package/components/oxy-button/index.scss +13 -13
  36. package/components/oxy-button/oxy-button.vue +11 -0
  37. package/components/oxy-button/types.ts +3 -3
  38. package/components/oxy-calendar/index.scss +17 -17
  39. package/components/oxy-calendar/oxy-calendar.vue +31 -0
  40. package/components/oxy-calendar/types.ts +3 -0
  41. package/components/oxy-calendar-view/month/month.vue +2 -0
  42. package/components/oxy-calendar-view/monthPanel/month-panel.vue +3 -1
  43. package/components/oxy-calendar-view/monthPanel/types.ts +10 -7
  44. package/components/oxy-calendar-view/oxy-calendar-view.vue +2 -0
  45. package/components/oxy-calendar-view/types.ts +3 -1
  46. package/components/oxy-calendar-view/year/types.ts +33 -1
  47. package/components/oxy-calendar-view/year/year.vue +2 -0
  48. package/components/oxy-calendar-view/yearPanel/year-panel.vue +2 -0
  49. package/components/oxy-card/index.scss +1 -1
  50. package/components/oxy-card/oxy-card.vue +2 -0
  51. package/components/oxy-cell/index.scss +3 -1
  52. package/components/oxy-cell/oxy-cell.vue +6 -4
  53. package/components/oxy-cell-group/oxy-cell-group.vue +2 -0
  54. package/components/oxy-checkbox/index.scss +7 -7
  55. package/components/oxy-checkbox/oxy-checkbox.vue +22 -16
  56. package/components/oxy-checkbox/types.ts +9 -0
  57. package/components/oxy-checkbox-group/index.scss +1 -1
  58. package/components/oxy-checkbox-group/oxy-checkbox-group.vue +2 -0
  59. package/components/oxy-circle/oxy-circle.vue +2 -0
  60. package/components/oxy-col/oxy-col.vue +3 -1
  61. package/components/oxy-col-picker/index.scss +3 -3
  62. package/components/oxy-col-picker/oxy-col-picker.vue +17 -1
  63. package/components/oxy-col-picker/types.ts +3 -0
  64. package/components/oxy-collapse/index.scss +2 -2
  65. package/components/oxy-collapse/oxy-collapse.vue +9 -0
  66. package/components/oxy-collapse-item/oxy-collapse-item.vue +4 -2
  67. package/components/oxy-config-provider/oxy-config-provider.vue +18 -0
  68. package/components/oxy-config-provider/types.ts +18 -0
  69. package/components/oxy-corner/index.scss +50 -32
  70. package/components/oxy-corner/oxy-corner.vue +2 -0
  71. package/components/oxy-count-down/oxy-count-down.vue +2 -0
  72. package/components/oxy-count-to/oxy-count-to.vue +12 -1
  73. package/components/oxy-count-to/types.ts +14 -4
  74. package/components/oxy-curtain/index.scss +10 -9
  75. package/components/oxy-curtain/oxy-curtain.vue +2 -0
  76. package/components/oxy-date-strip/oxy-date-strip.vue +22 -1
  77. package/components/oxy-date-strip-item/index.scss +4 -4
  78. package/components/oxy-date-strip-item/oxy-date-strip-item.vue +2 -0
  79. package/components/oxy-datetime-picker/index.scss +3 -3
  80. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +11 -1
  81. package/components/oxy-datetime-picker-view/oxy-datetime-picker-view.vue +2 -0
  82. package/components/oxy-divider/oxy-divider.vue +2 -0
  83. package/components/oxy-drop-menu/index.scss +2 -2
  84. package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -0
  85. package/components/oxy-drop-menu-item/index.scss +1 -1
  86. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +17 -9
  87. package/components/oxy-echarts/oxy-echarts.vue +2 -0
  88. package/components/oxy-fab/index.scss +1 -1
  89. package/components/oxy-fab/oxy-fab.vue +27 -0
  90. package/components/oxy-file-list/index.scss +9 -9
  91. package/components/oxy-file-list/oxy-file-list.vue +29 -17
  92. package/components/oxy-floating-panel/oxy-floating-panel.vue +34 -10
  93. package/components/oxy-footer/index.scss +7 -0
  94. package/components/oxy-footer/oxy-footer.vue +4 -2
  95. package/components/oxy-footer/types.ts +9 -6
  96. package/components/oxy-form/oxy-form.vue +13 -1
  97. package/components/oxy-form-item/oxy-form-item.vue +5 -3
  98. package/components/oxy-gap/oxy-gap.vue +2 -0
  99. package/components/oxy-global-loading/oxy-global-loading.vue +18 -5
  100. package/components/oxy-global-message/oxy-global-message.vue +30 -17
  101. package/components/oxy-global-toast/oxy-global-toast.vue +18 -5
  102. package/components/oxy-grid/oxy-grid.vue +6 -0
  103. package/components/oxy-grid-item/index.scss +1 -1
  104. package/components/oxy-grid-item/oxy-grid-item.vue +22 -20
  105. package/components/oxy-guidance/index.scss +9 -9
  106. package/components/oxy-guidance/oxy-guidance.vue +22 -16
  107. package/components/oxy-icon/oxy-icon.vue +2 -0
  108. package/components/oxy-icon/types.ts +3 -0
  109. package/components/oxy-image-preview/index.scss +75 -0
  110. package/components/oxy-image-preview/index.ts +56 -0
  111. package/components/oxy-image-preview/oxy-image-preview.vue +221 -0
  112. package/components/oxy-image-preview/types.ts +164 -0
  113. package/components/oxy-img/oxy-img.vue +2 -0
  114. package/components/oxy-img-cropper/index.scss +2 -2
  115. package/components/oxy-img-cropper/oxy-img-cropper.vue +6 -0
  116. package/components/oxy-img-lazy/oxy-img-lazy.vue +9 -0
  117. package/components/oxy-index-anchor/index.scss +1 -1
  118. package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
  119. package/components/oxy-index-bar/index.scss +1 -1
  120. package/components/oxy-index-bar/oxy-index-bar.vue +18 -0
  121. package/components/oxy-input/index.scss +2 -1
  122. package/components/oxy-input/oxy-input.vue +18 -4
  123. package/components/oxy-input/types.ts +6 -0
  124. package/components/oxy-input-number/index.scss +3 -1
  125. package/components/oxy-input-number/oxy-input-number.vue +2 -0
  126. package/components/oxy-keyboard/index.scss +3 -3
  127. package/components/oxy-keyboard/key/index.vue +2 -0
  128. package/components/oxy-keyboard/oxy-keyboard.vue +11 -2
  129. package/components/oxy-link/index.scss +8 -4
  130. package/components/oxy-link/oxy-link.vue +9 -3
  131. package/components/oxy-link/types.ts +2 -2
  132. package/components/oxy-list/oxy-list.vue +2 -0
  133. package/components/oxy-list/types.ts +7 -0
  134. package/components/oxy-loading/oxy-loading.vue +6 -0
  135. package/components/oxy-loadmore/index.scss +1 -1
  136. package/components/oxy-loadmore/oxy-loadmore.vue +2 -0
  137. package/components/oxy-long-press-menu/index.scss +1 -1
  138. package/components/oxy-long-press-menu/oxy-long-press-menu.vue +42 -13
  139. package/components/oxy-message-box/index.scss +223 -36
  140. package/components/oxy-message-box/index.ts +49 -23
  141. package/components/oxy-message-box/oxy-message-box.vue +181 -56
  142. package/components/oxy-message-box/types.ts +60 -2
  143. package/components/oxy-navbar/index.scss +1 -1
  144. package/components/oxy-navbar/oxy-navbar.vue +9 -6
  145. package/components/oxy-navbar-capsule/oxy-navbar-capsule.vue +2 -0
  146. package/components/oxy-notice-bar/index.scss +1 -1
  147. package/components/oxy-notice-bar/oxy-notice-bar.vue +29 -0
  148. package/components/oxy-notify/index.ts +16 -12
  149. package/components/oxy-notify/oxy-notify.vue +11 -4
  150. package/components/oxy-overlay/oxy-overlay.vue +34 -2
  151. package/components/oxy-pagination/oxy-pagination.vue +2 -0
  152. package/components/oxy-password-input/oxy-password-input.vue +2 -0
  153. package/components/oxy-picker/index.scss +7 -7
  154. package/components/oxy-picker/oxy-picker.vue +11 -0
  155. package/components/oxy-picker-view/index.scss +1 -1
  156. package/components/oxy-picker-view/oxy-picker-view.vue +2 -0
  157. package/components/oxy-popover/index.scss +2 -2
  158. package/components/oxy-popover/oxy-popover.vue +4 -1
  159. package/components/oxy-popup/oxy-popup.vue +8 -0
  160. package/components/oxy-progress/index.scss +2 -2
  161. package/components/oxy-progress/oxy-progress.vue +7 -0
  162. package/components/oxy-qrcode/draw.ts +15 -1
  163. package/components/oxy-qrcode/oxy-qrcode.vue +10 -3
  164. package/components/oxy-radio/index.scss +8 -8
  165. package/components/oxy-radio/oxy-radio.vue +13 -11
  166. package/components/oxy-radio-group/index.scss +1 -1
  167. package/components/oxy-radio-group/oxy-radio-group.vue +2 -0
  168. package/components/oxy-rate/oxy-rate.vue +5 -0
  169. package/components/oxy-rate/types.ts +2 -2
  170. package/components/oxy-resize/oxy-resize.vue +12 -0
  171. package/components/oxy-rich-text/index.scss +9 -9
  172. package/components/oxy-rich-text/oxy-rich-text.vue +6 -0
  173. package/components/oxy-rich-text/types.ts +15 -0
  174. package/components/oxy-root-portal/oxy-root-portal.vue +23 -15
  175. package/components/oxy-row/oxy-row.vue +2 -0
  176. package/components/oxy-search/index.scss +3 -3
  177. package/components/oxy-search/oxy-search.vue +19 -0
  178. package/components/oxy-segmented/index.scss +4 -4
  179. package/components/oxy-segmented/oxy-segmented.vue +2 -0
  180. package/components/oxy-select/index.scss +25 -25
  181. package/components/oxy-select/oxy-select.vue +27 -0
  182. package/components/oxy-select/types.ts +3 -0
  183. package/components/oxy-select-picker/index.scss +5 -5
  184. package/components/oxy-select-picker/oxy-select-picker.vue +7 -0
  185. package/components/oxy-sidebar/oxy-sidebar.vue +2 -0
  186. package/components/oxy-sidebar-item/index.scss +3 -3
  187. package/components/oxy-sidebar-item/oxy-sidebar-item.vue +17 -31
  188. package/components/oxy-signature/oxy-signature.vue +17 -0
  189. package/components/oxy-skeleton/oxy-skeleton.vue +7 -1
  190. package/components/oxy-slide-verify/index.scss +95 -0
  191. package/components/oxy-slide-verify/oxy-slide-verify.vue +244 -0
  192. package/components/oxy-slide-verify/types.ts +98 -0
  193. package/components/oxy-slider/oxy-slider.vue +3 -0
  194. package/components/oxy-sort-button/index.scss +10 -8
  195. package/components/oxy-sort-button/oxy-sort-button.vue +6 -0
  196. package/components/oxy-splitter/index.scss +9 -0
  197. package/components/oxy-splitter/oxy-splitter.vue +23 -2
  198. package/components/oxy-splitter-panel/index.scss +7 -5
  199. package/components/oxy-splitter-panel/oxy-splitter-panel.vue +93 -89
  200. package/components/oxy-status-tip/index.scss +3 -3
  201. package/components/oxy-status-tip/oxy-status-tip.vue +2 -0
  202. package/components/oxy-step/index.scss +4 -4
  203. package/components/oxy-step/oxy-step.vue +15 -13
  204. package/components/oxy-steps/oxy-steps.vue +2 -0
  205. package/components/oxy-sticky/oxy-sticky.vue +5 -3
  206. package/components/oxy-stream-render/oxy-stream-render.vue +29 -0
  207. package/components/oxy-swipe-action/oxy-swipe-action.vue +8 -0
  208. package/components/oxy-swiper/oxy-swiper.vue +6 -0
  209. package/components/oxy-swiper-nav/index.scss +4 -4
  210. package/components/oxy-switch/index.scss +6 -3
  211. package/components/oxy-switch/oxy-switch.vue +10 -0
  212. package/components/oxy-tab/index.scss +1 -7
  213. package/components/oxy-tab/oxy-tab.vue +12 -10
  214. package/components/oxy-tabbar/oxy-tabbar.vue +5 -0
  215. package/components/oxy-tabbar-item/oxy-tabbar-item.vue +11 -9
  216. package/components/oxy-table/index.scss +1 -1
  217. package/components/oxy-table/oxy-table.vue +8 -0
  218. package/components/oxy-table/types.ts +3 -0
  219. package/components/oxy-table-col/oxy-table-col.vue +21 -19
  220. package/components/oxy-tabs/index.scss +11 -11
  221. package/components/oxy-tabs/oxy-tabs.vue +17 -0
  222. package/components/oxy-tag/index.scss +24 -5
  223. package/components/oxy-tag/oxy-tag.vue +17 -2
  224. package/components/oxy-tag/types.ts +7 -0
  225. package/components/oxy-text/oxy-text.vue +12 -1
  226. package/components/oxy-textarea/index.scss +3 -2
  227. package/components/oxy-textarea/oxy-textarea.vue +10 -4
  228. package/components/oxy-toast/index.ts +21 -20
  229. package/components/oxy-toast/oxy-toast.vue +30 -5
  230. package/components/oxy-toast/types.ts +20 -9
  231. package/components/oxy-tooltip/index.scss +1 -1
  232. package/components/oxy-tooltip/oxy-tooltip.vue +2 -0
  233. package/components/oxy-transition/index.scss +3 -1
  234. package/components/oxy-transition/oxy-transition.vue +14 -0
  235. package/components/oxy-tree/index.scss +3 -3
  236. package/components/oxy-tree/oxy-tree.vue +28 -5
  237. package/components/oxy-tree/types.ts +57 -1
  238. package/components/oxy-upload/index.scss +9 -9
  239. package/components/oxy-upload/oxy-upload.vue +5 -3
  240. package/components/oxy-verification-code/oxy-verification-code.vue +24 -0
  241. package/components/oxy-video-preview/index.scss +12 -7
  242. package/components/oxy-video-preview/index.ts +64 -0
  243. package/components/oxy-video-preview/oxy-video-preview.vue +102 -31
  244. package/components/oxy-video-preview/types.ts +54 -8
  245. package/components/oxy-virtual-scroll/index.scss +1 -1
  246. package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +2 -0
  247. package/components/oxy-voice-player/index.scss +64 -64
  248. package/components/oxy-voice-player/oxy-voice-player.vue +38 -10
  249. package/components/oxy-waterfall/oxy-waterfall.vue +13 -0
  250. package/components/oxy-waterfall/types.ts +7 -0
  251. package/components/oxy-waterfall-item/oxy-waterfall-item.vue +9 -0
  252. package/components/oxy-watermark/oxy-watermark.vue +2 -0
  253. package/global.d.ts +2 -0
  254. package/index.ts +2 -0
  255. package/locale/lang/en-US.ts +51 -2
  256. package/locale/lang/zh-CN.ts +51 -2
  257. package/package.json +2 -2
  258. package/styles/all.scss +125 -0
  259. package/tags.json +1 -1
  260. package/vite-plugins/vite-plugin-host-class.ts +166 -0
  261. package/web-types.json +1 -1
@@ -21,7 +21,9 @@ export default {
21
21
  name: 'oxy-sidebar-item',
22
22
  options: {
23
23
  addGlobalClass: true,
24
+ // #ifndef MP-TOUTIAO
24
25
  virtualHost: true,
26
+ // #endif
25
27
  styleIsolation: 'shared'
26
28
  }
27
29
  }
@@ -39,7 +41,7 @@ import { deepAssign, isDef, isUndefined, omitBy } from '../common/util'
39
41
 
40
42
  const props = defineProps(sidebarItemProps)
41
43
 
42
- const { parent: sidebar } = useParent(SIDEBAR_KEY)
44
+ const { parent: sidebar, index } = useParent(SIDEBAR_KEY)
43
45
 
44
46
  const customBadgeProps = computed(() => {
45
47
  const badgeProps: Partial<BadgeProps> = deepAssign(
@@ -61,53 +63,37 @@ const customBadgeProps = computed(() => {
61
63
 
62
64
  const active = computed(() => {
63
65
  let active: boolean = false
64
- if (sidebar && sidebar.props.modelValue === props.value) {
66
+ if (sidebar.value && sidebar.value.props.modelValue === props.value) {
65
67
  active = true
66
68
  }
67
69
  return active
68
70
  })
69
71
 
70
72
  const prefix = computed(() => {
71
- let prefix: boolean = false
72
- if (sidebar) {
73
- let activeIndex: number = sidebar.children.findIndex((c: any) => {
74
- return c.value === sidebar.props.modelValue
75
- })
76
-
77
- let currentIndex: number = sidebar.children.findIndex((c: any) => {
78
- return c.value === props.value
79
- })
80
-
81
- if (currentIndex === activeIndex - 1) {
82
- prefix = true
83
- }
73
+ const sidebarValue = sidebar.value
74
+ if (!sidebarValue || index.value < 0) {
75
+ return false
84
76
  }
85
- return prefix
77
+
78
+ const activeIndex = sidebarValue.internalChildren.findIndex((child) => child.props?.value === sidebarValue.props.modelValue)
79
+ return index.value === activeIndex - 1
86
80
  })
87
81
 
88
82
  const suffix = computed(() => {
89
- let suffix: boolean = false
90
- if (sidebar) {
91
- let activeIndex: number = sidebar.children.findIndex((c: any) => {
92
- return c.value === sidebar.props.modelValue
93
- })
94
-
95
- let currentIndex: number = sidebar.children.findIndex((c: any) => {
96
- return c.value === props.value
97
- })
98
-
99
- if (currentIndex === activeIndex + 1) {
100
- suffix = true
101
- }
83
+ const sidebarValue = sidebar.value
84
+ if (!sidebarValue || index.value < 0) {
85
+ return false
102
86
  }
103
- return suffix
87
+
88
+ const activeIndex = sidebarValue.internalChildren.findIndex((child) => child.props?.value === sidebarValue.props.modelValue)
89
+ return index.value === activeIndex + 1
104
90
  })
105
91
 
106
92
  function handleClick() {
107
93
  if (props.disabled) {
108
94
  return
109
95
  }
110
- sidebar && sidebar.setChange(props.value, props.label)
96
+ sidebar.value && sidebar.value.setChange(props.value, props.label)
111
97
  }
112
98
  </script>
113
99
 
@@ -62,7 +62,9 @@ export default {
62
62
  name: 'oxy-signature',
63
63
  options: {
64
64
  addGlobalClass: true,
65
+ // #ifndef MP-TOUTIAO
65
66
  virtualHost: true,
67
+ // #endif
66
68
  styleIsolation: 'shared'
67
69
  }
68
70
  }
@@ -172,6 +174,12 @@ const currentLine = ref<Line>() // 当前正在绘制的线
172
174
  const currentStep = ref(0) // 当前步骤
173
175
 
174
176
  // 添加计算笔画宽度的方法
177
+ /**
178
+ * 根据绘制速度计算笔画宽度。
179
+ * 速度越快线条越细,速度越慢线条越粗,在 minWidth 和 maxWidth 之间动态变化。
180
+ * @param speed - 当前点的绘制速度
181
+ * @returns 计算后的线宽
182
+ */
175
183
  function calculateLineWidth(speed: number): number {
176
184
  if (!props.pressure) return lineWidthInPx.value
177
185
 
@@ -344,6 +352,9 @@ const draw = (e: any) => {
344
352
  }
345
353
 
346
354
  /* 重绘整个画布 */
355
+ /**
356
+ * 重绘整个画布。清除画布后按序重绘所有线条,笔锋模式使用贝塞尔曲线,普通模式使用直线段连接。
357
+ */
347
358
  const redrawCanvas = () => {
348
359
  const { ctx } = canvasState
349
360
  if (!ctx) return
@@ -450,6 +461,12 @@ const restore = () => {
450
461
  }
451
462
 
452
463
  // 添加平滑线条绘制方法
464
+ /**
465
+ * 使用二次贝塞尔曲线绘制平滑线条(笔锋模式)。
466
+ * 根据相邻两点的速度计算控制点偏移,实现笔触两端尖锐、中间饱满的效果。
467
+ * @param prePoint - 前一个点
468
+ * @param point - 当前点
469
+ */
453
470
  function drawSmoothLine(prePoint: Point, point: Point) {
454
471
  const { ctx } = canvasState
455
472
  if (!ctx) return
@@ -15,7 +15,13 @@ export default {
15
15
  // #ifdef H5
16
16
  name: 'oxy-skeleton',
17
17
  // #endif
18
- options: { virtualHost: true, addGlobalClass: true, styleIsolation: 'shared' }
18
+ options: {
19
+ // #ifndef MP-TOUTIAO
20
+ virtualHost: true,
21
+ // #endif
22
+ addGlobalClass: true,
23
+ styleIsolation: 'shared'
24
+ }
19
25
  }
20
26
  </script>
21
27
 
@@ -0,0 +1,95 @@
1
+ @import './../common/abstracts/_mixin.scss';
2
+ @import './../common/abstracts/variable.scss';
3
+
4
+ @include b(slide-verify) {
5
+ position: relative;
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: center;
9
+ overflow: hidden;
10
+ user-select: none;
11
+ width: $-slide-verify-width;
12
+ height: $-slide-verify-height;
13
+ border-radius: $-slide-verify-radius;
14
+ background: $-slide-verify-bg;
15
+
16
+ @include when(disabled) {
17
+ opacity: $-slide-verify-disabled-opacity;
18
+ }
19
+
20
+ @include e(text) {
21
+ width: 100%;
22
+ height: 100%;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ padding: 0 $-slide-verify-text-padding-x;
27
+ box-sizing: border-box;
28
+ pointer-events: none;
29
+ }
30
+
31
+ @include e(text-inner) {
32
+ color: $-slide-verify-text-color;
33
+ font-size: $-slide-verify-text-font-size;
34
+ line-height: $-slide-verify-text-line-height;
35
+ white-space: nowrap;
36
+ }
37
+
38
+ @include e(track) {
39
+ position: absolute;
40
+ left: 0;
41
+ top: 0;
42
+ width: 0;
43
+ height: 100%;
44
+ background: $-slide-verify-track-bg;
45
+ border-radius: $-slide-verify-radius;
46
+ overflow: hidden;
47
+ }
48
+
49
+ @include e(track-text) {
50
+ position: absolute;
51
+ left: 0;
52
+ top: 0;
53
+ min-width: 100%;
54
+ height: 100%;
55
+ display: flex;
56
+ align-items: center;
57
+ justify-content: center;
58
+ padding: 0 $-slide-verify-text-padding-x;
59
+ box-sizing: border-box;
60
+ color: $-slide-verify-success-text-color;
61
+ pointer-events: none;
62
+ white-space: nowrap;
63
+ }
64
+
65
+ @include e(track-text-inner) {
66
+ font-size: $-slide-verify-text-font-size;
67
+ line-height: $-slide-verify-text-line-height;
68
+ }
69
+
70
+ @include e(button) {
71
+ position: absolute;
72
+ right: 0;
73
+ top: 0;
74
+ width: $-slide-verify-button-size;
75
+ height: $-slide-verify-button-size;
76
+ display: flex;
77
+ align-items: center;
78
+ justify-content: center;
79
+ background: $-slide-verify-button-bg;
80
+ border: #{$-border-width-base} solid $-slide-verify-button-border-color;
81
+ border-radius: $-slide-verify-radius;
82
+ box-sizing: border-box;
83
+ box-shadow: $-slide-verify-button-shadow;
84
+ }
85
+
86
+ @include edeep(button-icon) {
87
+ color: $-slide-verify-button-color;
88
+ font-size: $-slide-verify-button-icon-size;
89
+ }
90
+
91
+ @include edeep(button-icon--success) {
92
+ color: $-slide-verify-button-success-color;
93
+ font-size: $-slide-verify-success-icon-size;
94
+ }
95
+ }
@@ -0,0 +1,244 @@
1
+ <template>
2
+ <view :class="rootClass" :id="slideVerifyId" :style="rootStyle">
3
+ <view class="oxy-slide-verify__text">
4
+ <slot name="text">
5
+ <text class="oxy-slide-verify__text-inner">
6
+ {{ slideVerifyText }}
7
+ </text>
8
+ </slot>
9
+ </view>
10
+
11
+ <view class="oxy-slide-verify__track" :style="trackStyle">
12
+ <view class="oxy-slide-verify__track-text">
13
+ <slot name="success-text">
14
+ <text class="oxy-slide-verify__track-text-inner">
15
+ {{ slideVerifySuccessText }}
16
+ </text>
17
+ </slot>
18
+ </view>
19
+
20
+ <view
21
+ class="oxy-slide-verify__button"
22
+ @touchstart.prevent="onTouchStart"
23
+ @touchmove.prevent="onTouchMove"
24
+ @touchend="onTouchEnd"
25
+ @touchcancel="onTouchEnd"
26
+ >
27
+ <slot v-if="isPass" name="success-icon">
28
+ <oxy-icon custom-class="oxy-slide-verify__button-icon oxy-slide-verify__button-icon--success" :name="successIcon" :size="successIconSize" />
29
+ </slot>
30
+
31
+ <slot v-else name="icon">
32
+ <oxy-icon custom-class="oxy-slide-verify__button-icon" :name="icon" :size="iconSize" />
33
+ </slot>
34
+ </view>
35
+ </view>
36
+ </view>
37
+ </template>
38
+
39
+ <script lang="ts">
40
+ export default {
41
+ name: 'oxy-slide-verify',
42
+ options: {
43
+ addGlobalClass: true,
44
+ // #ifndef MP-TOUTIAO
45
+ virtualHost: true,
46
+ // #endif
47
+ styleIsolation: 'shared'
48
+ }
49
+ }
50
+ </script>
51
+
52
+ <script lang="ts" setup>
53
+ import { computed, getCurrentInstance, onBeforeUnmount, onMounted, ref, type CSSProperties } from 'vue'
54
+ import OxyIcon from '../oxy-icon/oxy-icon.vue'
55
+ import { getRect, isDef, objToStyle, uuid } from '../common/util'
56
+ import { useTouch } from '../composables/useTouch'
57
+ import { useTranslate } from '../composables/useTranslate'
58
+ import { slideVerifyProps, type SlideVerifyEmits, type SlideVerifyExpose } from './types'
59
+
60
+ const props = defineProps(slideVerifyProps)
61
+ const emit = defineEmits<SlideVerifyEmits>()
62
+
63
+ const { proxy } = getCurrentInstance() as any
64
+ const touch = useTouch()
65
+ const { translate } = useTranslate('slide-verify')
66
+
67
+ const slideVerifyId = ref<string>(`oxy-slide-verify-${uuid()}`)
68
+
69
+ const slideVerifyText = computed(() => {
70
+ return isDef(props.text) && props.text !== '' ? props.text : translate('text')
71
+ })
72
+
73
+ const slideVerifySuccessText = computed(() => {
74
+ return isDef(props.successText) && props.successText !== '' ? props.successText : translate('successText')
75
+ })
76
+
77
+ const rootClass = computed(() => {
78
+ return [
79
+ 'oxy-slide-verify',
80
+ {
81
+ 'is-disabled': props.disabled,
82
+ 'is-success': isPass.value,
83
+ 'is-dragging': isDragging.value
84
+ },
85
+ props.customClass
86
+ ]
87
+ })
88
+
89
+ const rootStyle = computed(() => {
90
+ const style: CSSProperties = {}
91
+ if (isDef(props.backgroundColor)) {
92
+ style.background = props.backgroundColor
93
+ }
94
+ return `${objToStyle(style)}${props.customStyle}`
95
+ })
96
+
97
+ const trackStyle = computed(() => {
98
+ const style: CSSProperties = {
99
+ width: `${currentPosition.value + containerHeight.value}px`,
100
+ transition: isResetting.value ? 'all 0.3s ease' : 'none'
101
+ }
102
+
103
+ if (isDef(props.activeBackgroundColor)) {
104
+ style.background = props.activeBackgroundColor
105
+ }
106
+ if (currentPosition.value === 0) {
107
+ style.background = 'transparent'
108
+ }
109
+
110
+ return objToStyle(style)
111
+ })
112
+
113
+ const containerWidth = ref<number>(0)
114
+ const containerHeight = ref<number>(0)
115
+
116
+ /**
117
+ * 初始化:查询容器尺寸,用于计算滑块最大可拖动距离
118
+ */
119
+ const init = async () => {
120
+ try {
121
+ const rect = await getRect(`#${slideVerifyId.value}`, false, proxy)
122
+ containerWidth.value = Number(rect.width) || 0
123
+ containerHeight.value = Number(rect.height) || 0
124
+ } catch (error) {
125
+ containerWidth.value = 0
126
+ containerHeight.value = 0
127
+ }
128
+ }
129
+
130
+ onMounted(() => {
131
+ init()
132
+ })
133
+
134
+ const maxPosition = computed(() => {
135
+ const width = containerWidth.value
136
+ const height = containerHeight.value
137
+ if (width <= 0 || height <= 0) return 0
138
+ return Math.max(0, width - height)
139
+ })
140
+
141
+ const isComplete = computed(() => {
142
+ const distance = Math.abs(maxPosition.value - currentPosition.value)
143
+ return distance <= props.tolerance
144
+ })
145
+
146
+ const currentPosition = ref<number>(0)
147
+ const startPosition = ref<number>(0)
148
+ const isPass = ref<boolean>(false)
149
+ const isDragging = ref<boolean>(false)
150
+ const isResetting = ref<boolean>(false)
151
+ const timer = ref<ReturnType<typeof setTimeout> | null>(null)
152
+
153
+ const isDisabled = computed(() => props.disabled || isPass.value)
154
+
155
+ function clamp(value: number, min: number, max: number) {
156
+ return Math.max(min, Math.min(value, max))
157
+ }
158
+
159
+ function updatePosition(position: number) {
160
+ currentPosition.value = clamp(position, 0, maxPosition.value)
161
+ }
162
+
163
+ function clearResetTimer() {
164
+ if (timer.value !== null) {
165
+ clearTimeout(timer.value)
166
+ timer.value = null
167
+ }
168
+ }
169
+
170
+ /**
171
+ * 开启复位过渡动画(300ms),动画结束后自动关闭
172
+ */
173
+ function openResetTransition() {
174
+ isResetting.value = true
175
+ clearResetTimer()
176
+ timer.value = setTimeout(() => {
177
+ isResetting.value = false
178
+ timer.value = null
179
+ }, 300)
180
+ }
181
+
182
+ /**
183
+ * 触摸开始:记录起始位置,禁止拖拽时的过渡动画
184
+ */
185
+ function onTouchStart(event: any) {
186
+ if (isDisabled.value || isDragging.value) return
187
+
188
+ touch.touchStart(event)
189
+ startPosition.value = currentPosition.value
190
+ isDragging.value = true
191
+ }
192
+
193
+ /**
194
+ * 触摸移动:根据手指位移实时更新滑块位置
195
+ */
196
+ function onTouchMove(event: any) {
197
+ if (isDisabled.value || !isDragging.value) return
198
+
199
+ touch.touchMove(event)
200
+ updatePosition(startPosition.value + touch.deltaX.value)
201
+ }
202
+
203
+ /**
204
+ * 触摸结束:判断是否到达终点
205
+ * 完成则触发 success 事件,未完成则复位并触发 fail 事件
206
+ */
207
+ function onTouchEnd() {
208
+ if (isDisabled.value || !isDragging.value) return
209
+
210
+ isDragging.value = false
211
+
212
+ if (isComplete.value) {
213
+ updatePosition(maxPosition.value)
214
+ isPass.value = true
215
+ emit('success')
216
+ return
217
+ }
218
+
219
+ openResetTransition()
220
+ updatePosition(0)
221
+ emit('fail')
222
+ }
223
+
224
+ /**
225
+ * 重置滑块到初始状态,包含过渡动画
226
+ */
227
+ function reset() {
228
+ openResetTransition()
229
+ currentPosition.value = 0
230
+ startPosition.value = 0
231
+ isPass.value = false
232
+ isDragging.value = false
233
+ }
234
+
235
+ onBeforeUnmount(() => {
236
+ clearResetTimer()
237
+ })
238
+
239
+ defineExpose<SlideVerifyExpose>({ reset, init })
240
+ </script>
241
+
242
+ <style lang="scss" scoped>
243
+ @import './index.scss';
244
+ </style>
@@ -0,0 +1,98 @@
1
+ import type { ComponentPublicInstance, ExtractPropTypes } from 'vue'
2
+ import { baseProps, makeBooleanProp, makeNumberProp, makeStringProp, numericProp } from '../common/props'
3
+
4
+ export const slideVerifyProps = {
5
+ ...baseProps,
6
+
7
+ /**
8
+ * 容错范围(单位:px),距离终点在该范围内视为验证通过
9
+ * 类型: number
10
+ * 默认值: 10
11
+ */
12
+ tolerance: makeNumberProp(10),
13
+
14
+ /**
15
+ * 默认提示文案,传空字符串时使用内置文案
16
+ * 类型: string
17
+ * 默认值: ''
18
+ */
19
+ text: makeStringProp(''),
20
+
21
+ /**
22
+ * 验证成功提示文案,传空字符串时使用内置文案
23
+ * 类型: string
24
+ * 默认值: ''
25
+ */
26
+ successText: makeStringProp(''),
27
+
28
+ /**
29
+ * 是否禁用滑动验证
30
+ * 类型: boolean
31
+ * 默认值: false
32
+ */
33
+ disabled: makeBooleanProp(false),
34
+
35
+ /**
36
+ * 组件背景色,不传时使用组件 CSS 变量
37
+ * 类型: string
38
+ * 默认值: -
39
+ */
40
+ backgroundColor: String,
41
+
42
+ /**
43
+ * 激活轨道背景色,不传时使用组件 CSS 变量
44
+ * 类型: string
45
+ * 默认值: -
46
+ */
47
+ activeBackgroundColor: String,
48
+
49
+ /**
50
+ * 滑块图标名称
51
+ * 类型: string
52
+ * 默认值: 'arrow-right'
53
+ */
54
+ icon: makeStringProp('arrow-right'),
55
+
56
+ /**
57
+ * 验证通过图标名称
58
+ * 类型: string
59
+ * 默认值: 'check-circle-filled'
60
+ */
61
+ successIcon: makeStringProp('check-circle-filled'),
62
+
63
+ /**
64
+ * 滑块图标尺寸,number 与纯数字字符串按 rpx 处理,不传时使用组件默认样式
65
+ * 类型: string | number
66
+ * 默认值: -
67
+ */
68
+ iconSize: numericProp,
69
+
70
+ /**
71
+ * 验证通过图标尺寸,number 与纯数字字符串按 rpx 处理,不传时使用组件默认样式
72
+ * 类型: string | number
73
+ * 默认值: -
74
+ */
75
+ successIconSize: numericProp
76
+ }
77
+
78
+ export type SlideVerifyProps = ExtractPropTypes<typeof slideVerifyProps>
79
+
80
+ export type SlideVerifyExpose = {
81
+ /**
82
+ * 初始化尺寸信息
83
+ */
84
+ init: () => Promise<void>
85
+ /**
86
+ * 重置验证状态
87
+ */
88
+ reset: () => void
89
+ }
90
+
91
+ export type SlideVerifyEmits = {
92
+ /** 验证成功事件 */
93
+ success: []
94
+ /** 验证失败事件 */
95
+ fail: []
96
+ }
97
+
98
+ export type SlideVerifyInstance = ComponentPublicInstance<SlideVerifyProps, SlideVerifyExpose>
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <view :class="rootClass" :style="customStyle">
3
3
  <!-- #ifdef MP-DINGTALK -->
4
+ <!-- 钉钉小程序需额外包裹一层 view 来设置 flex: 1,确保滑块正确撑满 -->
4
5
  <view style="flex: 1" :class="rootClass">
5
6
  <!-- #endif -->
6
7
  <view :class="`oxy-slider__label-min ${customMinClass}`" v-if="!hideMinMax">{{ minProp }}</view>
@@ -60,7 +61,9 @@ export default {
60
61
  name: 'oxy-slider',
61
62
  options: {
62
63
  addGlobalClass: true,
64
+ // #ifndef MP-TOUTIAO
63
65
  virtualHost: true,
66
+ // #endif
64
67
  styleIsolation: 'shared'
65
68
  }
66
69
  }
@@ -20,14 +20,14 @@
20
20
  &::after {
21
21
  position: absolute;
22
22
  content: '';
23
- width: 38rpx;
24
- height: 6rpx;
25
- bottom: 12rpx;
23
+ width: $-sort-button-line-width;
24
+ height: $-sort-button-line-height;
25
+ bottom: $-sort-button-line-bottom;
26
26
  left: 50%;
27
27
  transform: translate(-50%, 0);
28
28
  background: $-sort-button-line-color;
29
29
  border-radius: calc($-sort-button-line-height / 2);
30
- transition: opacity .15s;
30
+ transition: opacity $-transition-duration-fast;
31
31
  opacity: 0;
32
32
  }
33
33
 
@@ -62,13 +62,15 @@
62
62
  @include e(right) {
63
63
  display: inline-block;
64
64
  min-width: 28rpx;
65
- margin-left: 4rpx;
65
+ margin-left: $-spacing-4;
66
66
  vertical-align: middle;
67
67
  line-height: $-line-height-tight;
68
68
 
69
- :deep(.oxy-sort-button__icon-up),
70
- :deep(.oxy-sort-button__icon-down) {
71
- transform: scale(calc((10 / 14)));
69
+ @include when(active) {
70
+ :deep(.oxy-sort-button__icon-up),
71
+ :deep(.oxy-sort-button__icon-down) {
72
+ transform: scale(calc((10 / 14)));
73
+ }
72
74
  }
73
75
  }
74
76
 
@@ -17,7 +17,9 @@ export default {
17
17
  name: 'oxy-sort-button',
18
18
  options: {
19
19
  addGlobalClass: true,
20
+ // #ifndef MP-TOUTIAO
20
21
  virtualHost: true,
22
+ // #endif
21
23
  styleIsolation: 'shared'
22
24
  }
23
25
  }
@@ -31,6 +33,10 @@ const props = defineProps(sortButtonProps)
31
33
 
32
34
  const emit = defineEmits(['change', 'update:modelValue'])
33
35
 
36
+ /**
37
+ * 排序切换处理。descFirst 模式下按 0→降序→升序 循环,普通模式按 0→升序→降序 循环。
38
+ * allowReset 为 true 时,第三次点击重置回 0。
39
+ */
34
40
  function handleClick() {
35
41
  let { modelValue: value, allowReset, descFirst } = props
36
42
  if (descFirst) {
@@ -17,3 +17,12 @@
17
17
  flex-direction: column;
18
18
  }
19
19
  }
20
+
21
+ // 看vite-plugin-host-class.ts DEFAULT_RULES中的配置
22
+ /* #ifdef MP-TOUTIAO */
23
+ @include b(splitter-toutiao) {
24
+ &.oxy-splitter {
25
+ display: block;
26
+ }
27
+ }
28
+ /* #endif */