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
@@ -17,7 +17,9 @@
17
17
  export default {
18
18
  name: 'oxy-loadmore',
19
19
  options: {
20
+ // #ifndef MP-TOUTIAO
20
21
  virtualHost: true,
22
+ // #endif
21
23
  addGlobalClass: true,
22
24
  styleIsolation: 'shared'
23
25
  }
@@ -26,7 +26,7 @@
26
26
  left: 0;
27
27
  right: 0;
28
28
  bottom: 0;
29
- z-index: 998;
29
+ z-index: $-z-index-overlay;
30
30
  background-color: transparent; /* 透明遮罩,点击关闭 */
31
31
  }
32
32
 
@@ -1,18 +1,23 @@
1
1
  <template>
2
- <view :id="elId" :data-id="elId" :class="`oxy-long-press-menu ${mode === 'selection' ? 'is-selectable' : ''} ${customClass}`" :style="customStyle">
2
+ <view
3
+ :id="elId"
4
+ :data-id="elId"
5
+ :class="`oxy-long-press-menu ${effectiveMode === 'selection' ? 'is-selectable' : ''} ${customClass}`"
6
+ :style="customStyle"
7
+ >
3
8
  <!-- 触发区域 -->
4
9
  <!-- mode='normal': 使用 longpress 事件 -->
5
10
  <!-- mode='selection': 不使用 longpress,依靠 renderjs/js 监听 selection -->
6
11
  <view
7
12
  class="oxy-long-press-menu__trigger"
8
- @longpress="mode === 'normal' ? onLongPress($event) : null"
9
- :class="{ 'is-active': isVisible && mode === 'normal' }"
13
+ @longpress="effectiveMode === 'normal' ? onLongPress($event) : null"
14
+ :class="{ 'is-active': isVisible && effectiveMode === 'normal' }"
10
15
  >
11
16
  <slot></slot>
12
17
  </view>
13
18
 
14
19
  <!-- 遮罩层 (Normal模式使用,Selection模式不需要遮罩,依靠原生行为关闭) -->
15
- <view v-if="isVisible && mode === 'normal'" class="oxy-long-press-menu__mask" @click="hideMenu" @touchmove.stop.prevent></view>
20
+ <view v-if="isVisible && effectiveMode === 'normal'" class="oxy-long-press-menu__mask" @click="hideMenu" @touchmove.stop.prevent></view>
16
21
 
17
22
  <!-- 气泡菜单 -->
18
23
  <view v-if="isVisible" class="oxy-long-press-menu__popover" :style="popoverStyle" @click.stop>
@@ -36,6 +41,7 @@
36
41
 
37
42
  <script>
38
43
  import { uuid, getRect, unitConvert } from '../common/util'
44
+ import { useTranslate } from '../composables/useTranslate'
39
45
 
40
46
  export default {
41
47
  name: 'oxy-long-press-menu',
@@ -77,16 +83,31 @@ export default {
77
83
  arrowBottom: true
78
84
  }
79
85
  },
86
+ setup() {
87
+ const { translate } = useTranslate('longPressMenu')
88
+ return { translate }
89
+ },
90
+ computed: {
91
+ effectiveMode() {
92
+ let mode = this.mode
93
+ // #ifndef APP-PLUS || H5
94
+ if (mode === 'selection') {
95
+ mode = 'normal'
96
+ }
97
+ // #endif
98
+ return mode
99
+ }
100
+ },
80
101
  watch: {
81
102
  // 监听外部 content 变化
82
103
  content(val) {
83
- if (this.mode === 'normal') {
104
+ if (this.effectiveMode === 'normal') {
84
105
  this.selectedText = val
85
106
  }
86
107
  }
87
108
  },
88
109
  created() {
89
- if (this.mode === 'normal') {
110
+ if (this.effectiveMode === 'normal') {
90
111
  this.selectedText = this.content
91
112
  }
92
113
  },
@@ -94,11 +115,11 @@ export default {
94
115
  // --- RenderJS 通信方法 ---
95
116
  // 接收 renderjs 发来的选中区域信息
96
117
  onSelectionChange(data) {
97
- if (this.mode !== 'selection') return
118
+ if (this.effectiveMode !== 'selection') return
98
119
 
99
120
  if (!data) {
100
121
  // 清除选中
101
- if (this.mode === 'selection') {
122
+ if (this.effectiveMode === 'selection') {
102
123
  this.isVisible = false
103
124
  }
104
125
  return
@@ -113,7 +134,7 @@ export default {
113
134
 
114
135
  // --- 现有逻辑 ---
115
136
  onLongPress(e) {
116
- if (this.mode !== 'normal') return
137
+ if (this.effectiveMode !== 'normal') return
117
138
 
118
139
  // 获取触发元素的位置
119
140
  getRect('.oxy-long-press-menu__trigger', false, this)
@@ -125,17 +146,25 @@ export default {
125
146
  .catch(() => {})
126
147
  this.$emit('longpress', e)
127
148
  },
149
+ /**
150
+ * 展示气泡菜单。根据触发元素 rect 计算气泡位置和箭头方向。
151
+ * - 上方空间不足时翻转到下方显示
152
+ * - 渲染后二次修正:气泡超出屏幕左侧则右对齐,超出右侧则左对齐
153
+ * - 同步修正箭头位置
154
+ * - Normal 模式触发振动反馈
155
+ * @param rect - 触发元素的 boundingClientRect
156
+ */
128
157
  showMenu(rect) {
129
158
  this.rect = rect
130
159
  // 计算气泡位置
131
160
  // 默认显示在元素上方
132
161
  this.arrowBottom = true // 箭头在底部(气泡在上方)
133
- let top = rect.top - (this.mode !== 'normal' ? 60 : 10) // 预估气泡高度 + 箭头 + 间距
162
+ let top = rect.top - (this.effectiveMode !== 'normal' ? 60 : 10) // 预估气泡高度 + 箭头 + 间距
134
163
  let left = rect.left + rect.width / 2
135
164
  // 如果上方空间不足,显示在下方
136
165
  if (top < 50) {
137
166
  // 顶部留一些安全距离
138
- top = rect.bottom + (this.mode !== 'normal' ? 20 : 60)
167
+ top = rect.bottom + (this.effectiveMode !== 'normal' ? 20 : 60)
139
168
  this.arrowBottom = false // 箭头在顶部(气泡在下方)
140
169
  }
141
170
  this.popoverStyle = {
@@ -172,7 +201,7 @@ export default {
172
201
  .catch(() => {})
173
202
  })
174
203
  // 振动反馈 (仅 Normal 模式或首次显示时)
175
- if (this.mode === 'normal') {
204
+ if (this.effectiveMode === 'normal') {
176
205
  uni.vibrateShort()
177
206
  }
178
207
  },
@@ -193,7 +222,7 @@ export default {
193
222
  data: textToCopy,
194
223
  success: () => {
195
224
  uni.showToast({
196
- title: '已复制',
225
+ title: this.translate('copied'),
197
226
  icon: 'none'
198
227
  })
199
228
  }
@@ -1,9 +1,9 @@
1
- @import "../common/abstracts/variable.scss";
2
- @import "../common/abstracts/_mixin.scss";
1
+ @import '../common/abstracts/variable.scss';
2
+ @import '../common/abstracts/_mixin.scss';
3
3
 
4
4
  .oxy-theme-dark {
5
5
  @include b(message-box) {
6
- @include e(body) {
6
+ @include e(container) {
7
7
  background-color: $-dark-background2;
8
8
  }
9
9
 
@@ -11,55 +11,111 @@
11
11
  color: $-dark-color;
12
12
  }
13
13
 
14
- @include e(content) {
14
+ @include e(content-text) {
15
15
  color: $-dark-color3;
16
+ }
16
17
 
18
+ @include e(content) {
17
19
  &::-webkit-scrollbar-thumb {
18
20
  background: $-dark-border-color;
19
21
  }
20
22
  }
23
+
24
+ @include e(close) {
25
+ color: $-dark-color3;
26
+ }
21
27
  }
22
28
  }
23
29
 
24
- :deep(.oxy-message-box){
25
- border-radius: $-message-box-radius;
26
- overflow: hidden;
30
+ :deep() {
31
+ .oxy-popup.oxy-message-box {
32
+ background: transparent;
33
+ border-radius: $-message-box-radius;
34
+ overflow: hidden;
35
+ }
27
36
  }
28
37
 
29
38
  @include b(message-box) {
30
- border-radius: $-message-box-radius;
31
- overflow: hidden;
32
-
33
39
  @include e(container) {
40
+ background: $-message-box-bg;
41
+ border-radius: $-message-box-radius;
42
+ overflow: hidden;
34
43
  box-sizing: border-box;
44
+ position: relative;
35
45
  }
36
46
 
37
47
  @include e(body) {
38
- background-color: $-message-box-bg;
39
48
  padding: $-message-box-padding;
40
49
 
41
- @include when(no-title) {
42
- padding: 56rpx 48rpx 0rpx;
50
+ @include when(prompt) {
51
+ .oxy-message-box__content {
52
+ padding-top: $-message-box-input-padding-top;
53
+ }
54
+ }
55
+ }
56
+
57
+ @include e(img) {
58
+ display: block;
59
+ width: 100%;
60
+ height: auto;
61
+ border-radius: $-message-box-img-radius;
62
+
63
+ & + .oxy-message-box__title {
64
+ margin-top: $-message-box-body-spacing-large;
65
+ }
66
+
67
+ & + .oxy-message-box__content {
68
+ margin-top: $-message-box-body-spacing-large;
69
+
70
+ .oxy-message-box__body.is-prompt & {
71
+ margin-top: $-message-box-body-spacing;
72
+ }
43
73
  }
44
74
  }
45
75
 
46
76
  @include e(title) {
77
+ display: flex;
78
+ flex-direction: column;
79
+ align-items: center;
47
80
  text-align: center;
48
81
  font-size: $-message-box-title-fs;
49
82
  color: $-message-box-title-color;
50
- line-height: $-lh-base;
51
- font-weight: $-fw-medium;
52
- padding-top: $-spacing-16;
53
- padding-bottom: $-spacing-24;
83
+ line-height: $-message-box-title-line-height;
84
+ font-weight: $-message-box-title-fw;
85
+
86
+ & + .oxy-message-box__content {
87
+ margin-top: $-message-box-body-spacing;
88
+ }
89
+ }
90
+
91
+ @include e(icon) {
92
+ font-size: $-message-box-icon-size;
93
+ line-height: $-message-box-icon-size;
94
+ margin: 0 auto;
95
+ margin-bottom: $-message-box-icon-margin-bottom;
96
+ color: $-message-box-icon-color;
97
+
98
+ @include when(success) {
99
+ color: $-message-box-icon-success-color;
100
+ }
101
+
102
+ @include when(info) {
103
+ color: $-message-box-icon-info-color;
104
+ }
105
+
106
+ @include when(warning) {
107
+ color: $-message-box-icon-warning-color;
108
+ }
109
+
110
+ @include when(danger) {
111
+ color: $-message-box-icon-danger-color;
112
+ }
54
113
  }
55
114
 
56
115
  @include e(content) {
57
116
  max-height: $-message-box-content-max-height;
58
- color: $-message-box-content-color;
59
- font-size: $-message-box-content-fs;
60
117
  text-align: center;
61
118
  overflow: auto;
62
- line-height: $-lh-base;
63
119
 
64
120
  &::-webkit-scrollbar {
65
121
  width: $-message-box-content-scrollbar-width;
@@ -72,38 +128,169 @@
72
128
  }
73
129
  }
74
130
 
131
+ @include e(content-text) {
132
+ color: $-message-box-content-color;
133
+ font-size: $-message-box-content-fs;
134
+ line-height: $-message-box-content-line-height;
135
+
136
+ @include m(prompt) {
137
+ display: block;
138
+ margin-bottom: $-message-box-body-spacing;
139
+ }
140
+ }
141
+
75
142
  @include e(input-error) {
76
- min-height: 40rpx;
77
- margin-top: 8rpx;
78
143
  color: $-message-box-input-error-color;
144
+ font-size: $-message-box-input-fs;
145
+ line-height: $-message-box-input-line-height;
146
+ padding-top: $-message-box-input-padding-top;
79
147
  text-align: left;
80
-
81
- @include when(hidden) {
82
- visibility: hidden;
83
- }
84
148
  }
85
149
 
86
150
  @include e(actions) {
87
- padding: 48rpx;
88
- }
89
-
90
- @include edeep(actions-btn) {
91
- &:not(:last-child) {
92
- margin-right: $-spacing-32;
151
+ padding: $-message-box-actions-padding;
152
+
153
+ :deep() {
154
+ .oxy-message-box__actions-btn {
155
+ min-width: 0;
156
+ flex: 1 1 0;
157
+
158
+ /* #ifndef MP-TOUTIAO */
159
+ &:not(:last-child) {
160
+ margin-right: $-message-box-actions-spacing;
161
+ }
162
+ /* #endif */
163
+ }
164
+
165
+ .oxy-message-box__actions-btn--confirm {
166
+ font-weight: $-message-box-actions-confirm-fw;
167
+ }
168
+ }
169
+
170
+ /* #ifdef MP-TOUTIAO */
171
+ // 抖音无 virtualHost,wrapper 元素阻断了 :deep(),改用 > * 作用于子元素
172
+ > *:not(:last-child) {
173
+ margin-right: $-message-box-actions-spacing;
174
+ }
175
+ /* #endif */
176
+
177
+ @include m(vertical) {
178
+ flex-direction: column;
179
+ padding: $-message-box-actions-padding-vertical;
180
+
181
+ :deep() {
182
+ .oxy-message-box__actions-btn {
183
+ flex: none;
184
+ width: 100%;
185
+
186
+ /* #ifndef MP-TOUTIAO */
187
+ &:not(:last-child) {
188
+ margin-right: 0;
189
+ margin-bottom: $-message-box-actions-spacing-vertical;
190
+ }
191
+ /* #endif */
192
+ }
193
+ }
194
+
195
+ /* #ifdef MP-TOUTIAO */
196
+ > *:not(:last-child) {
197
+ margin-right: 0;
198
+ margin-bottom: $-message-box-actions-spacing-vertical;
199
+ }
200
+ > * {
201
+ flex: none;
202
+ width: 100%;
203
+ }
204
+ /* #endif */
205
+ }
206
+
207
+ @include when(text) {
208
+ padding: $-message-box-actions-text-padding;
209
+
210
+ :deep() {
211
+ .oxy-message-box__actions-btn {
212
+ margin: 0;
213
+ border-radius: 0;
214
+ padding: $-message-box-actions-text-btn-padding;
215
+ border-top: $-message-box-actions-text-border;
216
+ border-color: $-message-box-actions-text-border-color;
217
+
218
+ &:not(:last-child) {
219
+ /* #ifndef MP-TOUTIAO */
220
+ margin-right: 0;
221
+ /* #endif */
222
+ border-right: $-message-box-actions-text-border;
223
+ border-color: $-message-box-actions-text-border-color;
224
+ }
225
+
226
+ &.is-text {
227
+ height: auto;
228
+ font-size: $-message-box-actions-text-btn-fs;
229
+ line-height: $-message-box-actions-text-btn-line-height;
230
+ }
231
+ }
232
+
233
+ .oxy-message-box__actions-btn--confirm.is-text {
234
+ color: $-message-box-actions-text-confirm-color;
235
+ }
236
+ }
237
+
238
+ /* #ifdef MP-TOUTIAO */
239
+ // 抖音下 text 主题样式通过 > * 作用到 wrapper 上
240
+ > * {
241
+ margin: 0;
242
+ border-radius: 0;
243
+ padding: $-message-box-actions-text-btn-padding;
244
+ border-top: $-message-box-actions-text-border;
245
+ border-color: $-message-box-actions-text-border-color;
246
+ }
247
+
248
+ > *:not(:last-child) {
249
+ border-right: $-message-box-actions-text-border;
250
+ border-color: $-message-box-actions-text-border-color;
251
+ }
252
+ /* #endif */
253
+
254
+ &.oxy-message-box__actions--vertical {
255
+ :deep() {
256
+ .oxy-message-box__actions-btn {
257
+ &:not(:last-child) {
258
+ border-right: none;
259
+ }
260
+ }
261
+ }
262
+
263
+ /* #ifdef MP-TOUTIAO */
264
+ > *:not(:last-child) {
265
+ border-right: none;
266
+ }
267
+ /* #endif */
268
+ }
93
269
  }
94
270
  }
95
271
 
96
272
  @include e(flex) {
97
273
  display: flex;
98
- justify-content: center;
99
- align-items: center;
274
+
275
+ /* #ifdef MP-TOUTIAO */
276
+ // 抖音下 flex 容器子元素是 wrapper 而非 button,需用 > * 直接作用
277
+ > * {
278
+ flex: 1;
279
+ min-width: 0;
280
+ }
281
+ /* #endif */
100
282
  }
101
283
 
102
284
  @include e(block) {
103
285
  display: block;
104
286
  }
105
287
 
106
- @include e(cancel) {
107
- margin-right: $-spacing-32;
288
+ @include e(close) {
289
+ position: absolute;
290
+ top: $-message-box-close-top;
291
+ right: $-message-box-close-right;
292
+ font-size: $-message-box-close-size;
293
+ color: $-message-box-close-color;
294
+ z-index: 1;
108
295
  }
109
296
  }
@@ -1,10 +1,7 @@
1
- import { inject, provide, ref } from 'vue'
2
1
  import type { Message, MessageOptions, MessageOptionsWithCallBack, MessageResult, MessageType } from './types'
3
- import { deepMerge } from '../common/util'
4
-
5
- const messageDefaultOptionKey = '__MESSAGE_OPTION__'
6
-
7
- const None = Symbol('None')
2
+ import { deepMerge, isDef, isObj, isString } from '../common/util'
3
+ import type { IconProps } from '../oxy-icon/types'
4
+ import { createSharedState } from '../composables/useSharedState'
8
5
 
9
6
  // 默认模板
10
7
  export const defaultOptions: MessageOptionsWithCallBack = {
@@ -14,39 +11,69 @@ export const defaultOptions: MessageOptionsWithCallBack = {
14
11
  closeOnClickModal: true,
15
12
  msg: '',
16
13
  type: 'alert',
14
+ theme: 'button',
15
+ actionLayout: 'horizontal',
17
16
  inputType: 'text',
18
17
  inputValue: '',
19
18
  showErr: false,
20
19
  zIndex: 99,
21
20
  lazyRender: true,
22
- inputError: ''
21
+ inputError: '',
22
+ showClose: false
23
23
  }
24
24
 
25
- export function useMessage(selector: string = ''): Message {
26
- const messageOptionKey = selector ? messageDefaultOptionKey + selector : messageDefaultOptionKey
27
- const messageOption = inject(messageOptionKey, ref<MessageOptionsWithCallBack | typeof None>(None)) // Message选项
28
- if (messageOption.value === None) {
29
- messageOption.value = defaultOptions
30
- provide(messageOptionKey, messageOption)
31
- }
25
+ const messageDefaultOptionKey = '__MESSAGE_OPTION__'
26
+
27
+ const {
28
+ getState: getMessageOptions,
29
+ initState: initMessageOptions,
30
+ removeState: removeMessageOptions,
31
+ resolveScopeId: resolveMessageScopeId
32
+ } = createSharedState<MessageOptionsWithCallBack>(() => defaultOptions, { namespace: 'message-box' })
32
33
 
34
+ export { getMessageOptions, initMessageOptions, removeMessageOptions, resolveMessageScopeId }
35
+
36
+ export function useMessage(selector: string = ''): Message {
37
+ const scopeId = resolveMessageScopeId()
33
38
  const createMethod = (type: MessageType) => {
34
39
  // 优先级:options->MessageOptions->defaultOptions
35
40
  return (options: MessageOptions | string) => {
36
- const messageOptions = deepMerge({ type: type }, typeof options === 'string' ? { title: options } : options) as MessageOptions
37
- if (messageOptions.type === 'confirm' || messageOptions.type === 'prompt') {
38
- messageOptions.showCancelButton = true
39
- } else {
40
- messageOptions.showCancelButton = false
41
+ const messageOptions = deepMerge({ type: type }, isString(options) ? { title: options } : options) as MessageOptions
42
+
43
+ // 保留历史行为:confirm / prompt 默认展示取消按钮,alert 默认不展示
44
+ if (!isDef(messageOptions.showCancelButton)) {
45
+ messageOptions.showCancelButton = messageOptions.type === 'confirm' || messageOptions.type === 'prompt'
41
46
  }
47
+
48
+ normalizeIconProps(messageOptions)
49
+
42
50
  return show(messageOptions)
43
51
  }
44
52
  }
45
53
 
54
+ /**
55
+ * 将 icon / iconColor 快捷字段合并到 iconProps 中,保持与 props 配置一致
56
+ */
57
+ function normalizeIconProps(options: MessageOptions) {
58
+ if (options.icon || options.iconColor) {
59
+ const iconProps: Partial<IconProps> = {}
60
+ if (options.icon) {
61
+ iconProps.name = options.icon
62
+ }
63
+ if (options.iconColor) {
64
+ iconProps.color = options.iconColor
65
+ }
66
+ options.iconProps = isDef(options.iconProps) && isObj(options.iconProps) ? { ...options.iconProps, ...iconProps } : iconProps
67
+ }
68
+ }
69
+
46
70
  const show = (option: MessageOptions | string) => {
71
+ const messageOption = initMessageOptions(selector, scopeId)
47
72
  // 返回一个promise
48
73
  return new Promise<MessageResult>((resolve, reject) => {
49
- const options = deepMerge(defaultOptions, typeof option === 'string' ? { title: option } : option)
74
+ const rawOptions = isString(option) ? { title: option } : { ...option }
75
+ normalizeIconProps(rawOptions)
76
+ const options = deepMerge(defaultOptions, rawOptions)
50
77
  messageOption.value = deepMerge(options, {
51
78
  show: true,
52
79
  success: (res: MessageResult) => {
@@ -69,9 +96,8 @@ export function useMessage(selector: string = ''): Message {
69
96
  const prompt = createMethod('prompt')
70
97
 
71
98
  const close = () => {
72
- if (messageOption.value !== None) {
73
- messageOption.value.show = false
74
- }
99
+ const messageOption = initMessageOptions(selector, scopeId)
100
+ messageOption.value.show = false
75
101
  }
76
102
  return {
77
103
  show,