oxy-uni-ui 1.2.0 → 2.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 (306) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/abstracts/variable.scss +396 -321
  3. package/components/common/path.ts +9 -0
  4. package/components/common/util.ts +200 -5
  5. package/components/composables/index.ts +1 -0
  6. package/components/composables/useGlobalLoading.ts +42 -0
  7. package/components/composables/useGlobalMessage.ts +48 -0
  8. package/components/composables/useGlobalToast.ts +84 -0
  9. package/components/composables/usePopover.ts +24 -20
  10. package/components/composables/useVirtualScroll.ts +13 -11
  11. package/components/composables/useWindowResize.ts +35 -0
  12. package/components/oxy-action-sheet/index.scss +24 -11
  13. package/components/oxy-action-sheet/oxy-action-sheet.vue +27 -19
  14. package/components/oxy-action-sheet/types.ts +7 -0
  15. package/components/oxy-backtop/index.scss +3 -3
  16. package/components/oxy-backtop/oxy-backtop.vue +9 -6
  17. package/components/oxy-backtop/types.ts +7 -7
  18. package/components/oxy-badge/index.scss +4 -4
  19. package/components/oxy-badge/oxy-badge.vue +3 -3
  20. package/components/oxy-badge/types.ts +2 -2
  21. package/components/oxy-button/index.scss +5 -5
  22. package/components/oxy-button/oxy-button.vue +5 -1
  23. package/components/oxy-calendar/index.scss +11 -11
  24. package/components/oxy-calendar/oxy-calendar.vue +1 -0
  25. package/components/oxy-calendar/types.ts +5 -0
  26. package/components/oxy-calendar-view/month/index.scss +4 -4
  27. package/components/oxy-calendar-view/month/types.ts +36 -0
  28. package/components/oxy-calendar-view/monthPanel/index.scss +7 -7
  29. package/components/oxy-calendar-view/monthPanel/month-panel.vue +14 -8
  30. package/components/oxy-calendar-view/year/index.scss +4 -4
  31. package/components/oxy-calendar-view/yearPanel/index.scss +4 -4
  32. package/components/oxy-calendar-view/yearPanel/year-panel.vue +21 -5
  33. package/components/oxy-card/index.scss +2 -2
  34. package/components/oxy-cell/index.scss +8 -8
  35. package/components/oxy-cell/oxy-cell.vue +15 -2
  36. package/components/oxy-cell/types.ts +4 -0
  37. package/components/oxy-checkbox/index.scss +8 -8
  38. package/components/oxy-checkbox/oxy-checkbox.vue +2 -2
  39. package/components/oxy-checkbox-group/index.scss +2 -2
  40. package/components/oxy-circle/oxy-circle.vue +10 -7
  41. package/components/oxy-circle/types.ts +5 -5
  42. package/components/oxy-col/oxy-col.vue +2 -2
  43. package/components/oxy-col-picker/index.scss +4 -4
  44. package/components/oxy-col-picker/oxy-col-picker.vue +9 -5
  45. package/components/oxy-col-picker/types.ts +12 -3
  46. package/components/oxy-collapse/index.scss +2 -2
  47. package/components/oxy-collapse-item/oxy-collapse-item.vue +3 -3
  48. package/components/oxy-corner/index.scss +32 -32
  49. package/components/oxy-corner/oxy-corner.vue +15 -3
  50. package/components/oxy-corner/types.ts +15 -1
  51. package/components/oxy-count-to/oxy-count-to.vue +3 -3
  52. package/components/oxy-curtain/index.scss +15 -15
  53. package/components/oxy-curtain/oxy-curtain.vue +4 -2
  54. package/components/oxy-curtain/types.ts +6 -1
  55. package/components/oxy-date-strip/index.scss +10 -0
  56. package/components/oxy-date-strip/oxy-date-strip.vue +198 -0
  57. package/components/oxy-date-strip/types.ts +98 -0
  58. package/components/oxy-date-strip/utils.ts +67 -0
  59. package/components/oxy-date-strip-item/index.scss +94 -0
  60. package/components/oxy-date-strip-item/oxy-date-strip-item.vue +102 -0
  61. package/components/oxy-date-strip-item/types.ts +53 -0
  62. package/components/oxy-datetime-picker/index.scss +11 -11
  63. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +4 -1
  64. package/components/oxy-datetime-picker/types.ts +10 -1
  65. package/components/oxy-drop-menu/index.scss +3 -3
  66. package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -3
  67. package/components/oxy-drop-menu-item/index.scss +1 -1
  68. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +4 -3
  69. package/components/oxy-drop-menu-item/types.ts +5 -0
  70. package/components/oxy-echarts/index.scss +17 -0
  71. package/components/oxy-echarts/index.ts +1 -0
  72. package/components/oxy-echarts/oxy-echarts.vue +32 -0
  73. package/components/oxy-echarts/types.ts +18 -0
  74. package/components/oxy-fab/index.scss +8 -8
  75. package/components/oxy-fab/oxy-fab.vue +22 -3
  76. package/components/oxy-file-list/index.scss +42 -15
  77. package/components/oxy-file-list/oxy-file-list.vue +208 -34
  78. package/components/oxy-file-list/types.ts +58 -2
  79. package/components/oxy-floating-panel/oxy-floating-panel.vue +13 -9
  80. package/components/oxy-floating-panel/{type.ts → types.ts} +8 -8
  81. package/components/oxy-footer/index.scss +19 -0
  82. package/components/oxy-footer/oxy-footer.vue +78 -0
  83. package/components/oxy-footer/types.ts +17 -0
  84. package/components/oxy-form-item/types.ts +22 -1
  85. package/components/oxy-gap/oxy-gap.vue +2 -2
  86. package/components/oxy-gap/types.ts +2 -2
  87. package/components/oxy-global-loading/oxy-global-loading.vue +53 -0
  88. package/components/oxy-global-message/oxy-global-message.vue +64 -0
  89. package/components/oxy-global-toast/oxy-global-toast.vue +53 -0
  90. package/components/oxy-grid/oxy-grid.vue +1 -1
  91. package/components/oxy-grid/types.ts +1 -1
  92. package/components/oxy-grid-item/index.scss +1 -1
  93. package/components/oxy-grid-item/oxy-grid-item.vue +7 -5
  94. package/components/oxy-grid-item/types.ts +1 -1
  95. package/components/oxy-guidance/index.scss +75 -0
  96. package/components/oxy-guidance/oxy-guidance.vue +201 -0
  97. package/components/oxy-guidance/types.ts +33 -0
  98. package/components/oxy-icon/oxy-icon.vue +2 -2
  99. package/components/oxy-icon/types.ts +1 -1
  100. package/components/oxy-img/oxy-img.vue +4 -4
  101. package/components/oxy-img/types.ts +3 -3
  102. package/components/oxy-img-cropper/index.scss +12 -12
  103. package/components/oxy-img-cropper/oxy-img-cropper.vue +97 -52
  104. package/components/oxy-img-cropper/types.ts +2 -2
  105. package/components/oxy-img-lazy/index.scss +17 -0
  106. package/components/oxy-img-lazy/oxy-img-lazy.vue +332 -0
  107. package/components/oxy-img-lazy/types.ts +69 -0
  108. package/components/oxy-index-anchor/index.scss +2 -2
  109. package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
  110. package/components/oxy-index-anchor/{type.ts → types.ts} +3 -0
  111. package/components/oxy-index-bar/index.scss +3 -3
  112. package/components/oxy-index-bar/oxy-index-bar.vue +3 -3
  113. package/components/oxy-index-bar/{type.ts → types.ts} +2 -2
  114. package/components/oxy-input/index.scss +1 -1
  115. package/components/oxy-input-number/index.scss +5 -5
  116. package/components/oxy-input-number/oxy-input-number.vue +2 -2
  117. package/components/oxy-input-number/types.ts +3 -2
  118. package/components/oxy-keyboard/index.scss +5 -5
  119. package/components/oxy-keyboard/key/index.scss +3 -3
  120. package/components/oxy-keyboard/key/index.vue +2 -2
  121. package/components/oxy-keyboard/key/types.ts +15 -0
  122. package/components/oxy-keyboard/oxy-keyboard.vue +1 -0
  123. package/components/oxy-keyboard/types.ts +5 -0
  124. package/components/oxy-link/index.scss +57 -0
  125. package/components/oxy-link/oxy-link.vue +130 -0
  126. package/components/oxy-link/types.ts +81 -0
  127. package/components/oxy-list/index.scss +7 -1
  128. package/components/oxy-list/oxy-list.vue +4 -3
  129. package/components/oxy-list/types.ts +1 -1
  130. package/components/oxy-loading/oxy-loading.vue +8 -4
  131. package/components/oxy-loading/types.ts +1 -1
  132. package/components/oxy-loadmore/index.scss +3 -3
  133. package/components/oxy-long-press-menu/index.scss +93 -0
  134. package/components/oxy-long-press-menu/oxy-long-press-menu.vue +338 -0
  135. package/components/oxy-long-press-menu/types.ts +34 -0
  136. package/components/oxy-message-box/index.scss +12 -11
  137. package/components/oxy-message-box/oxy-message-box.vue +11 -3
  138. package/components/oxy-message-box/types.ts +14 -0
  139. package/components/oxy-navbar/index.scss +2 -2
  140. package/components/oxy-navbar/oxy-navbar.vue +58 -13
  141. package/components/oxy-navbar/types.ts +8 -1
  142. package/components/oxy-navbar-capsule/types.ts +3 -0
  143. package/components/oxy-notice-bar/index.scss +3 -3
  144. package/components/oxy-notice-bar/oxy-notice-bar.vue +9 -5
  145. package/components/oxy-notice-bar/types.ts +3 -3
  146. package/components/oxy-notify/index.ts +1 -0
  147. package/components/oxy-notify/oxy-notify.vue +3 -2
  148. package/components/oxy-notify/types.ts +7 -0
  149. package/components/oxy-pagination/index.scss +1 -1
  150. package/components/oxy-password-input/oxy-password-input.vue +2 -2
  151. package/components/oxy-password-input/types.ts +1 -1
  152. package/components/oxy-picker/index.scss +45 -2
  153. package/components/oxy-picker/oxy-picker.vue +103 -14
  154. package/components/oxy-picker/types.ts +33 -1
  155. package/components/oxy-picker-view/index.scss +3 -3
  156. package/components/oxy-picker-view/oxy-picker-view.vue +4 -4
  157. package/components/oxy-popover/index.scss +9 -9
  158. package/components/oxy-popup/index.scss +2 -2
  159. package/components/oxy-popup/oxy-popup.vue +35 -2
  160. package/components/oxy-popup/types.ts +8 -1
  161. package/components/oxy-progress/index.scss +3 -3
  162. package/components/oxy-qrcode/draw.ts +398 -0
  163. package/components/oxy-qrcode/index.scss +2 -0
  164. package/components/oxy-qrcode/oxy-qrcode.vue +124 -0
  165. package/components/oxy-qrcode/qrcode.ts +936 -0
  166. package/components/oxy-qrcode/types.ts +42 -0
  167. package/components/oxy-radio/index.scss +13 -13
  168. package/components/oxy-radio/oxy-radio.vue +1 -1
  169. package/components/oxy-radio-group/index.scss +2 -2
  170. package/components/oxy-rate/types.ts +4 -4
  171. package/components/oxy-resize/index.scss +2 -2
  172. package/components/oxy-resize/oxy-resize.vue +4 -4
  173. package/components/oxy-resize/types.ts +3 -0
  174. package/components/oxy-rich-text/icon/emjio.svg +1 -0
  175. package/components/oxy-rich-text/icon/quote.svg +1 -0
  176. package/components/oxy-rich-text/icon/text.svg +1 -0
  177. package/components/oxy-rich-text/icon/title.svg +1 -0
  178. package/components/oxy-rich-text/index.scss +160 -0
  179. package/components/oxy-rich-text/mp-html/card/card.vue +122 -0
  180. package/components/oxy-rich-text/mp-html/card/index.js +7 -0
  181. package/components/oxy-rich-text/mp-html/editable/config.js +15 -0
  182. package/components/oxy-rich-text/mp-html/editable/index.js +553 -0
  183. package/components/oxy-rich-text/mp-html/emoji/index.js +203 -0
  184. package/components/oxy-rich-text/mp-html/highlight/config.js +5 -0
  185. package/components/oxy-rich-text/mp-html/highlight/index.js +96 -0
  186. package/components/oxy-rich-text/mp-html/highlight/prism.css +1 -0
  187. package/components/oxy-rich-text/mp-html/highlight/prism.min.js +7 -0
  188. package/components/oxy-rich-text/mp-html/img-cache/index.js +138 -0
  189. package/components/oxy-rich-text/mp-html/latex/index.js +80 -0
  190. package/components/oxy-rich-text/mp-html/latex/katex.css +1 -0
  191. package/components/oxy-rich-text/mp-html/latex/katex.min.js +1 -0
  192. package/components/oxy-rich-text/mp-html/markdown/index.js +50 -0
  193. package/components/oxy-rich-text/mp-html/markdown/marked.min.js +71 -0
  194. package/components/oxy-rich-text/mp-html/mp-html.d.ts +184 -0
  195. package/components/oxy-rich-text/mp-html/mp-html.vue +684 -0
  196. package/components/oxy-rich-text/mp-html/node/node.vue +1172 -0
  197. package/components/oxy-rich-text/mp-html/parser.js +1428 -0
  198. package/components/oxy-rich-text/mp-html/search/index.js +132 -0
  199. package/components/oxy-rich-text/mp-html/style/index.js +129 -0
  200. package/components/oxy-rich-text/mp-html/style/parser.js +175 -0
  201. package/components/oxy-rich-text/mp-html/template/index.js +67 -0
  202. package/components/oxy-rich-text/mp-html/txv-video/index.js +46 -0
  203. package/components/oxy-rich-text/oxy-rich-text.vue +642 -0
  204. package/components/oxy-rich-text/types.ts +76 -0
  205. package/components/oxy-row/oxy-row.vue +3 -3
  206. package/components/oxy-row/types.ts +1 -1
  207. package/components/oxy-search/index.scss +3 -3
  208. package/components/oxy-segmented/index.scss +16 -16
  209. package/components/oxy-segmented/oxy-segmented.vue +23 -3
  210. package/components/oxy-select/index.scss +331 -0
  211. package/components/oxy-select/oxy-select.vue +456 -0
  212. package/components/oxy-select/types.ts +83 -0
  213. package/components/oxy-select-picker/index.scss +7 -7
  214. package/components/oxy-select-picker/oxy-select-picker.vue +4 -0
  215. package/components/oxy-select-picker/types.ts +7 -1
  216. package/components/oxy-sidebar-item/index.scss +1 -1
  217. package/components/oxy-signature/oxy-signature.vue +18 -10
  218. package/components/oxy-signature/types.ts +106 -13
  219. package/components/oxy-skeleton/oxy-skeleton.vue +6 -6
  220. package/components/oxy-skeleton/types.ts +1 -1
  221. package/components/oxy-slider/index.scss +3 -3
  222. package/components/oxy-sort-button/index.scss +8 -8
  223. package/components/oxy-status-tip/index.scss +4 -4
  224. package/components/oxy-status-tip/oxy-status-tip.vue +5 -5
  225. package/components/oxy-status-tip/types.ts +3 -3
  226. package/components/oxy-step/index.scss +14 -14
  227. package/components/oxy-sticky/oxy-sticky.vue +6 -6
  228. package/components/oxy-stream-render/index.scss +6 -0
  229. package/components/oxy-stream-render/oxy-stream-render.vue +204 -0
  230. package/components/oxy-stream-render/types.ts +8 -0
  231. package/components/oxy-swipe-action/oxy-swipe-action.vue +27 -2
  232. package/components/oxy-swiper/oxy-swiper.vue +6 -6
  233. package/components/oxy-swiper/types.ts +5 -5
  234. package/components/oxy-switch/index.scss +8 -8
  235. package/components/oxy-switch/oxy-switch.vue +2 -2
  236. package/components/oxy-switch/types.ts +1 -1
  237. package/components/oxy-tab/index.scss +11 -1
  238. package/components/oxy-tabbar/index.scss +1 -1
  239. package/components/oxy-tabbar/oxy-tabbar.vue +39 -10
  240. package/components/oxy-table/index.scss +5 -5
  241. package/components/oxy-table/oxy-table.vue +8 -6
  242. package/components/oxy-table/types.ts +2 -2
  243. package/components/oxy-table-col/oxy-table-col.vue +3 -3
  244. package/components/oxy-table-col/types.ts +2 -2
  245. package/components/oxy-tabs/index.scss +43 -15
  246. package/components/oxy-tabs/oxy-tabs.vue +53 -19
  247. package/components/oxy-tabs/types.ts +15 -3
  248. package/components/oxy-tag/index.scss +15 -15
  249. package/components/oxy-text/index.scss +5 -1
  250. package/components/oxy-text/oxy-text.vue +76 -7
  251. package/components/oxy-text/types.ts +12 -0
  252. package/components/oxy-textarea/index.scss +6 -6
  253. package/components/oxy-toast/oxy-toast.vue +24 -8
  254. package/components/oxy-tooltip/index.scss +9 -9
  255. package/components/oxy-tree/index.scss +61 -9
  256. package/components/oxy-tree/oxy-tree.vue +102 -17
  257. package/components/oxy-tree/types.ts +23 -10
  258. package/components/oxy-upload/index.scss +21 -21
  259. package/components/oxy-upload/types.ts +2 -2
  260. package/components/oxy-verification-code/index.scss +6 -0
  261. package/components/oxy-verification-code/oxy-verification-code.vue +187 -0
  262. package/components/oxy-verification-code/types.ts +82 -0
  263. package/components/oxy-video-preview/index.scss +4 -4
  264. package/components/oxy-virtual-scroll/index.scss +4 -4
  265. package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +11 -7
  266. package/components/oxy-virtual-scroll/types.ts +14 -14
  267. package/components/oxy-voice-player/index.scss +908 -0
  268. package/components/oxy-voice-player/oxy-voice-player.vue +821 -0
  269. package/components/oxy-voice-player/types.ts +567 -0
  270. package/components/oxy-waterfall/index.scss +18 -0
  271. package/components/oxy-waterfall/oxy-waterfall.vue +218 -0
  272. package/components/oxy-waterfall/types.ts +90 -0
  273. package/components/oxy-waterfall-item/index.scss +8 -0
  274. package/components/oxy-waterfall-item/oxy-waterfall-item.vue +89 -0
  275. package/components/oxy-waterfall-item/types.ts +16 -0
  276. package/components/oxy-watermark/oxy-watermark.vue +35 -13
  277. package/components/oxy-watermark/types.ts +14 -14
  278. package/global.d.ts +9 -0
  279. package/index.ts +3 -0
  280. package/locale/lang/ar-SA.ts +3 -0
  281. package/locale/lang/en-US.ts +29 -0
  282. package/locale/lang/zh-CN.ts +29 -0
  283. package/package.json +97 -1
  284. package/tags.json +1 -1
  285. package/uni-echarts/changelog.md +2 -0
  286. package/uni-echarts/components/index.js +1 -0
  287. package/uni-echarts/components/uni-echarts/events.js +95 -0
  288. package/uni-echarts/components/uni-echarts/types.d.ts +183 -0
  289. package/uni-echarts/components/uni-echarts/types.js +1 -0
  290. package/uni-echarts/components/uni-echarts/uni-echarts.vue +530 -0
  291. package/uni-echarts/components/uni-echarts/uni-echarts.vue.d.ts +19 -0
  292. package/uni-echarts/global.d.ts +7 -0
  293. package/uni-echarts/index.d.ts +440 -0
  294. package/uni-echarts/index.js +2 -0
  295. package/uni-echarts/package.json +105 -0
  296. package/uni-echarts/shared-core.d.ts +269 -0
  297. package/uni-echarts/shared-core.js +900 -0
  298. package/web-types.json +1 -1
  299. package/components/oxy-number-keyboard/index.scss +0 -78
  300. package/components/oxy-number-keyboard/key/index.scss +0 -81
  301. package/components/oxy-number-keyboard/key/index.vue +0 -78
  302. package/components/oxy-number-keyboard/key/types.ts +0 -11
  303. package/components/oxy-number-keyboard/oxy-number-keyboard.vue +0 -151
  304. package/components/oxy-number-keyboard/types.ts +0 -83
  305. package/components/oxy-tree/components/tree-node-content.vue +0 -72
  306. package/components/oxy-tree/index.ts +0 -51
@@ -0,0 +1,332 @@
1
+ <template>
2
+ <view :class="`oxy-img-lazy ${customClass}`" :style="rootStyle">
3
+ <!-- 加载中 -->
4
+ <image
5
+ :src="loadSrc"
6
+ class="oxy-img-lazy__image oxy-img-lazy__load"
7
+ @load="init"
8
+ :show-menu-by-longpress="true"
9
+ :mode="mode"
10
+ :style="{
11
+ opacity: isShow ? '0' : '1',
12
+ borderRadius,
13
+ width,
14
+ height,
15
+ transition: `opacity ${duration / 1000}s ${effect}`
16
+ }"
17
+ />
18
+
19
+ <!-- 加载成功 -->
20
+ <image
21
+ class="oxy-img-lazy__image"
22
+ @load="load"
23
+ @error="error"
24
+ :show-menu-by-longpress="true"
25
+ :webp="true"
26
+ v-if="status === 1"
27
+ :src="imageSrc"
28
+ :mode="mode"
29
+ :style="{
30
+ opacity: isShow ? '1' : '0',
31
+ borderRadius,
32
+ width,
33
+ height,
34
+ transition: `opacity ${duration / 1000}s ${effect}`
35
+ }"
36
+ />
37
+ <!-- 加载失败 -->
38
+ <image
39
+ class="oxy-img-lazy__image"
40
+ v-if="status === 2"
41
+ :show-menu-by-longpress="true"
42
+ :src="errorSrc"
43
+ :mode="mode"
44
+ :style="{
45
+ opacity: isShow ? '1' : '0',
46
+ borderRadius,
47
+ width,
48
+ height,
49
+ transition: `opacity ${duration / 1000}s ${effect}`
50
+ }"
51
+ />
52
+ </view>
53
+ </template>
54
+ <script lang="ts">
55
+ export default {
56
+ name: 'oxy-img-lazy',
57
+ options: {
58
+ virtualHost: true,
59
+ addGlobalClass: true,
60
+ styleIsolation: 'shared'
61
+ }
62
+ }
63
+ </script>
64
+
65
+ <script lang="ts" setup>
66
+ import { computed, getCurrentInstance, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
67
+ import { withDefaultUnit, isDef, objToStyle } from '../common/util'
68
+ import { imgLazyProps } from './types'
69
+
70
+ const props = defineProps(imgLazyProps)
71
+ const emit = defineEmits(['show', 'load', 'error', 'destroyed'])
72
+
73
+ const rootStyle = computed(() => {
74
+ const style: Record<string, string | number> = {}
75
+ if (isDef(props.height)) {
76
+ style['height'] = withDefaultUnit(props.height)
77
+ }
78
+ if (isDef(props.width)) {
79
+ style['width'] = withDefaultUnit(props.width)
80
+ }
81
+ return `${objToStyle(style)}${props.customStyle}`
82
+ })
83
+
84
+ // 响应式数据
85
+ const status = ref<number>(0) // 0加载中 1加载成功 2加载失败
86
+ const isShow = ref<boolean>(false)
87
+ const loadTimer = ref<number | null>(null)
88
+ const observer = ref<any>(null)
89
+ const renderCount = ref<number>(0) // 添加渲染计数器
90
+ const lastSrc = ref<string>('') // 记录上一次的src值
91
+ const scrollTimeout = ref<number | null>(null) // 滚动检测定时器
92
+ const retryCount = ref<number>(0) // 重试次数计数器
93
+ const maxRetries = ref<number>(3) // 最大重试次数
94
+ const imageSrc = ref<string>('')
95
+ // 获取当前组件实例
96
+ const instance = getCurrentInstance()
97
+
98
+ // 重置状态方法
99
+ const resetStatus = () => {
100
+ status.value = 0
101
+ isShow.value = false
102
+ loadTimer.value = null
103
+ }
104
+
105
+ // 清理资源方法
106
+ const cleanup = () => {
107
+ if (observer.value) {
108
+ observer.value.disconnect()
109
+ observer.value = null
110
+ }
111
+ if (loadTimer.value) {
112
+ clearTimeout(loadTimer.value)
113
+ loadTimer.value = null
114
+ }
115
+ if (scrollTimeout.value) {
116
+ clearTimeout(scrollTimeout.value)
117
+ scrollTimeout.value = null
118
+ }
119
+ }
120
+
121
+ // 开始加载方法
122
+ const startLoad = () => {
123
+ status.value = 1
124
+ loadTimer.value = new Date().getTime()
125
+ }
126
+
127
+ // 图片加载成功
128
+ const load = (event: any) => {
129
+ const minTimeOut = props.minTimeOut
130
+
131
+ if (minTimeOut <= 0) {
132
+ isShow.value = true
133
+ } else {
134
+ // 确保loadTimer存在
135
+ const timerDiff = loadTimer.value ? new Date().getTime() - loadTimer.value : 0
136
+
137
+ if (timerDiff < minTimeOut) {
138
+ loadTimer.value = setTimeout(() => {
139
+ isShow.value = true
140
+ loadTimer.value = null
141
+ }, minTimeOut - timerDiff) as unknown as number
142
+ } else {
143
+ isShow.value = true
144
+ }
145
+ }
146
+
147
+ setTimeout(() => {
148
+ emit('load', event)
149
+ }, props.duration)
150
+ }
151
+
152
+ // 图片加载失败
153
+ const error = (event: any) => {
154
+ imageSrc.value = props.errorSrc
155
+ status.value = 2
156
+ isShow.value = true
157
+ cleanup() // 加载失败时清理资源
158
+ setTimeout(() => {
159
+ emit('error', event)
160
+ }, props.duration)
161
+ }
162
+
163
+ // 初始化懒加载
164
+ const init = async () => {
165
+ // 确保清理之前的观察者
166
+ cleanup()
167
+
168
+ // 如果没有src,不进行懒加载
169
+ if (!props.src) return
170
+
171
+ // 如果组件已经在视口内,直接开始加载
172
+ const isInViewport = await isComponentInViewport()
173
+ if (isInViewport) {
174
+ startLoad()
175
+ return
176
+ }
177
+
178
+ try {
179
+ // 使用组件实例创建IntersectionObserver
180
+ observer.value = uni.createIntersectionObserver(instance)
181
+ let load = false
182
+
183
+ observer.value.relativeToViewport(props.showDistance).observe('.oxy-img-lazy__load', (res: any) => {
184
+ if (!load && res.intersectionRatio > 0) {
185
+ emit('show')
186
+ load = true
187
+ startLoad()
188
+ cleanup()
189
+ }
190
+ })
191
+ } catch (error) {
192
+ console.error('懒加载初始化失败:', error)
193
+ // 降级处理:如果IntersectionObserver失败,直接加载
194
+ startLoad()
195
+ }
196
+ }
197
+
198
+ // 检查组件是否在视口内
199
+ const isComponentInViewport = (): Promise<boolean> => {
200
+ return new Promise((resolve) => {
201
+ try {
202
+ const query = uni.createSelectorQuery().in(instance)
203
+ query
204
+ .select('.oxy-img-lazy__load')
205
+ .boundingClientRect((rect: any) => {
206
+ if (rect) {
207
+ const windowHeight = uni.getSystemInfoSync().windowHeight
208
+ const windowWidth = uni.getSystemInfoSync().windowWidth
209
+
210
+ // 检查是否在可视区域内(考虑滚动容器的偏移)
211
+ const isInViewport = rect.top < windowHeight && rect.bottom > 0 && rect.left < windowWidth && rect.right > 0
212
+
213
+ resolve(isInViewport)
214
+ } else {
215
+ resolve(false)
216
+ }
217
+ })
218
+ .exec()
219
+ } catch (error) {
220
+ resolve(false)
221
+ }
222
+ })
223
+ }
224
+
225
+ // 监听src变化
226
+ watch(
227
+ () => props.src,
228
+ (newSrc, oldSrc) => {
229
+ // 无论isShow状态如何,都重置加载状态
230
+ if (newSrc) {
231
+ imageSrc.value = newSrc
232
+ }
233
+ if (newSrc !== oldSrc) {
234
+ resetStatus()
235
+ // 如果组件已经可见,直接开始加载
236
+ if (isShow.value) {
237
+ startLoad()
238
+ } else {
239
+ // 重新初始化懒加载观察者
240
+ nextTick(() => {
241
+ init()
242
+ })
243
+ }
244
+ }
245
+ },
246
+ {
247
+ immediate: true,
248
+ deep: true
249
+ }
250
+ )
251
+
252
+ // 添加一个强制刷新方法
253
+ const forceRefresh = () => {
254
+ resetStatus()
255
+ cleanup()
256
+ nextTick(() => {
257
+ init()
258
+ })
259
+ }
260
+
261
+ // 检查是否需要重新初始化
262
+ const checkAndReinit = () => {
263
+ // 如果src发生变化,或者这是第一次渲染,则重新初始化
264
+ if (props.src !== lastSrc.value || renderCount.value === 0) {
265
+ lastSrc.value = props.src || ''
266
+ resetStatus()
267
+ nextTick(() => {
268
+ init()
269
+ })
270
+ }
271
+ renderCount.value++
272
+ }
273
+
274
+ // 滚动检测和手动触发机制
275
+ const setupScrollDetection = () => {
276
+ // 监听页面滚动事件
277
+ uni.$on('pageScroll', () => {
278
+ if (scrollTimeout.value) {
279
+ clearTimeout(scrollTimeout.value)
280
+ }
281
+
282
+ // 防抖处理,滚动停止后检测可见性
283
+ scrollTimeout.value = setTimeout(() => {
284
+ checkVisibilityOnScroll()
285
+ }, 300) as unknown as number
286
+ })
287
+ }
288
+
289
+ // 滚动时检查可见性
290
+ const checkVisibilityOnScroll = async () => {
291
+ if (status.value === 0) {
292
+ // 只有在未加载状态下检查
293
+ const isInViewport = await isComponentInViewport()
294
+ if (isInViewport) {
295
+ startLoad()
296
+ cleanup() // 清理观察器
297
+ }
298
+ }
299
+ }
300
+
301
+ // 手动触发加载(用于scroll-view和swiper等特殊情况)
302
+ const manualTriggerLoad = () => {
303
+ if (status.value === 0) {
304
+ startLoad()
305
+ cleanup()
306
+ }
307
+ }
308
+
309
+ // 暴露方法给父组件
310
+ defineExpose({
311
+ forceRefresh,
312
+ manualTriggerLoad
313
+ })
314
+
315
+ // 组件挂载后初始化
316
+ onMounted(() => {
317
+ // 增加渲染计数并检查是否需要重新初始化
318
+ checkAndReinit()
319
+ // 设置滚动检测
320
+ setupScrollDetection()
321
+ })
322
+
323
+ // 组件销毁前清理资源
324
+ onBeforeUnmount(() => {
325
+ cleanup()
326
+ emit('destroyed')
327
+ })
328
+ </script>
329
+
330
+ <style lang="scss" scoped>
331
+ @import './index.scss';
332
+ </style>
@@ -0,0 +1,69 @@
1
+ import { baseProps, makeNumberProp, makeStringProp, numericProp } from '../common/props'
2
+ export type ImageMode =
3
+ | 'scaleToFill'
4
+ | 'aspectFit'
5
+ | 'aspectFill'
6
+ | 'widthFix'
7
+ | 'heightFix'
8
+ | 'top'
9
+ | 'bottom'
10
+ | 'center'
11
+ | 'left'
12
+ | 'right'
13
+ | 'top left'
14
+ | 'top right'
15
+ | 'bottom left'
16
+ | 'bottom right'
17
+
18
+ export type ImageEffect = 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out'
19
+
20
+ export const imgLazyProps = {
21
+ ...baseProps,
22
+ /**
23
+ * 图片链接
24
+ */
25
+ src: String,
26
+ /**
27
+ * 填充模式:'top left' / 'top right' / 'bottom left' / 'bottom right' / 'right' / 'left' / 'center' / 'bottom' / 'top' / 'heightFix' / 'widthFix' / 'aspectFill' / 'aspectFit' / 'scaleToFill'
28
+ */
29
+ mode: makeStringProp<ImageMode>('aspectFill'),
30
+ /**
31
+ * 宽度,number 类型按 `rpx` 语义处理,也支持 `px/rpx`
32
+ */
33
+ width: numericProp,
34
+ /**
35
+ * 高度,number 类型按 `rpx` 语义处理,也支持 `px/rpx`
36
+ */
37
+ height: numericProp,
38
+ /**
39
+ * 圆角大小,number 类型按 `rpx` 语义处理,也支持 `px/rpx`
40
+ */
41
+ borderRadius: makeStringProp('0'),
42
+ /**
43
+ * 懒加载延迟时间
44
+ */
45
+ minTimeOut: makeNumberProp(0),
46
+ /**
47
+ * 图片提前加载的距离阈值
48
+ */
49
+ showDistance: {
50
+ type: Object,
51
+ default: () => ({ bottom: 20 })
52
+ },
53
+ /**
54
+ * 图片懒加载时的视觉过渡效果
55
+ */
56
+ effect: makeStringProp<ImageEffect>('linear'),
57
+ /**
58
+ * 图片懒加载时的视觉过渡时间
59
+ */
60
+ duration: makeNumberProp(0),
61
+ /**
62
+ * 加载中时显示的图片链接
63
+ */
64
+ loadSrc: makeStringProp(''),
65
+ /**
66
+ * 加载失败时显示的图片链接
67
+ */
68
+ errorSrc: makeStringProp('')
69
+ }
@@ -22,8 +22,8 @@
22
22
 
23
23
  @include b(index-anchor) {
24
24
  background-color: $-color-gray-2;
25
- padding: 10px;
26
- font-size: 14px;
25
+ padding: 20rpx;
26
+ font-size: 28rpx;
27
27
  color: $-color-title;
28
28
 
29
29
  @include when(sticky){
@@ -13,9 +13,9 @@
13
13
  </template>
14
14
 
15
15
  <script setup lang="ts">
16
- import { indexAnchorProps } from './type'
16
+ import { indexAnchorProps } from './types'
17
17
  import { onMounted, getCurrentInstance, ref, computed } from 'vue'
18
- import { indexBarInjectionKey } from '../oxy-index-bar/type'
18
+ import { indexBarInjectionKey } from '../oxy-index-bar/types'
19
19
  import { getRect, isDef, uuid } from '../common/util'
20
20
  import { useParent } from '../composables/useParent'
21
21
 
@@ -3,6 +3,9 @@ import { baseProps, makeRequiredProp } from '../common/props'
3
3
 
4
4
  export const indexAnchorProps = {
5
5
  ...baseProps,
6
+ /**
7
+ * 索引项标识,可用于字母索引或数字索引
8
+ */
6
9
  index: makeRequiredProp([String, Number])
7
10
  }
8
11
 
@@ -22,15 +22,15 @@
22
22
  @include e(sidebar) {
23
23
  position: absolute;
24
24
  top: 50%;
25
- right: 4px;
25
+ right: 8rpx;
26
26
  transform: translateY(-50%);
27
27
  }
28
28
 
29
29
  @include e(index) {
30
- font-size: 12px;
30
+ font-size: 24rpx;
31
31
  font-weight: $-fw-medium;
32
32
  color: $-color-title;
33
- padding: 4px 6px;
33
+ padding: 8rpx 12rpx;
34
34
 
35
35
  @include when(active) {
36
36
  color: $-color-theme;
@@ -24,8 +24,8 @@
24
24
  </template>
25
25
 
26
26
  <script setup lang="ts">
27
- import type { AnchorIndex } from './type'
28
- import { indexBarInjectionKey, indexBarProps } from './type'
27
+ import type { AnchorIndex } from './types'
28
+ import { indexBarInjectionKey, indexBarProps } from './types'
29
29
  import { ref, getCurrentInstance, onMounted, reactive, nextTick, watch } from 'vue'
30
30
  import { getRect, isDef, uuid, pause } from '../common/util'
31
31
  import { useChildren } from '../composables/useChildren'
@@ -71,7 +71,7 @@ let offsetTop = 0
71
71
  let sidebarInfo = {
72
72
  // 侧边栏距离顶部的高度
73
73
  offsetTop: 0,
74
- // 高度固定24px
74
+ // 高度固定48rpx
75
75
  indexHeight: 24
76
76
  }
77
77
 
@@ -6,7 +6,7 @@ export type AnchorIndex = number | string
6
6
 
7
7
  export const indexBarProps = {
8
8
  /**
9
- * @description 索引是否吸顶
9
+ * 索引栏是否启用吸顶效果
10
10
  */
11
11
  sticky: makeBooleanProp(false)
12
12
  }
@@ -16,7 +16,7 @@ export type IndexBarProps = ExtractPropTypes<typeof indexBarProps>
16
16
  export type InderBarProvide = {
17
17
  props: { sticky?: boolean }
18
18
  anchorState: {
19
- activeIndex: AnchorIndex | null // 当前激活的索引
19
+ activeIndex: AnchorIndex | null
20
20
  }
21
21
  }
22
22
 
@@ -301,7 +301,7 @@
301
301
  }
302
302
 
303
303
  @include e(count) {
304
- margin-left: 15px;
304
+ margin-left: 30rpx;
305
305
  font-size: $-input-count-fs;
306
306
  color: $-input-count-color;
307
307
  vertical-align: middle;
@@ -45,8 +45,8 @@
45
45
  &::after {
46
46
  position: absolute;
47
47
  content: "";
48
- width: calc(200% - 2px);
49
- height: calc(200% - 2px);
48
+ width: calc(200% - 4rpx);
49
+ height: calc(200% - 4rpx);
50
50
  left: 0;
51
51
  top: 0;
52
52
  border: 1px solid $-input-number-border-color;
@@ -77,7 +77,7 @@
77
77
  display: block;
78
78
  width: $-input-number-input-width;
79
79
  height: $-input-number-height;
80
- padding: 0 2px;
80
+ padding: 0 4rpx;
81
81
  box-sizing: border-box;
82
82
  z-index: 1;
83
83
  background: transparent;
@@ -93,7 +93,7 @@
93
93
  @include e(input-border) {
94
94
  position: absolute;
95
95
  width: 100%;
96
- height: calc(200% - 2px);
96
+ height: calc(200% - 4rpx);
97
97
  left: 0;
98
98
  top: 0;
99
99
  border-top: 1px solid $-input-number-border-color;
@@ -129,4 +129,4 @@
129
129
  border-left: none;
130
130
  }
131
131
  }
132
- }
132
+ }
@@ -13,7 +13,7 @@
13
13
  <view v-if="!withoutInput" class="oxy-input-number__inner" @click.stop="">
14
14
  <input
15
15
  class="oxy-input-number__input"
16
- :style="`${inputWidth ? 'width: ' + inputWidth : ''}`"
16
+ :style="`${inputWidth ? 'width: ' + withDefaultUnit(inputWidth) : ''}`"
17
17
  :type="inputType"
18
18
  :input-mode="precision ? 'decimal' : 'numeric'"
19
19
  :disabled="disabled || disableInput"
@@ -52,7 +52,7 @@ export default {
52
52
  <script lang="ts" setup>
53
53
  import OxyIcon from '../oxy-icon/oxy-icon.vue'
54
54
  import { computed, nextTick, ref, watch } from 'vue'
55
- import { isDef, isEqual } from '../common/util'
55
+ import { isDef, isEqual, withDefaultUnit } from '../common/util'
56
56
  import { inputNumberProps, type OperationType } from './types'
57
57
  import { callInterceptor } from '../common/interceptor'
58
58
 
@@ -57,9 +57,10 @@ export const inputNumberProps = {
57
57
  */
58
58
  withoutInput: makeBooleanProp(false),
59
59
  /**
60
- * 输入框宽度
60
+ * 输入框宽度。
61
+ * number 或纯数字字符串默认按 rpx 处理,支持传入带单位字符串(如 `px`、`rpx`、`%`)。
61
62
  */
62
- inputWidth: makeNumericProp(36),
63
+ inputWidth: makeNumericProp(72),
63
64
  /**
64
65
  * 是否允许为空
65
66
  */
@@ -18,7 +18,7 @@
18
18
  user-select: none;
19
19
 
20
20
  @include m(with-title) {
21
- border-radius: 20px 20px 0 0;
21
+ border-radius: 40rpx 40rpx 0 0;
22
22
  }
23
23
 
24
24
  @include e(header) {
@@ -28,7 +28,7 @@
28
28
  justify-content: center;
29
29
  box-sizing: content-box;
30
30
  height: $-keyboard-title-height;
31
- padding-top: 6px;
31
+ padding-top: 12rpx;
32
32
  color: $-keyboard-title-color;
33
33
  font-size: $-keyboard-title-font-size;
34
34
  }
@@ -45,7 +45,7 @@
45
45
 
46
46
  @include e(body) {
47
47
  display: flex;
48
- padding: 6px 0 0 6px;
48
+ padding: 12rpx 0 0 12rpx;
49
49
  }
50
50
 
51
51
  @include e(keys) {
@@ -57,7 +57,7 @@
57
57
  &-car {
58
58
  @include e(body) {
59
59
  display: flex;
60
- padding: 6px 0 0 6px;
60
+ padding: 12rpx 0 0 12rpx;
61
61
  }
62
62
  }
63
63
 
@@ -68,7 +68,7 @@
68
68
  flex-wrap: wrap;
69
69
 
70
70
  .oxy-key-wrapper {
71
- --oxy-keyboard-key-font-size: 18px;
71
+ --oxy-keyboard-key-font-size: 36rpx;
72
72
  flex-basis: 10%;
73
73
 
74
74
  @include m(wider) {
@@ -21,7 +21,7 @@
21
21
  flex: 1;
22
22
  flex-basis: 33%;
23
23
  box-sizing: border-box;
24
- padding: 0 6px 6px 0;
24
+ padding: 0 12rpx 12rpx 0;
25
25
 
26
26
  @include m(wider) {
27
27
  flex-basis: 66%;
@@ -45,8 +45,8 @@
45
45
  @include m(large) {
46
46
  position: absolute;
47
47
  top: 0;
48
- right: 6px;
49
- bottom: 6px;
48
+ right: 12rpx;
49
+ bottom: 12rpx;
50
50
  left: 0;
51
51
  height: auto;
52
52
  }
@@ -11,13 +11,13 @@
11
11
  <template v-if="text">
12
12
  {{ text }}
13
13
  </template>
14
- <oxy-icon v-else custom-class="oxy-key__icon" name="keyboard-delete" size="22px"></oxy-icon>
14
+ <oxy-icon v-else custom-class="oxy-key__icon" name="keyboard-delete" size="44rpx"></oxy-icon>
15
15
  </template>
16
16
  <template v-else-if="type === 'extra'">
17
17
  <template v-if="text">
18
18
  {{ text }}
19
19
  </template>
20
- <oxy-icon v-else custom-class="oxy-key__icon" name="keyboard-collapse" size="22px"></oxy-icon>
20
+ <oxy-icon v-else custom-class="oxy-key__icon" name="keyboard-collapse" size="44rpx"></oxy-icon>
21
21
  </template>
22
22
  <template v-else>{{ text }}</template>
23
23
  </view>
@@ -3,9 +3,24 @@ import { makeBooleanProp, makeNumericProp, makeStringProp } from '../../common/p
3
3
  export type NumberKeyType = '' | 'delete' | 'extra' | 'close'
4
4
 
5
5
  export const keyProps = {
6
+ /**
7
+ * 按键类型
8
+ */
6
9
  type: makeStringProp<NumberKeyType>(''),
10
+ /**
11
+ * 按键显示文本
12
+ */
7
13
  text: makeNumericProp(''),
14
+ /**
15
+ * 是否为加宽按键
16
+ */
8
17
  wider: makeBooleanProp(false),
18
+ /**
19
+ * 是否为大号按键
20
+ */
9
21
  large: makeBooleanProp(false),
22
+ /**
23
+ * 是否显示加载状态
24
+ */
10
25
  loading: makeBooleanProp(false)
11
26
  }
@@ -3,6 +3,7 @@
3
3
  v-model="show"
4
4
  position="bottom"
5
5
  :z-index="zIndex"
6
+ :max-width="popupMaxWidth"
6
7
  :safe-area-inset-bottom="safeAreaInsetBottom"
7
8
  :modal-style="modal ? '' : 'opacity: 0;'"
8
9
  :modal="hideOnClickOutside"