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,456 @@
1
+ <template>
2
+ <view :class="rootClass" :style="rootStyle">
3
+ <view v-if="label" class="oxy-select__label" :style="labelStyle">
4
+ <slot name="label">{{ label }}</slot>
5
+ </view>
6
+ <view class="oxy-select__box">
7
+ <view :class="['oxy-select__wrapper', { 'is-disabled': disabled, 'is-readonly': readonly, 'is-focus': showSelector }]">
8
+ <view class="oxy-select__input-box" @click="toggleSelector">
9
+ <view class="oxy-select__tags" v-if="multiple && currentList.length > 0">
10
+ <view class="oxy-select__tags-item" v-for="item in displayTags" :key="item[valueKey]">
11
+ <span class="oxy-select__tags-item-text">{{ formatItemName(item) }}</span>
12
+ <view v-if="!disabled && !readonly" @click.stop="delItem(item)">
13
+ <oxy-icon custom-class="oxy-select__icon-error" name="close" />
14
+ </view>
15
+ </view>
16
+ <view v-if="currentList.length > collapseTagsNum && collapseTags" class="oxy-select__tags-item">
17
+ <span class="oxy-select__tags-item-text">+{{ currentList.length - collapseTagsNum }}</span>
18
+ </view>
19
+ <input
20
+ v-if="filterable && !disabled && !readonly"
21
+ @input="inputChange"
22
+ class="oxy-select__input-text oxy-select__input-filter"
23
+ type="text"
24
+ :placeholder="currentList.length === 0 ? typePlaceholder : ''"
25
+ v-model="filterInput"
26
+ />
27
+ </view>
28
+ <view v-else-if="current && current.length > 0 && !showSelector" class="oxy-select__input-text">
29
+ {{ current }}
30
+ </view>
31
+ <input
32
+ v-else-if="filterable && showSelector"
33
+ :focus="isFocus"
34
+ @input="inputChange"
35
+ :disabled="disabled"
36
+ :readonly="readonly"
37
+ class="oxy-select__input-text oxy-select__input-selector"
38
+ type="text"
39
+ :placeholder="placeholderOld || typePlaceholder"
40
+ v-model="filterInput"
41
+ />
42
+ <view v-else-if="!disabled && !readonly" class="oxy-select__input-text oxy-select__input-placeholder">{{ typePlaceholder }}</view>
43
+ <oxy-icon
44
+ v-if="(current.length > 0 && clear && !disabled && !readonly) || (currentArr.length > 0 && clear && !disabled && !readonly)"
45
+ custom-class="oxy-select__icon oxy-select__icon-clear"
46
+ name="close-circle-filled"
47
+ @click.stop="clearVal"
48
+ />
49
+ <oxy-icon
50
+ :custom-class="`oxy-select__icon oxy-select__icon-arrow ${showSelector ? 'is-open' : ''}`"
51
+ v-else-if="!disabled && !readonly"
52
+ name="arrow-down"
53
+ />
54
+ </view>
55
+ <oxy-transition :show="showSelector" name="fade" :duration="duration" :lazy-render="false">
56
+ <view class="oxy-select--mask" @click="toggleSelector" />
57
+ <view class="oxy-select__selector" :class="isDown ? 'oxy-select__selector__down' : 'oxy-select__selector__upwards'">
58
+ <view class="oxy-select__selector-arrow"></view>
59
+ <scroll-view :scroll-y="true" class="oxy-select__selector-scroll">
60
+ <view v-if="loading" class="oxy-select__loading">
61
+ <oxy-icon name="refresh" custom-class="oxy-select__loading-icon" />
62
+ <text>{{ loadingText }}</text>
63
+ </view>
64
+ <template v-else>
65
+ <view class="oxy-select__selector-empty" v-if="filterMixinDatacomResData.length === 0">
66
+ <span>{{ emptyTips }}</span>
67
+ </view>
68
+ <view
69
+ v-else
70
+ :class="[
71
+ 'oxy-select__selector-item',
72
+ { 'oxy-select_selector-item_active': multiple ? currentArr.includes(item[valueKey]) : modelValue === item[valueKey] }
73
+ ]"
74
+ v-for="(item, index) in filterMixinDatacomResData"
75
+ :key="index"
76
+ @click="change(item)"
77
+ >
78
+ <span :class="{ 'oxy-select__selector__disabled': item.disabled }">{{ formatItemName(item) }}</span>
79
+ <oxy-icon v-if="multiple && currentArr.includes(item[valueKey])" name="check" />
80
+ </view>
81
+ </template>
82
+ </scroll-view>
83
+ </view>
84
+ </oxy-transition>
85
+ </view>
86
+ </view>
87
+ </view>
88
+ </template>
89
+ <script lang="ts">
90
+ export default {
91
+ name: 'oxy-select',
92
+ options: {
93
+ addGlobalClass: true,
94
+ virtualHost: true,
95
+ styleIsolation: 'shared'
96
+ }
97
+ }
98
+ </script>
99
+
100
+ <script lang="ts" setup>
101
+ import { getCurrentInstance, ref, watch, computed } from 'vue'
102
+ import { objToStyle } from '../common/util'
103
+ import { useWindowResize, type WindowResizeResult } from '../composables/useWindowResize'
104
+ import { selectProps, type SelectProps } from './types'
105
+ import OxyTransition from '../oxy-transition/oxy-transition.vue'
106
+
107
+ type SelectOption = Record<string, any>
108
+ type SelectModelValue = SelectProps['modelValue']
109
+
110
+ const props = defineProps(selectProps)
111
+ const emit = defineEmits(['inputChange', 'input', 'change', 'update:modelValue'])
112
+
113
+ const instance = getCurrentInstance() as any
114
+ const showSelector = ref<boolean>(false)
115
+ const current = ref<string | SelectOption[]>('')
116
+ const mixinDatacomResData = ref<SelectOption[]>([])
117
+ const placeholderOld = ref<string>('')
118
+ const currentArr = ref<Array<string | number | boolean>>([])
119
+ const filterInput = ref<string>('')
120
+ const isFocus = ref<boolean>(false)
121
+ const windowHeight = ref<number>(0)
122
+ const isDown = ref<boolean>(true)
123
+ const rootStyle = ref('')
124
+ const duration = ref<number>(200)
125
+ let overlayTimer: ReturnType<typeof setTimeout> | null
126
+
127
+ const syncWindowHeight = (res?: WindowResizeResult) => {
128
+ const resizeHeight = Number(res?.size?.windowHeight ?? res?.windowHeight)
129
+ const systemHeight = uni.getSystemInfoSync().windowHeight
130
+ windowHeight.value = Number.isFinite(resizeHeight) && resizeHeight > 0 ? resizeHeight : systemHeight
131
+ }
132
+
133
+ const handleWindowResize = (res?: WindowResizeResult) => {
134
+ syncWindowHeight(res)
135
+ if (showSelector.value) {
136
+ void getIsDown()
137
+ }
138
+ }
139
+
140
+ useWindowResize(handleWindowResize, { immediate: true })
141
+
142
+ const rootClass = computed(() => {
143
+ return `oxy-select ${props.noBorder ? 'is-no-border' : ''} ${props.customClass}`
144
+ })
145
+
146
+ const labelStyle = computed(() => {
147
+ const labelStyle: Record<string, any> = {}
148
+ if (props.labelWidth) {
149
+ labelStyle['min-width'] = props.labelWidth
150
+ labelStyle['max-width'] = props.labelWidth
151
+ }
152
+ return objToStyle(labelStyle)
153
+ })
154
+
155
+ const currentList = computed(() => {
156
+ if (props.multiple && Array.isArray(current.value)) {
157
+ return current.value
158
+ }
159
+ return []
160
+ })
161
+
162
+ const displayTags = computed(() => {
163
+ if (props.collapseTags) {
164
+ return currentList.value.slice(0, props.collapseTagsNum)
165
+ }
166
+ return currentList.value
167
+ })
168
+
169
+ const filterMixinDatacomResData = computed(() => {
170
+ if (props.filterable && filterInput.value) {
171
+ return mixinDatacomResData.value.filter((e) => e[props.labelKey].includes(filterInput.value))
172
+ } else {
173
+ return mixinDatacomResData.value
174
+ }
175
+ })
176
+
177
+ const typePlaceholder = computed(() => {
178
+ return props.placeholder
179
+ })
180
+
181
+ const valueCom = computed(() => {
182
+ return props.modelValue
183
+ })
184
+
185
+ watch(
186
+ () => props.columns,
187
+ (newValue, oldValue) => {
188
+ if (Array.isArray(newValue) && oldValue !== newValue) {
189
+ mixinDatacomResData.value = newValue || []
190
+ }
191
+ },
192
+ {
193
+ immediate: true
194
+ }
195
+ )
196
+
197
+ watch(
198
+ () => valueCom.value,
199
+ () => {
200
+ initDefVal()
201
+ },
202
+ {
203
+ deep: true,
204
+ immediate: true
205
+ }
206
+ )
207
+
208
+ watch(
209
+ () => mixinDatacomResData.value,
210
+ (val) => {
211
+ if (val.length) {
212
+ initDefVal()
213
+ }
214
+ },
215
+ {
216
+ immediate: true
217
+ }
218
+ )
219
+
220
+ watch(
221
+ () => showSelector.value,
222
+ (val) => {
223
+ if (overlayTimer) {
224
+ clearTimeout(overlayTimer)
225
+ }
226
+ if (val) {
227
+ rootStyle.value = `z-index: 1;${props.customStyle}`
228
+ } else {
229
+ overlayTimer = setTimeout(() => {
230
+ rootStyle.value = `${props.customStyle}`
231
+ }, duration.value)
232
+ }
233
+ },
234
+ {
235
+ immediate: true
236
+ }
237
+ )
238
+
239
+ function getIsDown() {
240
+ return new Promise((resolve) => {
241
+ const query = uni.createSelectorQuery().in(instance)
242
+ query
243
+ .select('.oxy-select__box')
244
+ .boundingClientRect((data) => {
245
+ const rect = data as UniApp.NodeInfo
246
+ if (rect) {
247
+ const bottomSpace = windowHeight.value - (rect.bottom || 0)
248
+ const topSpace = rect.top || 0
249
+ const threshold = 280 // max-height 240 + padding/arrow space
250
+
251
+ // 如果下方空间不足,且上方空间比下方空间大,则向上弹出
252
+ if (bottomSpace < threshold && topSpace > bottomSpace) {
253
+ isDown.value = false
254
+ } else {
255
+ isDown.value = true
256
+ }
257
+ }
258
+ resolve(isDown.value)
259
+ })
260
+ .exec()
261
+ })
262
+ }
263
+
264
+ function initDefVal() {
265
+ let defValue: SelectModelValue | '' = ''
266
+ if ((valueCom.value || valueCom.value === 0) && !isDisabled(valueCom.value)) {
267
+ defValue = valueCom.value as SelectModelValue
268
+ } else {
269
+ let strogeValue: SelectModelValue | '' | undefined
270
+ if (strogeValue || strogeValue === 0) {
271
+ defValue = strogeValue
272
+ } else {
273
+ let defItem = ''
274
+ if (props.defItem > 0 && props.defItem <= mixinDatacomResData.value.length) {
275
+ defItem = mixinDatacomResData.value[props.defItem - 1][props.valueKey] as string
276
+ }
277
+ defValue = defItem as SelectModelValue
278
+ }
279
+ if (defValue || defValue === 0) {
280
+ handleEmit(defValue)
281
+ }
282
+ }
283
+ if (props.multiple) {
284
+ const _mixinDatacomResData = mixinDatacomResData.value || []
285
+ const defArray = Array.isArray(defValue) ? defValue : []
286
+ const list: SelectOption[] = defArray.map((item) => {
287
+ const found = _mixinDatacomResData.find((e) => {
288
+ return e[props.valueKey] == item
289
+ })
290
+ return {
291
+ ...found
292
+ }
293
+ })
294
+ current.value = list
295
+ currentArr.value = list.map((e) => e[props.valueKey] as string | number | boolean)
296
+ if (defArray.length < 1) {
297
+ currentArr.value = []
298
+ }
299
+ } else {
300
+ const def = mixinDatacomResData.value.find((item) => item[props.valueKey] === defValue)
301
+ current.value = def ? formatItemName(def) : ''
302
+ }
303
+ }
304
+
305
+ /**
306
+ * @param {[String, Number]} value
307
+ * 判断用户给的 value 是否同时为禁用状态
308
+ */
309
+ function isDisabled(value: any) {
310
+ let isDisabled = false
311
+
312
+ mixinDatacomResData.value.forEach((item) => {
313
+ if (item[props.valueKey] === value) {
314
+ isDisabled = item.disabled
315
+ }
316
+ })
317
+ return isDisabled
318
+ }
319
+
320
+ function inputChange(e: any) {
321
+ emit('inputChange', e.detail.value)
322
+ }
323
+
324
+ function clearVal() {
325
+ if (props.disabled || props.readonly) {
326
+ return
327
+ }
328
+ if (props.multiple) {
329
+ current.value = []
330
+ currentArr.value = []
331
+ handleEmit([])
332
+ } else {
333
+ current.value = ''
334
+ currentArr.value = []
335
+ handleEmit('')
336
+ }
337
+ placeholderOld.value = props.placeholder
338
+ filterInput.value = ''
339
+ }
340
+
341
+ function change(item: any) {
342
+ if (!item.disabled) {
343
+ if (props.multiple) {
344
+ if (!Array.isArray(current.value)) {
345
+ current.value = []
346
+ } else {
347
+ current.value = [...current.value]
348
+ }
349
+ const currentList = current.value as SelectOption[]
350
+ const value = item[props.valueKey] as string | number | boolean
351
+ if (!currentArr.value) {
352
+ currentArr.value = []
353
+ }
354
+ const index = currentArr.value.indexOf(value)
355
+ if (index !== -1) {
356
+ currentList.splice(index, 1)
357
+ currentArr.value.splice(index, 1)
358
+ handleEmit(currentList)
359
+ } else {
360
+ currentList.push(item)
361
+ currentArr.value.push(value)
362
+ handleEmit(currentList)
363
+ }
364
+ filterInput.value = ''
365
+ } else {
366
+ showSelector.value = false
367
+ current.value = formatItemName(item)
368
+ if (props.filterable) {
369
+ filterInput.value = item[props.labelKey]
370
+ }
371
+ handleEmit(item[props.valueKey])
372
+ }
373
+ }
374
+ }
375
+ function delItem(item: any) {
376
+ if (props.disabled || props.readonly) {
377
+ return
378
+ }
379
+ if (currentArr.value.includes(item[props.valueKey])) {
380
+ if (!Array.isArray(current.value)) {
381
+ return
382
+ }
383
+ const currentList = current.value as SelectOption[]
384
+ const index = currentList.findIndex((e) => {
385
+ return e[props.valueKey] == item[props.valueKey]
386
+ })
387
+ currentList.splice(index, 1)
388
+ currentArr.value.splice(index, 1)
389
+ handleEmit(currentList)
390
+ }
391
+ }
392
+ function handleEmit(val: any) {
393
+ if (props.multiple) {
394
+ emit('input', currentArr.value)
395
+ emit('update:modelValue', currentArr.value)
396
+ const _currentArr = mixinDatacomResData.value.filter((item) => currentArr.value.includes(item[props.valueKey]))
397
+ emit('change', _currentArr)
398
+ } else {
399
+ emit('input', val)
400
+ emit('update:modelValue', val)
401
+ const _current = mixinDatacomResData.value.find((item) => val == item[props.valueKey])
402
+ emit('change', _current)
403
+ }
404
+ }
405
+ async function toggleSelector() {
406
+ if (props.disabled || props.readonly) {
407
+ return
408
+ }
409
+ const nextShow = !showSelector.value
410
+ if (nextShow) {
411
+ await getIsDown()
412
+ }
413
+ showSelector.value = nextShow
414
+ isFocus.value = nextShow
415
+ if (props.filterable && current.value && showSelector.value) {
416
+ if (!props.multiple) {
417
+ if (typeof current.value === 'string') {
418
+ placeholderOld.value = current.value
419
+ }
420
+ }
421
+ } else if (props.filterable && !current.value && !showSelector.value) {
422
+ if (placeholderOld.value != props.placeholder) {
423
+ if (!props.multiple) {
424
+ current.value = placeholderOld.value
425
+ }
426
+ }
427
+ }
428
+ filterInput.value = ''
429
+ }
430
+
431
+ function formatItemName(item: any) {
432
+ if (!item) {
433
+ return ''
434
+ }
435
+ const label = item[props.labelKey]
436
+
437
+ if (props.format) {
438
+ // 格式化输出
439
+ let str = props.format
440
+ for (const key in item) {
441
+ str = str.replace(new RegExp(`{${key}}`, 'g'), item[key])
442
+ }
443
+ return str
444
+ }
445
+
446
+ return label !== undefined && label !== null ? String(label) : ''
447
+ }
448
+
449
+ // 获取当前加载的数据
450
+ function getLoadData() {
451
+ return mixinDatacomResData.value
452
+ }
453
+ </script>
454
+ <style lang="scss" scoped>
455
+ @import './index.scss';
456
+ </style>
@@ -0,0 +1,83 @@
1
+ import type { ExtractPropTypes } from 'vue'
2
+ import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
3
+
4
+ export const selectProps = {
5
+ ...baseProps,
6
+ /**
7
+ * 选中项
8
+ */
9
+ modelValue: makeRequiredProp([String, Number, Array]),
10
+ /**
11
+ * 是否多选
12
+ */
13
+ multiple: makeBooleanProp(false),
14
+ /**
15
+ * 是否禁用
16
+ */
17
+ disabled: makeBooleanProp(false),
18
+ /** 只读 */
19
+ readonly: makeBooleanProp(false),
20
+ /**
21
+ * 多作为 key 唯一标识的键名
22
+ */
23
+ labelKey: makeStringProp('label'),
24
+ /**
25
+ * 多作为 value 唯一标识的键名
26
+ */
27
+ valueKey: makeStringProp('value'),
28
+ /**
29
+ * 是否开启搜索
30
+ */
31
+ filterable: makeBooleanProp(false),
32
+ /**
33
+ * 是否折叠显示标签
34
+ */
35
+ collapseTags: makeBooleanProp(false),
36
+ /**
37
+ * 超过多少个标签才折叠
38
+ */
39
+ collapseTagsNum: makeNumberProp(1),
40
+ /**
41
+ * 选择器数据
42
+ */
43
+ columns: makeArrayProp<Record<string, any>>(),
44
+ /**
45
+ * 左侧标题
46
+ */
47
+ label: makeStringProp(''),
48
+ /** 设置左侧标题宽度 */
49
+ labelWidth: makeStringProp(''),
50
+ /** 选择器的值靠右展示 */
51
+ alignRight: makeBooleanProp(false),
52
+ /**
53
+ * 输入框的提示文字
54
+ */
55
+ placeholder: makeStringProp('请选择'),
56
+ /**
57
+ * 无选项提示
58
+ */
59
+ emptyTips: makeStringProp('无选项'),
60
+ /**
61
+ * 是否可清除
62
+ */
63
+ clear: makeBooleanProp(true),
64
+ /**
65
+ * 是否加载中
66
+ */
67
+ loading: makeBooleanProp(false),
68
+ /**
69
+ * 加载中文字
70
+ */
71
+ loadingText: makeStringProp('加载中...'),
72
+ /**
73
+ * 格式化输出
74
+ */
75
+ format: makeStringProp(''),
76
+ defItem: makeNumberProp(0),
77
+ /**
78
+ * 是否隐藏边框
79
+ */
80
+ noBorder: makeBooleanProp(false)
81
+ }
82
+
83
+ export type SelectProps = ExtractPropTypes<typeof selectProps>
@@ -73,19 +73,19 @@
73
73
  }
74
74
 
75
75
  @include edeep(header) {
76
- height: 72px;
77
- line-height: 72px;
76
+ height: 144rpx;
77
+ line-height: 144rpx;
78
78
  }
79
79
  @include e(wrapper) {
80
- padding: 0 10px;
80
+ padding: 0 20rpx;
81
81
  position: relative;
82
- max-height: 356px;
82
+ max-height: 712rpx;
83
83
  box-sizing: border-box;
84
84
  overflow: auto;
85
85
 
86
86
  @include when(filterable) {
87
- height: 314px;
88
- max-height: 314px;
87
+ height: 628rpx;
88
+ max-height: 628rpx;
89
89
  }
90
90
 
91
91
  @include when(loading) {
@@ -97,6 +97,6 @@
97
97
  }
98
98
 
99
99
  @include e(footer) {
100
- padding: 24px 15px;
100
+ padding: 48rpx 30rpx;
101
101
  }
102
102
  }
@@ -40,6 +40,7 @@
40
40
  :title="title || translate('title')"
41
41
  :close-on-click-modal="closeOnClickModal"
42
42
  :z-index="zIndex"
43
+ :max-width="popupMaxWidth"
43
44
  :safe-area-inset-bottom="safeAreaInsetBottom"
44
45
  :root-portal="rootPortal"
45
46
  @close="close"
@@ -320,6 +321,9 @@ function close() {
320
321
 
321
322
  function open() {
322
323
  if (props.disabled || props.readonly) return
324
+ if (isFunction(props.beforeOpen) && !props.beforeOpen()) {
325
+ return
326
+ }
323
327
  selectList.value = valueFormat(props.modelValue)
324
328
  pickerShow.value = true
325
329
  isConfirm.value = false
@@ -72,6 +72,8 @@ export const selectPickerProps = {
72
72
  beforeConfirm: Function as PropType<SelectPickerBeforeConfirm>,
73
73
  /** 弹窗层级 */
74
74
  zIndex: makeNumberProp(15),
75
+ /** 弹层最大宽度,支持 `rpx`、`px`、`%` 等单位;`%` 在弹层打开时按屏幕宽度换算为 `rpx` */
76
+ popupMaxWidth: makeStringProp('1200rpx'),
75
77
  /** 弹出面板是否设置底部安全距离(iphone X 类型的机型) */
76
78
  safeAreaInsetBottom: makeBooleanProp(true),
77
79
  /** 可搜索(目前只支持本地搜索) */
@@ -105,7 +107,11 @@ export const selectPickerProps = {
105
107
  /**
106
108
  * 必填标记位置,可选值:before、after
107
109
  */
108
- markerSide: makeStringProp<'before' | 'after'>('before')
110
+ markerSide: makeStringProp<'before' | 'after'>('before'),
111
+ /**
112
+ * 打开pop之前的校验
113
+ */
114
+ beforeOpen: Function as PropType<() => boolean>
109
115
  }
110
116
  export type SelectPickerProps = ExtractPropTypes<typeof selectPickerProps>
111
117
 
@@ -91,7 +91,7 @@
91
91
 
92
92
  @include edeep(icon) {
93
93
  font-size: $-sidebar-icon-size;
94
- margin-right: 2px;
94
+ margin-right: 4rpx;
95
95
  }
96
96
 
97
97
  }
@@ -69,7 +69,7 @@ export default {
69
69
  </script>
70
70
  <script lang="ts" setup>
71
71
  import { computed, getCurrentInstance, onBeforeMount, onMounted, reactive, ref, watch, type CSSProperties } from 'vue'
72
- import { addUnit, getRect, isDef, objToStyle, uuid } from '../common/util'
72
+ import { getRect, isDef, objToStyle, unitConvert, unitConvertWithDefault, withDefaultUnit, uuid } from '../common/util'
73
73
  import { signatureProps, type SignatureExpose, type SignatureResult, type Point, type Line } from './types'
74
74
  import { useTranslate } from '../composables/useTranslate'
75
75
  // #ifdef MP-WEIXIN
@@ -147,11 +147,11 @@ watch(
147
147
  const canvasStyle = computed(() => {
148
148
  const style: CSSProperties = {}
149
149
  if (isDef(props.width)) {
150
- style.width = addUnit(props.width)
150
+ style.width = unitConvert(withDefaultUnit(props.width, 'rpx'), 0, { output: 'px' })
151
151
  }
152
152
 
153
153
  if (isDef(props.height)) {
154
- style.height = addUnit(props.height)
154
+ style.height = unitConvert(withDefaultUnit(props.height, 'rpx'), 0, { output: 'px' })
155
155
  }
156
156
 
157
157
  return `${objToStyle(style)}`
@@ -159,6 +159,12 @@ const canvasStyle = computed(() => {
159
159
 
160
160
  const disableScroll = computed(() => props.disableScroll)
161
161
  const enableHistory = computed(() => props.enableHistory)
162
+ const resolveStrokeWidth = (value: number | string): number => {
163
+ return unitConvertWithDefault(value, { defaultUnit: 'rpx' })
164
+ }
165
+ const lineWidthInPx = computed(() => resolveStrokeWidth(props.lineWidth))
166
+ const minWidthInPx = computed(() => resolveStrokeWidth(props.minWidth))
167
+ const maxWidthInPx = computed(() => resolveStrokeWidth(props.maxWidth))
162
168
 
163
169
  const lines = ref<Line[]>([]) // 保存所有线条
164
170
  const redoLines = ref<Line[]>([]) // 保存撤销的线条
@@ -167,22 +173,24 @@ const currentStep = ref(0) // 当前步骤
167
173
 
168
174
  // 添加计算笔画宽度的方法
169
175
  function calculateLineWidth(speed: number): number {
170
- if (!props.pressure) return props.lineWidth
176
+ if (!props.pressure) return lineWidthInPx.value
171
177
 
172
178
  const minSpeed = props.minSpeed || 1.5
179
+ const minWidth = Math.min(minWidthInPx.value, maxWidthInPx.value)
180
+ const maxWidth = Math.max(minWidthInPx.value, maxWidthInPx.value)
173
181
  const limitedSpeed = Math.min(minSpeed * 10, Math.max(minSpeed, speed))
174
- const addWidth = ((props.maxWidth - props.minWidth) * (limitedSpeed - minSpeed)) / minSpeed
175
- const lineWidth = Math.max(props.maxWidth - addWidth, props.minWidth)
176
- return Math.min(lineWidth, props.maxWidth)
182
+ const addWidth = ((maxWidth - minWidth) * (limitedSpeed - minSpeed)) / minSpeed
183
+ const lineWidth = Math.max(maxWidth - addWidth, minWidth)
184
+ return Math.min(lineWidth, maxWidth)
177
185
  }
178
186
 
179
187
  /* 获取默认笔画宽度 */
180
188
  const getDefaultLineWidth = () => {
181
189
  if (props.pressure) {
182
190
  // 在压感模式下,使用最大和最小宽度的平均值作为默认值
183
- return (props.maxWidth + props.minWidth) / 2
191
+ return (maxWidthInPx.value + minWidthInPx.value) / 2
184
192
  }
185
- return props.lineWidth
193
+ return lineWidthInPx.value
186
194
  }
187
195
 
188
196
  /* 开始画线 */
@@ -469,7 +477,7 @@ function drawSmoothLine(prePoint: Point, point: Point) {
469
477
  }
470
478
 
471
479
  // 计算线宽
472
- const lineWidth = point.lineWidth || props.lineWidth
480
+ const lineWidth = point.lineWidth || lineWidthInPx.value
473
481
 
474
482
  // 绘制贝塞尔曲线
475
483
  if (typeof prePoint.lastX1 === 'number') {