oxy-uni-ui 2.1.2 → 2.1.4

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 +4 -2
  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
@@ -24,7 +24,9 @@
24
24
  export default {
25
25
  name: 'oxy-grid-item',
26
26
  options: {
27
+ // #ifndef MP-TOUTIAO
27
28
  virtualHost: true,
29
+ // #endif
28
30
  addGlobalClass: true,
29
31
  styleIsolation: 'shared'
30
32
  }
@@ -53,8 +55,8 @@ const border = ref<boolean>(true)
53
55
  const { parent: grid } = useParent(GRID_KEY)
54
56
 
55
57
  const childCount = computed(() => {
56
- if (isDef(grid) && isDef(grid.children)) {
57
- return grid.children.length
58
+ if (isDef(grid.value) && isDef(grid.value.children)) {
59
+ return grid.value.children.length
58
60
  } else {
59
61
  return 0
60
62
  }
@@ -79,13 +81,13 @@ const customBadgeProps = computed(() => {
79
81
  watch(
80
82
  () => childCount.value,
81
83
  () => {
82
- if (!grid) return
83
- const width = grid.props.column ? 100 / grid.props.column + '%' : 100 / (childCount.value || 1) + '%'
84
- const gutterSize = grid.props.gutter ? withDefaultUnit(grid.props.gutter) : ''
84
+ if (!grid.value) return
85
+ const width = grid.value.props.column ? 100 / grid.value.props.column + '%' : 100 / (childCount.value || 1) + '%'
86
+ const gutterSize = grid.value.props.gutter ? withDefaultUnit(grid.value.props.gutter) : ''
85
87
  // 单独定义间隔
86
88
  const gutterStyle = gutterSize ? `padding:${gutterSize} ${gutterSize} 0 0; background-color: transparent;` : ''
87
89
  // 单独定义正方形
88
- const squareStyle = grid.props.square ? `background-color:transparent; padding-bottom: 0; padding-top:${width}` : ''
90
+ const squareStyle = grid.value.props.square ? `background-color:transparent; padding-bottom: 0; padding-top:${width}` : ''
89
91
  style.value = `width: ${width}; ${squareStyle || gutterStyle}`
90
92
  },
91
93
  {
@@ -99,28 +101,28 @@ onMounted(() => {
99
101
  })
100
102
 
101
103
  function init() {
102
- if (!grid) return
103
- const children = grid.children
104
- const width = grid.props.column ? 100 / grid.props.column + '%' : 100 / children.length + '%'
105
- const gutterSize = grid.props.gutter ? withDefaultUnit(grid.props.gutter) : ''
104
+ if (!grid.value) return
105
+ const children = grid.value.children
106
+ const width = grid.value.props.column ? 100 / grid.value.props.column + '%' : 100 / children.length + '%'
107
+ const gutterSize = grid.value.props.gutter ? withDefaultUnit(grid.value.props.gutter) : ''
106
108
  // 单独定义间隔
107
109
  const gutterStyle = gutterSize ? `padding:${gutterSize} ${gutterSize} 0 0; background-color: transparent;` : ''
108
110
  // 单独定义正方形
109
- const squareStyle = grid.props.square ? `background-color:transparent; padding-bottom: 0; padding-top:${width}` : ''
111
+ const squareStyle = grid.value.props.square ? `background-color:transparent; padding-bottom: 0; padding-top:${width}` : ''
110
112
  // 间隔+正方形
111
113
  gutterContentStyle.value =
112
- gutterSize && grid.props.square
113
- ? `right: ${gutterSize}; bottom:${gutterSize};height: auto; background-color: ${grid.props.bgColor}`
114
- : `background-color: ${grid.props.bgColor}`
114
+ gutterSize && grid.value.props.square
115
+ ? `right: ${gutterSize}; bottom:${gutterSize};height: auto; background-color: ${grid.value.props.bgColor}`
116
+ : `background-color: ${grid.value.props.bgColor}`
115
117
 
116
- border.value = Boolean(grid.props.border)
117
- square.value = Boolean(grid.props.square)
118
- gutter.value = Number(grid.props.gutter)
118
+ border.value = Boolean(grid.value.props.border)
119
+ square.value = Boolean(grid.value.props.square)
120
+ gutter.value = Number(grid.value.props.gutter)
119
121
  style.value = `width: ${width}; ${squareStyle || gutterStyle}`
120
122
  }
121
123
 
122
124
  function click() {
123
- if (grid && !grid.props.clickable) return
125
+ if (grid.value && !grid.value.props.clickable) return
124
126
  const { url, linkType } = props
125
127
  emit('itemclick')
126
128
  if (url) {
@@ -160,8 +162,8 @@ function setiIemClass(classes: string) {
160
162
  }
161
163
 
162
164
  const hoverClass = computed(() => {
163
- if (grid?.props.clickable) {
164
- return grid.props.hoverClass ? grid.props.hoverClass : 'oxy-grid-item__content--hover'
165
+ if (grid.value?.props.clickable) {
166
+ return grid.value.props.hoverClass ? grid.value.props.hoverClass : 'oxy-grid-item__content--hover'
165
167
  }
166
168
  return 'none'
167
169
  })
@@ -2,11 +2,11 @@
2
2
  @import '../common/abstracts/mixin';
3
3
 
4
4
  @include b(guide){
5
- z-index: 1001;
5
+ z-index: $-guide-content-z-index;
6
6
  @include e(box) {
7
7
  position: absolute;
8
- z-index: 10001;
9
- transition: all 0.2s;
8
+ z-index: $-guide-tip-z-index;
9
+ transition: all $-transition-duration-base;
10
10
 
11
11
  &::before {
12
12
  content: '';
@@ -18,7 +18,7 @@
18
18
  position: absolute;
19
19
  top: -8rpx;
20
20
  left: -8rpx;
21
- padding: 8rpx;
21
+ padding: $-spacing-8;
22
22
  }
23
23
 
24
24
  @include e(arrow) {
@@ -28,7 +28,7 @@
28
28
  position: absolute;
29
29
  top: 144rpx;
30
30
  left: 45%;
31
- z-index: 10000;
31
+ z-index: $-guide-arrow-z-index;
32
32
  transform: rotate(45deg);
33
33
  }
34
34
 
@@ -38,8 +38,8 @@
38
38
  color: $-guide-tip-color;
39
39
  position: absolute;
40
40
  top: 152rpx;
41
- z-index: 10001;
42
- padding: 16rpx 20rpx;
41
+ z-index: $-guide-tip-z-index;
42
+ padding: $-spacing-16 $-spacing-20;
43
43
  font-size: $-fs-content;
44
44
  border-radius: $-guide-tip-radius;
45
45
  text-align: justify;
@@ -49,7 +49,7 @@
49
49
  justify-content: space-between;
50
50
  align-items: center;
51
51
  padding-right: 0;
52
- margin-top: 20rpx;
52
+ margin-top: $-spacing-20;
53
53
 
54
54
  @include e(next) {
55
55
  background: $-guide-tip-action-bg;
@@ -70,6 +70,6 @@
70
70
  top: 0;
71
71
  width: 100%;
72
72
  height: 100%;
73
- z-index: 1000;
73
+ z-index: $-guide-model-z-index;
74
74
  }
75
75
  }
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <view :class="['oxy-guide', customClass]" v-if="showGuide" :style="customStyle" @touchmove.stop.prevent>
3
3
  <view class="oxy-guide__box" :style="guideStyle">
4
- <view ref="tips" class="oxy-guide__box__tips" :style="tipPosition">
4
+ <view class="oxy-guide__box__tips" :style="tipPosition">
5
5
  <view class="text">{{ guideInfo.tips }}</view>
6
6
  <view class="oxy-guide__box__tips__tool-btn">
7
- <text class="oxy-guide__box__tips__tool-btn-skip" @click="skip">跳过</text>
7
+ <text class="oxy-guide__box__tips__tool-btn-skip" @click="skip">{{ translate('skip') }}</text>
8
8
  <view class="oxy-guide__box__tips__tool-btn__next" @click="next">{{ guideInfo.next }}</view>
9
9
  </view>
10
10
  </view>
@@ -19,7 +19,9 @@
19
19
  export default {
20
20
  name: 'oxy-guidance',
21
21
  options: {
22
+ // #ifndef MP-TOUTIAO
22
23
  virtualHost: true,
24
+ // #endif
23
25
  addGlobalClass: true,
24
26
  styleIsolation: 'shared'
25
27
  }
@@ -27,12 +29,14 @@ export default {
27
29
  </script>
28
30
 
29
31
  <script lang="ts" setup>
30
- import { computed, getCurrentInstance, nextTick, onMounted, ref, watch } from 'vue'
32
+ import { computed, getCurrentInstance, nextTick, onMounted, ref } from 'vue'
31
33
  import { unitConvert } from '../common/util'
32
34
  import { guidanceProps, type guideListType } from './types'
35
+ import { useTranslate } from '../composables/useTranslate'
33
36
  import NodeInfo = UniNamespace.NodeInfo
34
37
 
35
38
  const props = defineProps(guidanceProps)
39
+ const { translate } = useTranslate('guidance')
36
40
 
37
41
  const stepName = ref('step') //该提示步骤的名称,用于不在重复展示
38
42
 
@@ -114,9 +118,13 @@ function next() {
114
118
  }
115
119
  }
116
120
 
117
- const tips = ref()
118
-
119
121
  // 展示新手提示
122
+ /**
123
+ * 展示新手提示。根据目标元素 rect 计算引导框位置、箭头方向和提示框定位。
124
+ * 若提示框超出屏幕底部,自动翻转方向(箭头在上/提示框在上)。
125
+ * @param data - 目标元素的 boundingClientRect
126
+ * @param scrollTop - 当前页面滚动距离
127
+ */
120
128
  function viewTips(data: any, scrollTop: number) {
121
129
  if (data) {
122
130
  // 如果dom宽度大于或者等于窗口宽度,需要重新调整dom展示宽度
@@ -128,13 +136,7 @@ function viewTips(data: any, scrollTop: number) {
128
136
  if (data.left == 0) {
129
137
  data.left = 10
130
138
  }
131
- let domRW = systemInfo.value.windowWidth - data.left
132
- let left = 0
133
- tipWidth.value = tips.value.$el.clientWidth
134
- // 如果dom距离右边没有tips的宽度大的话,就要让tips向左偏移
135
- if (domRW < tipWidth.value) {
136
- left = domRW - tipWidth.value
137
- }
139
+ const domRW = systemInfo.value.windowWidth - data.left
138
140
  // 步骤条展示的高度需要加上屏幕滚动的高度
139
141
  data.top += scrollTop
140
142
  // 根据实际情况需要滚动到展示区域
@@ -142,17 +144,21 @@ function viewTips(data: any, scrollTop: number) {
142
144
  scrollTop: data.top > 44 ? data.top - 44 : 0,
143
145
  duration: 100
144
146
  })
145
- let obj = Object.assign(guideList.value[index.value], data)
147
+ const obj = Object.assign(guideList.value[index.value], data)
146
148
  // 设置三角形高度
147
- let arrowTopHeight = data.height + 9
149
+ const arrowTopHeight = data.height + 9
148
150
  //如果dom在屏幕底部的话,重新调整提示框和三角形的定位
149
- let newHeight = systemInfo.value.windowHeight - data.bottom
151
+ const newHeight = systemInfo.value.windowHeight - data.bottom
150
152
  uni
151
153
  .createSelectorQuery()
152
154
  .in(proxy)
153
155
  .select('.oxy-guide__box__tips')
154
156
  .boundingClientRect((res) => {
155
- if (newHeight > ((res as NodeInfo).height ?? 0) + 5) {
157
+ const tipsRect = res as NodeInfo | null
158
+ tipWidth.value = tipsRect?.width ?? 0
159
+ // 如果dom距离右边没有tips的宽度大的话,就要让tips向左偏移
160
+ const left = domRW < tipWidth.value ? domRW - tipWidth.value : 0
161
+ if (newHeight > (tipsRect?.height ?? 0) + 5) {
156
162
  // 设置提示框定位
157
163
  arrowTop.value = `top: ${toPx(arrowTopHeight)};`
158
164
  tipPosition.value = `top: ${toPx(arrowTopHeight + 5)};${
@@ -8,7 +8,9 @@
8
8
  export default {
9
9
  name: 'oxy-icon',
10
10
  options: {
11
+ // #ifndef MP-TOUTIAO
11
12
  virtualHost: true,
13
+ // #endif
12
14
  addGlobalClass: true,
13
15
  styleIsolation: 'shared'
14
16
  }
@@ -1,3 +1,4 @@
1
+ import type { ExtractPropTypes } from 'vue'
1
2
  import { baseProps, makeRequiredProp, makeStringProp, numericProp } from '../common/props'
2
3
 
3
4
  export const iconProps = {
@@ -19,3 +20,5 @@ export const iconProps = {
19
20
  */
20
21
  classPrefix: makeStringProp('oxy-icon')
21
22
  }
23
+
24
+ export type IconProps = ExtractPropTypes<typeof iconProps>
@@ -0,0 +1,75 @@
1
+ @import '../common/abstracts/variable.scss';
2
+ @import '../common/abstracts/_mixin.scss';
3
+
4
+ @include b(image-preview) {
5
+ display: flex;
6
+ width: 100%;
7
+ height: 100%;
8
+ background: $-image-preview-bg;
9
+
10
+ @include e(close) {
11
+ position: absolute;
12
+ z-index: $-image-preview-close-z-index;
13
+ display: flex;
14
+ justify-content: center;
15
+ align-items: center;
16
+
17
+ @include m(top-right) {
18
+ top: $-image-preview-close-margin;
19
+ right: $-image-preview-close-margin;
20
+ }
21
+
22
+ @include m(top-left) {
23
+ top: $-image-preview-close-margin;
24
+ left: $-image-preview-close-margin;
25
+ }
26
+ }
27
+
28
+ @include edeep(close-icon) {
29
+ font-size: $-image-preview-close-size;
30
+ line-height: $-image-preview-close-size;
31
+ color: $-image-preview-close-color;
32
+ }
33
+
34
+ @include e(index) {
35
+ position: absolute;
36
+ top: $-image-preview-index-margin;
37
+ left: 50%;
38
+ transform: translateX(-50%);
39
+ z-index: $-image-preview-index-z-index;
40
+ color: $-image-preview-index-color;
41
+ font-size: $-image-preview-index-font-size;
42
+ line-height: $-image-preview-index-line-height;
43
+ font-weight: $-image-preview-index-font-weight;
44
+ }
45
+
46
+ @include e(swiper) {
47
+ width: 100%;
48
+ height: 100%;
49
+ }
50
+
51
+ @include e(swiper-item) {
52
+ width: 100%;
53
+ height: 100%;
54
+ display: flex;
55
+ justify-content: center;
56
+ align-items: center;
57
+ overflow: hidden;
58
+
59
+ :deep() {
60
+ .oxy-swiper__item {
61
+ width: 100%;
62
+ height: 100%;
63
+ padding: 0;
64
+ }
65
+ }
66
+ }
67
+
68
+ @include e(image) {
69
+ width: 100%;
70
+ height: 100%;
71
+ object-fit: contain;
72
+ transform-origin: center center;
73
+ will-change: transform;
74
+ }
75
+ }
@@ -0,0 +1,56 @@
1
+ import { inject, provide, ref } from 'vue'
2
+ import type { ImagePreview, ImagePreviewOptions } from './types'
3
+ import { deepMerge, isArray } from '../common/util'
4
+
5
+ const imagePreviewDefaultOptionKey = '__IMAGE_PREVIEW_OPTION__'
6
+
7
+ export const defaultOptions: ImagePreviewOptions = {
8
+ images: [],
9
+ startPosition: 0,
10
+ showIndex: true,
11
+ loop: true,
12
+ closeable: true,
13
+ closeIcon: 'close',
14
+ closeIconPosition: 'top-right',
15
+ closeOnClick: true,
16
+ showMenuByLongpress: true,
17
+ show: false,
18
+ zIndex: 1000
19
+ }
20
+
21
+ const None = Symbol('None')
22
+
23
+ export function useImagePreview(selector: string = ''): ImagePreview {
24
+ const imagePreviewOptionKey = getImagePreviewOptionKey(selector)
25
+ const imagePreviewOption = inject(imagePreviewOptionKey, ref<ImagePreviewOptions | typeof None>(None))
26
+
27
+ if (imagePreviewOption.value === None) {
28
+ imagePreviewOption.value = defaultOptions
29
+ provide(imagePreviewOptionKey, imagePreviewOption)
30
+ }
31
+
32
+ const open = (options: ImagePreviewOptions | string[]) => {
33
+ let mergedOptions: ImagePreviewOptions
34
+
35
+ if (isArray(options)) {
36
+ mergedOptions = deepMerge(defaultOptions, { images: options }) as ImagePreviewOptions
37
+ } else {
38
+ mergedOptions = deepMerge(defaultOptions, options) as ImagePreviewOptions
39
+ }
40
+
41
+ imagePreviewOption.value = deepMerge(mergedOptions, { show: true }) as ImagePreviewOptions
42
+ }
43
+
44
+ const close = () => {
45
+ imagePreviewOption.value = { show: false } as ImagePreviewOptions
46
+ }
47
+
48
+ return {
49
+ previewImage: open,
50
+ closeImagePreview: close
51
+ }
52
+ }
53
+
54
+ export const getImagePreviewOptionKey = (selector: string) => {
55
+ return selector ? `${imagePreviewDefaultOptionKey}${selector}` : imagePreviewDefaultOptionKey
56
+ }
@@ -0,0 +1,221 @@
1
+ <template>
2
+ <oxy-overlay
3
+ :show="state.show"
4
+ :z-index="options.zIndex"
5
+ :lock-scroll="true"
6
+ :custom-class="`oxy-image-preview ${props.customClass}`"
7
+ :custom-style="props.customStyle"
8
+ @enter="handleEnter"
9
+ @after-leave="handleAfterLeave"
10
+ >
11
+ <slot name="close" :close="close">
12
+ <view v-if="options.closeable" :class="`oxy-image-preview__close oxy-image-preview__close--${options.closeIconPosition}`" @click.stop="close">
13
+ <oxy-icon :name="options.closeIcon" custom-class="oxy-image-preview__close-icon" />
14
+ </view>
15
+ </slot>
16
+
17
+ <oxy-swiper
18
+ v-if="state.visible"
19
+ custom-class="oxy-image-preview__swiper"
20
+ custom-item-class="oxy-image-preview__swiper-item"
21
+ :list="state.images"
22
+ v-model:current="state.currentIndex"
23
+ :autoplay="false"
24
+ :loop="options.loop"
25
+ image-mode="aspectFit"
26
+ height="100%"
27
+ @change="handleSwiperChange"
28
+ >
29
+ <template #default="{ item, index }">
30
+ <image
31
+ :src="getImageUrl(item)"
32
+ class="oxy-image-preview__image"
33
+ mode="aspectFit"
34
+ :show-menu-by-longpress="options.showMenuByLongpress"
35
+ @click="handleImageClick(index)"
36
+ @longpress="handleLongPress(item)"
37
+ />
38
+ </template>
39
+ <template #indicator="{ total, current }">
40
+ <slot name="indicator" :total="total" :current="current">
41
+ <view v-if="options.showIndex && total > 1" class="oxy-image-preview__index">{{ current + 1 }} / {{ total }}</view>
42
+ </slot>
43
+ </template>
44
+ </oxy-swiper>
45
+
46
+ <slot :current="state.currentIndex" :total="state.images.length" :images="state.images" :close="close"></slot>
47
+ </oxy-overlay>
48
+ </template>
49
+
50
+ <script lang="ts">
51
+ export default {
52
+ name: 'oxy-image-preview',
53
+ options: {
54
+ addGlobalClass: true,
55
+ // #ifndef MP-TOUTIAO
56
+ virtualHost: true,
57
+ // #endif
58
+ styleIsolation: 'shared'
59
+ }
60
+ }
61
+ </script>
62
+
63
+ <script lang="ts" setup>
64
+ import { computed, inject, reactive, ref, watch } from 'vue'
65
+ import OxyIcon from '../oxy-icon/oxy-icon.vue'
66
+ import OxyOverlay from '../oxy-overlay/oxy-overlay.vue'
67
+ import OxySwiper from '../oxy-swiper/oxy-swiper.vue'
68
+ import { imagePreviewProps, type ImagePreviewExpose, type ImagePreviewOptions } from './types'
69
+ import { defaultOptions, getImagePreviewOptionKey } from './index'
70
+ import { isArray, isDef, isFunction, isString } from '../common/util'
71
+ import type { SwiperList } from '../oxy-swiper/types'
72
+
73
+ const props = defineProps(imagePreviewProps)
74
+
75
+ const emit = defineEmits<{
76
+ open: []
77
+ close: []
78
+ click: [{ index: number }]
79
+ change: [{ index: number }]
80
+ 'long-press': [{ image: string }]
81
+ }>()
82
+
83
+ const state = reactive({
84
+ show: false,
85
+ visible: false,
86
+ currentIndex: 0,
87
+ images: [] as string[]
88
+ })
89
+
90
+ const imagePreviewOptionKey = getImagePreviewOptionKey(props.selector)
91
+ const imagePreviewOption = inject(imagePreviewOptionKey, ref<ImagePreviewOptions>(defaultOptions))
92
+
93
+ const options = computed(() => ({
94
+ showIndex: isDef(imagePreviewOption.value.showIndex) ? imagePreviewOption.value.showIndex : props.showIndex,
95
+ loop: isDef(imagePreviewOption.value.loop) ? imagePreviewOption.value.loop : props.loop,
96
+ closeable: isDef(imagePreviewOption.value.closeable) ? imagePreviewOption.value.closeable : props.closeable,
97
+ closeIcon: isDef(imagePreviewOption.value.closeIcon) ? imagePreviewOption.value.closeIcon : props.closeIcon,
98
+ closeIconPosition: isDef(imagePreviewOption.value.closeIconPosition) ? imagePreviewOption.value.closeIconPosition : props.closeIconPosition,
99
+ closeOnClick: isDef(imagePreviewOption.value.closeOnClick) ? imagePreviewOption.value.closeOnClick : props.closeOnClick,
100
+ showMenuByLongpress: isDef(imagePreviewOption.value.showMenuByLongpress) ? imagePreviewOption.value.showMenuByLongpress : props.showMenuByLongpress,
101
+ zIndex: isDef(imagePreviewOption.value.zIndex) ? imagePreviewOption.value.zIndex! : props.zIndex,
102
+ onOpen: imagePreviewOption.value.onOpen || props.onOpen || null,
103
+ onClose: imagePreviewOption.value.onClose || props.onClose || null,
104
+ onChange: imagePreviewOption.value.onChange || props.onChange || null,
105
+ onLongPress: imagePreviewOption.value.onLongPress || props.onLongPress || null
106
+ }))
107
+
108
+ watch(
109
+ () => imagePreviewOption.value,
110
+ (newVal: ImagePreviewOptions) => {
111
+ reset(newVal)
112
+ },
113
+ { deep: true, immediate: true }
114
+ )
115
+
116
+ watch(
117
+ () => state.show,
118
+ (newVal, oldVal) => {
119
+ if (newVal && !oldVal) {
120
+ emit('open')
121
+ if (isFunction(options.value.onOpen)) {
122
+ options.value.onOpen()
123
+ }
124
+ } else if (!newVal && oldVal) {
125
+ emit('close')
126
+ if (isFunction(options.value.onClose)) {
127
+ options.value.onClose()
128
+ }
129
+ }
130
+ }
131
+ )
132
+
133
+ function reset(option: ImagePreviewOptions) {
134
+ state.show = isDef(option.show) ? option.show! : false
135
+
136
+ if (state.show) {
137
+ state.images = isDef(option.images) ? option.images! : props.images || []
138
+ state.currentIndex = normalizeIndex(isDef(option.startPosition) ? option.startPosition! : props.startPosition)
139
+ }
140
+ }
141
+
142
+ function normalizeIndex(index: number) {
143
+ const total = state.images.length
144
+ if (!total) return 0
145
+ if (options.value.loop) {
146
+ return (index + total) % total
147
+ }
148
+ return Math.min(Math.max(index, 0), total - 1)
149
+ }
150
+
151
+ function handleEnter() {
152
+ state.visible = true
153
+ }
154
+
155
+ function handleAfterLeave() {
156
+ state.visible = false
157
+ state.images = []
158
+ state.currentIndex = 0
159
+ }
160
+
161
+ function open(opts?: ImagePreviewOptions | string[]) {
162
+ if (opts) {
163
+ if (isArray(opts)) {
164
+ state.images = opts
165
+ state.currentIndex = normalizeIndex(props.startPosition)
166
+ } else {
167
+ state.images = isDef(opts.images) ? opts.images! : props.images || []
168
+ state.currentIndex = normalizeIndex(isDef(opts.startPosition) ? opts.startPosition! : props.startPosition)
169
+ }
170
+ } else {
171
+ state.images = props.images || []
172
+ state.currentIndex = normalizeIndex(props.startPosition)
173
+ }
174
+ state.show = true
175
+ }
176
+
177
+ function close() {
178
+ state.show = false
179
+ }
180
+
181
+ function setActive(index: number) {
182
+ state.currentIndex = normalizeIndex(index)
183
+ }
184
+
185
+ function handleSwiperChange({ current }: { current: number }) {
186
+ state.currentIndex = current
187
+ emit('change', { index: current })
188
+ if (isFunction(options.value.onChange)) {
189
+ options.value.onChange(current)
190
+ }
191
+ }
192
+
193
+ function handleImageClick(index: number) {
194
+ emit('click', { index })
195
+ if (options.value.closeOnClick) {
196
+ close()
197
+ }
198
+ }
199
+
200
+ function handleLongPress(image: string | SwiperList) {
201
+ const url = getImageUrl(image)
202
+ emit('long-press', { image: url })
203
+ if (isFunction(options.value.onLongPress)) {
204
+ options.value.onLongPress(url)
205
+ }
206
+ }
207
+
208
+ function getImageUrl(image: string | SwiperList) {
209
+ return isString(image) ? image : image.value || ''
210
+ }
211
+
212
+ defineExpose<ImagePreviewExpose>({
213
+ open,
214
+ close,
215
+ setActive
216
+ })
217
+ </script>
218
+
219
+ <style lang="scss">
220
+ @import './index.scss';
221
+ </style>