oxy-uni-ui 1.0.1

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 (355) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -0
  3. package/attributes.json +1 -0
  4. package/components/common/AbortablePromise.ts +28 -0
  5. package/components/common/abstracts/_config.scss +7 -0
  6. package/components/common/abstracts/_function.scss +89 -0
  7. package/components/common/abstracts/_mixin.scss +385 -0
  8. package/components/common/abstracts/variable.scss +974 -0
  9. package/components/common/base64.ts +29 -0
  10. package/components/common/canvasHelper.ts +49 -0
  11. package/components/common/clickoutside.ts +25 -0
  12. package/components/common/event.ts +8 -0
  13. package/components/common/interceptor.ts +43 -0
  14. package/components/common/props.ts +51 -0
  15. package/components/common/util.ts +778 -0
  16. package/components/composables/index.ts +11 -0
  17. package/components/composables/useCell.ts +13 -0
  18. package/components/composables/useChildren.ts +113 -0
  19. package/components/composables/useCountDown.ts +138 -0
  20. package/components/composables/useLockScroll.ts +37 -0
  21. package/components/composables/useParent.ts +41 -0
  22. package/components/composables/usePopover.ts +176 -0
  23. package/components/composables/useQueue.ts +52 -0
  24. package/components/composables/useRaf.ts +37 -0
  25. package/components/composables/useTouch.ts +43 -0
  26. package/components/composables/useTranslate.ts +12 -0
  27. package/components/composables/useUpload.ts +364 -0
  28. package/components/oxy-action-sheet/index.scss +204 -0
  29. package/components/oxy-action-sheet/oxy-action-sheet.vue +155 -0
  30. package/components/oxy-action-sheet/types.ts +118 -0
  31. package/components/oxy-backtop/index.scss +25 -0
  32. package/components/oxy-backtop/oxy-backtop.vue +45 -0
  33. package/components/oxy-backtop/types.ts +37 -0
  34. package/components/oxy-badge/index.scss +63 -0
  35. package/components/oxy-badge/oxy-badge.vue +61 -0
  36. package/components/oxy-badge/types.ts +41 -0
  37. package/components/oxy-button/index.scss +336 -0
  38. package/components/oxy-button/oxy-button.vue +195 -0
  39. package/components/oxy-button/types.ts +133 -0
  40. package/components/oxy-calendar/index.scss +158 -0
  41. package/components/oxy-calendar/oxy-calendar.vue +451 -0
  42. package/components/oxy-calendar/types.ts +217 -0
  43. package/components/oxy-calendar-view/index.scss +0 -0
  44. package/components/oxy-calendar-view/month/index.scss +162 -0
  45. package/components/oxy-calendar-view/month/month.vue +389 -0
  46. package/components/oxy-calendar-view/month/types.ts +20 -0
  47. package/components/oxy-calendar-view/monthPanel/index.scss +89 -0
  48. package/components/oxy-calendar-view/monthPanel/month-panel.vue +374 -0
  49. package/components/oxy-calendar-view/monthPanel/types.ts +48 -0
  50. package/components/oxy-calendar-view/oxy-calendar-view.vue +111 -0
  51. package/components/oxy-calendar-view/types.ts +109 -0
  52. package/components/oxy-calendar-view/utils.ts +429 -0
  53. package/components/oxy-calendar-view/year/index.scss +153 -0
  54. package/components/oxy-calendar-view/year/types.ts +20 -0
  55. package/components/oxy-calendar-view/year/year.vue +202 -0
  56. package/components/oxy-calendar-view/yearPanel/index.scss +24 -0
  57. package/components/oxy-calendar-view/yearPanel/types.ts +38 -0
  58. package/components/oxy-calendar-view/yearPanel/year-panel.vue +135 -0
  59. package/components/oxy-card/index.scss +71 -0
  60. package/components/oxy-card/oxy-card.vue +37 -0
  61. package/components/oxy-card/types.ts +30 -0
  62. package/components/oxy-cell/index.scss +206 -0
  63. package/components/oxy-cell/oxy-cell.vue +140 -0
  64. package/components/oxy-cell/types.ts +111 -0
  65. package/components/oxy-cell-group/index.scss +56 -0
  66. package/components/oxy-cell-group/oxy-cell-group.vue +45 -0
  67. package/components/oxy-cell-group/types.ts +32 -0
  68. package/components/oxy-checkbox/index.scss +285 -0
  69. package/components/oxy-checkbox/oxy-checkbox.vue +177 -0
  70. package/components/oxy-checkbox/types.ts +68 -0
  71. package/components/oxy-checkbox-group/index.scss +20 -0
  72. package/components/oxy-checkbox-group/oxy-checkbox-group.vue +100 -0
  73. package/components/oxy-checkbox-group/types.ts +59 -0
  74. package/components/oxy-circle/index.scss +18 -0
  75. package/components/oxy-circle/oxy-circle.vue +296 -0
  76. package/components/oxy-circle/types.ts +54 -0
  77. package/components/oxy-col/index.scss +19 -0
  78. package/components/oxy-col/oxy-col.vue +49 -0
  79. package/components/oxy-col/types.ts +15 -0
  80. package/components/oxy-col-picker/index.scss +168 -0
  81. package/components/oxy-col-picker/oxy-col-picker.vue +498 -0
  82. package/components/oxy-col-picker/types.ts +166 -0
  83. package/components/oxy-collapse/index.scss +55 -0
  84. package/components/oxy-collapse/oxy-collapse.vue +151 -0
  85. package/components/oxy-collapse/types.ts +58 -0
  86. package/components/oxy-collapse-item/index.scss +90 -0
  87. package/components/oxy-collapse-item/oxy-collapse-item.vue +171 -0
  88. package/components/oxy-collapse-item/types.ts +48 -0
  89. package/components/oxy-config-provider/oxy-config-provider.vue +73 -0
  90. package/components/oxy-config-provider/types.ts +1052 -0
  91. package/components/oxy-count-down/index.scss +15 -0
  92. package/components/oxy-count-down/oxy-count-down.vue +60 -0
  93. package/components/oxy-count-down/types.ts +41 -0
  94. package/components/oxy-count-down/utils.ts +52 -0
  95. package/components/oxy-count-to/index.scss +7 -0
  96. package/components/oxy-count-to/oxy-count-to.vue +125 -0
  97. package/components/oxy-count-to/types.ts +117 -0
  98. package/components/oxy-curtain/index.scss +85 -0
  99. package/components/oxy-curtain/oxy-curtain.vue +172 -0
  100. package/components/oxy-curtain/types.ts +73 -0
  101. package/components/oxy-datetime-picker/index.scss +164 -0
  102. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +801 -0
  103. package/components/oxy-datetime-picker/types.ts +231 -0
  104. package/components/oxy-datetime-picker-view/oxy-datetime-picker-view.vue +499 -0
  105. package/components/oxy-datetime-picker-view/types.ts +120 -0
  106. package/components/oxy-datetime-picker-view/util.ts +30 -0
  107. package/components/oxy-design-uni/oxy-design-uni.vue +5 -0
  108. package/components/oxy-divider/index.scss +100 -0
  109. package/components/oxy-divider/oxy-divider.vue +52 -0
  110. package/components/oxy-divider/types.ts +35 -0
  111. package/components/oxy-drop-menu/index.scss +86 -0
  112. package/components/oxy-drop-menu/oxy-drop-menu.vue +166 -0
  113. package/components/oxy-drop-menu/types.ts +38 -0
  114. package/components/oxy-drop-menu-item/index.scss +66 -0
  115. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +221 -0
  116. package/components/oxy-drop-menu-item/types.ts +94 -0
  117. package/components/oxy-fab/index.scss +116 -0
  118. package/components/oxy-fab/oxy-fab.vue +276 -0
  119. package/components/oxy-fab/types.ts +66 -0
  120. package/components/oxy-floating-panel/index.scss +64 -0
  121. package/components/oxy-floating-panel/oxy-floating-panel.vue +140 -0
  122. package/components/oxy-floating-panel/type.ts +32 -0
  123. package/components/oxy-form/oxy-form.vue +207 -0
  124. package/components/oxy-form/types.ts +76 -0
  125. package/components/oxy-form-item/index.scss +18 -0
  126. package/components/oxy-form-item/oxy-form-item.vue +56 -0
  127. package/components/oxy-form-item/types.ts +16 -0
  128. package/components/oxy-gap/index.scss +9 -0
  129. package/components/oxy-gap/oxy-gap.vue +36 -0
  130. package/components/oxy-gap/types.ts +17 -0
  131. package/components/oxy-grid/index.scss +9 -0
  132. package/components/oxy-grid/oxy-grid.vue +106 -0
  133. package/components/oxy-grid/types.ts +50 -0
  134. package/components/oxy-grid-item/index.scss +148 -0
  135. package/components/oxy-grid-item/oxy-grid-item.vue +176 -0
  136. package/components/oxy-grid-item/types.ts +77 -0
  137. package/components/oxy-icon/index.scss +1230 -0
  138. package/components/oxy-icon/oxy-icon.vue +53 -0
  139. package/components/oxy-icon/oxy-icons.ttf +0 -0
  140. package/components/oxy-icon/types.ts +21 -0
  141. package/components/oxy-img/index.scss +19 -0
  142. package/components/oxy-img/oxy-img.vue +81 -0
  143. package/components/oxy-img/types.ts +61 -0
  144. package/components/oxy-img-cropper/index.scss +231 -0
  145. package/components/oxy-img-cropper/oxy-img-cropper.vue +664 -0
  146. package/components/oxy-img-cropper/types.ts +76 -0
  147. package/components/oxy-index-anchor/index.scss +35 -0
  148. package/components/oxy-index-anchor/oxy-index-anchor.vue +55 -0
  149. package/components/oxy-index-anchor/type.ts +9 -0
  150. package/components/oxy-index-bar/index.scss +39 -0
  151. package/components/oxy-index-bar/oxy-index-bar.vue +156 -0
  152. package/components/oxy-index-bar/type.ts +23 -0
  153. package/components/oxy-input/index.scss +323 -0
  154. package/components/oxy-input/oxy-input.vue +300 -0
  155. package/components/oxy-input/placeholder.scss +21 -0
  156. package/components/oxy-input/types.ts +189 -0
  157. package/components/oxy-input-number/index.scss +132 -0
  158. package/components/oxy-input-number/oxy-input-number.vue +464 -0
  159. package/components/oxy-input-number/types.ts +101 -0
  160. package/components/oxy-keyboard/constants.ts +81 -0
  161. package/components/oxy-keyboard/index.scss +102 -0
  162. package/components/oxy-keyboard/key/index.scss +79 -0
  163. package/components/oxy-keyboard/key/index.vue +76 -0
  164. package/components/oxy-keyboard/key/types.ts +11 -0
  165. package/components/oxy-keyboard/oxy-keyboard.vue +206 -0
  166. package/components/oxy-keyboard/types.ts +92 -0
  167. package/components/oxy-loading/index.scss +37 -0
  168. package/components/oxy-loading/oxy-loading.vue +90 -0
  169. package/components/oxy-loading/types.ts +22 -0
  170. package/components/oxy-loadmore/index.scss +39 -0
  171. package/components/oxy-loadmore/oxy-loadmore.vue +59 -0
  172. package/components/oxy-loadmore/types.ts +30 -0
  173. package/components/oxy-message-box/index.scss +108 -0
  174. package/components/oxy-message-box/index.ts +87 -0
  175. package/components/oxy-message-box/oxy-message-box.vue +291 -0
  176. package/components/oxy-message-box/types.ts +132 -0
  177. package/components/oxy-navbar/index.scss +93 -0
  178. package/components/oxy-navbar/oxy-navbar.vue +111 -0
  179. package/components/oxy-navbar/types.ts +52 -0
  180. package/components/oxy-navbar-capsule/index.scss +66 -0
  181. package/components/oxy-navbar-capsule/oxy-navbar-capsule.vue +35 -0
  182. package/components/oxy-navbar-capsule/types.ts +8 -0
  183. package/components/oxy-notice-bar/index.scss +68 -0
  184. package/components/oxy-notice-bar/oxy-notice-bar.vue +266 -0
  185. package/components/oxy-notice-bar/types.ts +67 -0
  186. package/components/oxy-notify/index.scss +34 -0
  187. package/components/oxy-notify/index.ts +61 -0
  188. package/components/oxy-notify/oxy-notify.vue +85 -0
  189. package/components/oxy-notify/types.ts +66 -0
  190. package/components/oxy-number-keyboard/index.scss +78 -0
  191. package/components/oxy-number-keyboard/key/index.scss +81 -0
  192. package/components/oxy-number-keyboard/key/index.vue +78 -0
  193. package/components/oxy-number-keyboard/key/types.ts +11 -0
  194. package/components/oxy-number-keyboard/oxy-number-keyboard.vue +151 -0
  195. package/components/oxy-number-keyboard/types.ts +83 -0
  196. package/components/oxy-overlay/index.scss +17 -0
  197. package/components/oxy-overlay/oxy-overlay.vue +47 -0
  198. package/components/oxy-overlay/types.ts +25 -0
  199. package/components/oxy-pagination/index.scss +57 -0
  200. package/components/oxy-pagination/oxy-pagination.vue +110 -0
  201. package/components/oxy-pagination/types.ts +41 -0
  202. package/components/oxy-password-input/index.scss +124 -0
  203. package/components/oxy-password-input/oxy-password-input.vue +49 -0
  204. package/components/oxy-password-input/types.ts +33 -0
  205. package/components/oxy-picker/index.scss +110 -0
  206. package/components/oxy-picker/oxy-picker.vue +412 -0
  207. package/components/oxy-picker/types.ts +189 -0
  208. package/components/oxy-picker-view/index.scss +92 -0
  209. package/components/oxy-picker-view/oxy-picker-view.vue +369 -0
  210. package/components/oxy-picker-view/types.ts +152 -0
  211. package/components/oxy-popover/index.scss +116 -0
  212. package/components/oxy-popover/oxy-popover.vue +180 -0
  213. package/components/oxy-popover/types.ts +69 -0
  214. package/components/oxy-popup/index.scss +84 -0
  215. package/components/oxy-popup/oxy-popup.vue +169 -0
  216. package/components/oxy-popup/types.ts +95 -0
  217. package/components/oxy-progress/index.scss +68 -0
  218. package/components/oxy-progress/oxy-progress.vue +197 -0
  219. package/components/oxy-progress/types.ts +35 -0
  220. package/components/oxy-radio/index.scss +301 -0
  221. package/components/oxy-radio/oxy-radio.vue +118 -0
  222. package/components/oxy-radio/types.ts +42 -0
  223. package/components/oxy-radio-group/index.scss +23 -0
  224. package/components/oxy-radio-group/oxy-radio-group.vue +51 -0
  225. package/components/oxy-radio-group/types.ts +39 -0
  226. package/components/oxy-rate/index.scss +25 -0
  227. package/components/oxy-rate/oxy-rate.vue +178 -0
  228. package/components/oxy-rate/types.ts +103 -0
  229. package/components/oxy-resize/index.scss +27 -0
  230. package/components/oxy-resize/oxy-resize.vue +144 -0
  231. package/components/oxy-resize/types.ts +6 -0
  232. package/components/oxy-root-portal/oxy-root-portal.vue +50 -0
  233. package/components/oxy-row/index.scss +10 -0
  234. package/components/oxy-row/oxy-row.vue +42 -0
  235. package/components/oxy-row/types.ts +16 -0
  236. package/components/oxy-search/index.scss +148 -0
  237. package/components/oxy-search/oxy-search.vue +187 -0
  238. package/components/oxy-search/types.ts +93 -0
  239. package/components/oxy-segmented/index.scss +101 -0
  240. package/components/oxy-segmented/oxy-segmented.vue +143 -0
  241. package/components/oxy-segmented/types.ts +71 -0
  242. package/components/oxy-select-picker/index.scss +102 -0
  243. package/components/oxy-select-picker/oxy-select-picker.vue +432 -0
  244. package/components/oxy-select-picker/types.ts +123 -0
  245. package/components/oxy-sidebar/index.scss +25 -0
  246. package/components/oxy-sidebar/oxy-sidebar.vue +63 -0
  247. package/components/oxy-sidebar/types.ts +38 -0
  248. package/components/oxy-sidebar-item/index.scss +97 -0
  249. package/components/oxy-sidebar-item/oxy-sidebar-item.vue +116 -0
  250. package/components/oxy-sidebar-item/types.ts +31 -0
  251. package/components/oxy-signature/index.scss +31 -0
  252. package/components/oxy-signature/oxy-signature.vue +630 -0
  253. package/components/oxy-signature/types.ts +108 -0
  254. package/components/oxy-skeleton/index.scss +96 -0
  255. package/components/oxy-skeleton/index.ts +1 -0
  256. package/components/oxy-skeleton/oxy-skeleton.vue +110 -0
  257. package/components/oxy-skeleton/types.ts +69 -0
  258. package/components/oxy-slider/index.scss +98 -0
  259. package/components/oxy-slider/oxy-slider.vue +356 -0
  260. package/components/oxy-slider/types.ts +138 -0
  261. package/components/oxy-sort-button/index.scss +89 -0
  262. package/components/oxy-sort-button/oxy-sort-button.vue +69 -0
  263. package/components/oxy-sort-button/types.ts +43 -0
  264. package/components/oxy-status-tip/images/collect.png +0 -0
  265. package/components/oxy-status-tip/images/content.png +0 -0
  266. package/components/oxy-status-tip/images/network.png +0 -0
  267. package/components/oxy-status-tip/images/search.png +0 -0
  268. package/components/oxy-status-tip/index.scss +37 -0
  269. package/components/oxy-status-tip/oxy-status-tip.vue +71 -0
  270. package/components/oxy-status-tip/types.ts +50 -0
  271. package/components/oxy-step/index.scss +235 -0
  272. package/components/oxy-step/oxy-step.vue +150 -0
  273. package/components/oxy-step/types.ts +33 -0
  274. package/components/oxy-steps/index.scss +10 -0
  275. package/components/oxy-steps/oxy-steps.vue +28 -0
  276. package/components/oxy-steps/types.ts +50 -0
  277. package/components/oxy-sticky/index.scss +9 -0
  278. package/components/oxy-sticky/oxy-sticky.vue +190 -0
  279. package/components/oxy-sticky/types.ts +13 -0
  280. package/components/oxy-sticky-box/index.scss +6 -0
  281. package/components/oxy-sticky-box/oxy-sticky-box.vue +155 -0
  282. package/components/oxy-sticky-box/types.ts +11 -0
  283. package/components/oxy-swipe-action/index.scss +22 -0
  284. package/components/oxy-swipe-action/oxy-swipe-action.vue +294 -0
  285. package/components/oxy-swipe-action/types.ts +40 -0
  286. package/components/oxy-swiper/index.scss +53 -0
  287. package/components/oxy-swiper/oxy-swiper.vue +318 -0
  288. package/components/oxy-swiper/types.ts +264 -0
  289. package/components/oxy-swiper-nav/index.scss +159 -0
  290. package/components/oxy-swiper-nav/oxy-swiper-nav.vue +37 -0
  291. package/components/oxy-swiper-nav/types.ts +42 -0
  292. package/components/oxy-switch/index.scss +58 -0
  293. package/components/oxy-switch/oxy-switch.vue +83 -0
  294. package/components/oxy-switch/types.ts +58 -0
  295. package/components/oxy-tab/index.scss +16 -0
  296. package/components/oxy-tab/oxy-tab.vue +88 -0
  297. package/components/oxy-tab/types.ts +30 -0
  298. package/components/oxy-tabbar/index.scss +62 -0
  299. package/components/oxy-tabbar/oxy-tabbar.vue +91 -0
  300. package/components/oxy-tabbar/types.ts +73 -0
  301. package/components/oxy-tabbar-item/index.scss +55 -0
  302. package/components/oxy-tabbar-item/oxy-tabbar-item.vue +99 -0
  303. package/components/oxy-tabbar-item/types.ts +51 -0
  304. package/components/oxy-table/index.scss +163 -0
  305. package/components/oxy-table/oxy-table.vue +283 -0
  306. package/components/oxy-table/types.ts +58 -0
  307. package/components/oxy-table-col/index.scss +46 -0
  308. package/components/oxy-table-col/oxy-table-col.vue +149 -0
  309. package/components/oxy-table-col/types.ts +54 -0
  310. package/components/oxy-tabs/index.scss +299 -0
  311. package/components/oxy-tabs/oxy-tabs.vue +443 -0
  312. package/components/oxy-tabs/types.ts +107 -0
  313. package/components/oxy-tag/index.scss +115 -0
  314. package/components/oxy-tag/oxy-tag.vue +148 -0
  315. package/components/oxy-tag/types.ts +81 -0
  316. package/components/oxy-text/index.scss +37 -0
  317. package/components/oxy-text/oxy-text.vue +139 -0
  318. package/components/oxy-text/types.ts +98 -0
  319. package/components/oxy-textarea/index.scss +340 -0
  320. package/components/oxy-textarea/oxy-textarea.vue +296 -0
  321. package/components/oxy-textarea/placeholder.scss +20 -0
  322. package/components/oxy-textarea/types.ts +288 -0
  323. package/components/oxy-toast/index.scss +75 -0
  324. package/components/oxy-toast/index.ts +92 -0
  325. package/components/oxy-toast/oxy-toast.vue +198 -0
  326. package/components/oxy-toast/types.ts +181 -0
  327. package/components/oxy-tooltip/index.scss +66 -0
  328. package/components/oxy-tooltip/oxy-tooltip.vue +141 -0
  329. package/components/oxy-tooltip/types.ts +107 -0
  330. package/components/oxy-transition/index.scss +95 -0
  331. package/components/oxy-transition/oxy-transition.vue +232 -0
  332. package/components/oxy-transition/types.ts +98 -0
  333. package/components/oxy-upload/index.scss +175 -0
  334. package/components/oxy-upload/oxy-upload.vue +673 -0
  335. package/components/oxy-upload/types.ts +391 -0
  336. package/components/oxy-video-preview/index.scss +34 -0
  337. package/components/oxy-video-preview/oxy-video-preview.vue +72 -0
  338. package/components/oxy-video-preview/types.ts +23 -0
  339. package/components/oxy-watermark/index.scss +18 -0
  340. package/components/oxy-watermark/oxy-watermark.vue +486 -0
  341. package/components/oxy-watermark/types.ts +76 -0
  342. package/dayjs/constant.js +26 -0
  343. package/dayjs/index.d.ts +430 -0
  344. package/dayjs/index.js +542 -0
  345. package/dayjs/locale/en.js +13 -0
  346. package/dayjs/utils.js +59 -0
  347. package/global.d.ts +101 -0
  348. package/index.ts +12 -0
  349. package/locale/index.ts +32 -0
  350. package/locale/lang/ar-SA.ts +133 -0
  351. package/locale/lang/en-US.ts +133 -0
  352. package/locale/lang/zh-CN.ts +137 -0
  353. package/package.json +1 -0
  354. package/tags.json +1 -0
  355. package/web-types.json +1 -0
@@ -0,0 +1,498 @@
1
+ <template>
2
+ <view :class="`oxy-col-picker ${customClass}`" :style="customStyle">
3
+ <oxy-cell
4
+ v-if="!$slots.default"
5
+ :title="label"
6
+ :value="showValue || placeholder || translate('placeholder')"
7
+ :required="required"
8
+ :size="size"
9
+ :title-width="labelWidth"
10
+ :prop="prop"
11
+ :rules="rules"
12
+ :clickable="!disabled && !readonly"
13
+ :value-align="alignRight ? 'right' : 'left'"
14
+ :custom-class="cellClass"
15
+ :custom-style="customStyle"
16
+ :custom-title-class="customLabelClass"
17
+ :custom-value-class="customValueClass"
18
+ :ellipsis="ellipsis"
19
+ :use-title-slot="!!$slots.label"
20
+ :marker-side="markerSide"
21
+ @click="showPicker"
22
+ >
23
+ <template v-if="$slots.label" #title>
24
+ <slot name="label"></slot>
25
+ </template>
26
+ <template #right-icon>
27
+ <oxy-icon v-if="showArrow" custom-class="oxy-col-picker__arrow" name="arrow-right" />
28
+ </template>
29
+ </oxy-cell>
30
+ <view v-else @click="showPicker">
31
+ <slot></slot>
32
+ </view>
33
+ <oxy-action-sheet
34
+ v-model="pickerShow"
35
+ :duration="250"
36
+ :title="title || translate('title')"
37
+ :close-on-click-modal="closeOnClickModal"
38
+ :z-index="zIndex"
39
+ :safe-area-inset-bottom="safeAreaInsetBottom"
40
+ :root-portal="rootPortal"
41
+ @open="handlePickerOpend"
42
+ @close="handlePickerClose"
43
+ @closed="handlePickerClosed"
44
+ >
45
+ <view class="oxy-col-picker__selected">
46
+ <scroll-view :scroll-x="true" scroll-with-animation :scroll-left="scrollLeft">
47
+ <view class="oxy-col-picker__selected-container">
48
+ <view
49
+ v-for="(_, colIndex) in selectList"
50
+ :key="colIndex"
51
+ :class="`oxy-col-picker__selected-item ${colIndex === currentCol && 'is-selected'}`"
52
+ @click="handleColClick(colIndex)"
53
+ >
54
+ {{ selectShowList[colIndex] || translate('select') }}
55
+ </view>
56
+ <view class="oxy-col-picker__selected-line" :style="state.lineStyle"></view>
57
+ </view>
58
+ </scroll-view>
59
+ </view>
60
+ <view class="oxy-col-picker__list-container">
61
+ <view
62
+ v-for="(col, colIndex) in selectList"
63
+ :key="colIndex"
64
+ class="oxy-col-picker__list"
65
+ :style="colIndex === currentCol ? 'display: block;' : 'display: none;'"
66
+ >
67
+ <view
68
+ v-for="(item, index) in col"
69
+ :key="index"
70
+ :class="`oxy-col-picker__list-item ${pickerColSelected[colIndex] && item[valueKey] === pickerColSelected[colIndex] && 'is-selected'} ${
71
+ item.disabled && 'is-disabled'
72
+ }`"
73
+ @click="chooseItem(colIndex, index)"
74
+ >
75
+ <view>
76
+ <view class="oxy-col-picker__list-item-label">{{ item[labelKey] }}</view>
77
+ <view v-if="item[tipKey]" class="oxy-col-picker__list-item-tip">{{ item[tipKey] }}</view>
78
+ </view>
79
+ <oxy-icon custom-class="oxy-col-picker__checked" name="check"></oxy-icon>
80
+ </view>
81
+ <view v-if="loading" class="oxy-col-picker__loading">
82
+ <oxy-loading :color="loadingColor" />
83
+ </view>
84
+ </view>
85
+ </view>
86
+ </oxy-action-sheet>
87
+ </view>
88
+ </template>
89
+ <script lang="ts">
90
+ export default {
91
+ name: 'oxy-col-picker',
92
+ options: {
93
+ addGlobalClass: true,
94
+ virtualHost: true,
95
+ styleIsolation: 'shared'
96
+ }
97
+ }
98
+ </script>
99
+
100
+ <script lang="ts" setup>
101
+ import OxyIcon from '../oxy-icon/oxy-icon.vue'
102
+ import OxyLoading from '../oxy-loading/oxy-loading.vue'
103
+ import OxyActionSheet from '../oxy-action-sheet/oxy-action-sheet.vue'
104
+ import OxyCell from '../oxy-cell/oxy-cell.vue'
105
+ import { computed, getCurrentInstance, onMounted, ref, watch, type CSSProperties, reactive } from 'vue'
106
+ import { addUnit, debounce, getRect, isArray, isBoolean, isDef, isFunction, objToStyle } from '../common/util'
107
+ import { useTranslate } from '../composables/useTranslate'
108
+ import { colPickerProps, type ColPickerExpose } from './types'
109
+
110
+ const { translate } = useTranslate('col-picker')
111
+
112
+ const $container = '.oxy-col-picker__selected-container'
113
+ const $item = '.oxy-col-picker__selected-item'
114
+
115
+ const props = defineProps(colPickerProps)
116
+ const emit = defineEmits(['close', 'update:modelValue', 'confirm'])
117
+
118
+ const pickerShow = ref<boolean>(false)
119
+ const currentCol = ref<number>(0)
120
+ const selectList = ref<Record<string, any>[][]>([])
121
+ const pickerColSelected = ref<(string | number)[]>([])
122
+ const selectShowList = ref<Record<string, any>[]>([])
123
+ const loading = ref<boolean>(false)
124
+ const isChange = ref<boolean>(false)
125
+ const lastSelectList = ref<Record<string, any>[][]>([])
126
+ const lastPickerColSelected = ref<(string | number)[]>([])
127
+ const scrollLeft = ref<number>(0)
128
+ const inited = ref<boolean>(false)
129
+ const isCompleting = ref<boolean>(false)
130
+
131
+ const state = reactive({
132
+ lineStyle: 'display:none;' // 激活项边框线样式
133
+ })
134
+
135
+ const { proxy } = getCurrentInstance() as any
136
+
137
+ const updateLineAndScroll = debounce(function (animation = true) {
138
+ setLineStyle(animation)
139
+ lineScrollIntoView()
140
+ }, 50)
141
+
142
+ const showValue = computed(() => {
143
+ const selectedItems = (props.modelValue || []).map((item, colIndex) => {
144
+ return getSelectedItem(item, colIndex, selectList.value)
145
+ })
146
+
147
+ if (props.displayFormat) {
148
+ return props.displayFormat(selectedItems)
149
+ } else {
150
+ return selectedItems
151
+ .map((item) => {
152
+ return item[props.labelKey]
153
+ })
154
+ .join('')
155
+ }
156
+ })
157
+
158
+ const cellClass = computed(() => {
159
+ const classes = ['oxy-col-picker__cell']
160
+ if (props.disabled) classes.push('is-disabled')
161
+ if (props.readonly) classes.push('is-readonly')
162
+ if (props.error) classes.push('is-error')
163
+ if (!showValue.value) classes.push('oxy-col-picker__cell--placeholder')
164
+ return classes.join(' ')
165
+ })
166
+
167
+ watch(
168
+ () => props.modelValue,
169
+ (newValue) => {
170
+ if (newValue === pickerColSelected.value) return
171
+ pickerColSelected.value = newValue
172
+ newValue.map((item, colIndex) => {
173
+ return getSelectedItem(item, colIndex, selectList.value)[props.labelKey]
174
+ })
175
+ handleAutoComplete()
176
+ },
177
+ {
178
+ deep: true,
179
+ immediate: true
180
+ }
181
+ )
182
+
183
+ watch(
184
+ () => props.columns,
185
+ (newValue, oldValue) => {
186
+ if (newValue.length && !isArray(newValue[0])) {
187
+ console.error('[Oxy ui] error(oxy-col-picker): the columns props of oxy-col-picker should be a two-dimensional array')
188
+ return
189
+ }
190
+ if (newValue.length === 0 && !oldValue) return
191
+
192
+ const newSelectedList = newValue.slice(0)
193
+
194
+ selectList.value = newSelectedList
195
+
196
+ selectShowList.value = pickerColSelected.value.map((item, colIndex) => {
197
+ return getSelectedItem(item, colIndex, newSelectedList)[props.labelKey]
198
+ })
199
+ lastSelectList.value = newSelectedList
200
+
201
+ if (newSelectedList.length > 0) {
202
+ currentCol.value = newSelectedList.length - 1
203
+ }
204
+ },
205
+ {
206
+ deep: true,
207
+ immediate: true
208
+ }
209
+ )
210
+
211
+ watch(
212
+ () => props.columnChange,
213
+ (fn) => {
214
+ if (fn && !isFunction(fn)) {
215
+ console.error('The type of columnChange must be Function')
216
+ }
217
+ },
218
+ {
219
+ deep: true,
220
+ immediate: true
221
+ }
222
+ )
223
+
224
+ watch(
225
+ () => props.displayFormat,
226
+ (fn) => {
227
+ if (fn && !isFunction(fn)) {
228
+ console.error('The type of displayFormat must be Function')
229
+ }
230
+ },
231
+ {
232
+ deep: true,
233
+ immediate: true
234
+ }
235
+ )
236
+
237
+ watch(
238
+ () => props.beforeConfirm,
239
+ (fn) => {
240
+ if (fn && !isFunction(fn)) {
241
+ console.error('The type of beforeConfirm must be Function')
242
+ }
243
+ },
244
+ {
245
+ deep: true,
246
+ immediate: true
247
+ }
248
+ )
249
+
250
+ // 是否展示箭头
251
+ const showArrow = computed(() => {
252
+ return !props.disabled && !props.readonly
253
+ })
254
+
255
+ onMounted(() => {
256
+ inited.value = true
257
+ })
258
+
259
+ // 打开弹框
260
+ function open() {
261
+ showPicker()
262
+ }
263
+ // 关闭弹框
264
+ function close() {
265
+ handlePickerClose()
266
+ }
267
+ function handlePickerOpend() {
268
+ updateLineAndScroll(false)
269
+ }
270
+
271
+ function handlePickerClose() {
272
+ pickerShow.value = false
273
+ emit('close')
274
+ }
275
+
276
+ function handlePickerClosed() {
277
+ if (isChange.value) {
278
+ setTimeout(() => {
279
+ selectList.value = lastSelectList.value.slice(0)
280
+ pickerColSelected.value = lastPickerColSelected.value.slice(0)
281
+ selectShowList.value = lastPickerColSelected.value.map((item, colIndex) => {
282
+ return getSelectedItem(item, colIndex, lastSelectList.value)[props.labelKey]
283
+ })
284
+ currentCol.value = lastSelectList.value.length - 1
285
+ isChange.value = false
286
+ }, 250)
287
+ }
288
+ }
289
+
290
+ function showPicker() {
291
+ const { disabled, readonly } = props
292
+
293
+ if (disabled || readonly) return
294
+ pickerShow.value = true
295
+ lastPickerColSelected.value = pickerColSelected.value.slice(0)
296
+ lastSelectList.value = selectList.value.slice(0)
297
+ }
298
+
299
+ function getSelectedItem(value: string | number, colIndex: number, selectList: Record<string, any>[][]) {
300
+ const { valueKey, labelKey } = props
301
+ if (selectList[colIndex]) {
302
+ const selecteds = selectList[colIndex].filter((item) => {
303
+ return item[valueKey] === value
304
+ })
305
+
306
+ if (selecteds.length > 0) {
307
+ return selecteds[0]
308
+ }
309
+ }
310
+
311
+ return {
312
+ [valueKey]: value,
313
+ [labelKey]: ''
314
+ }
315
+ }
316
+
317
+ function chooseItem(colIndex: number, index: number) {
318
+ const item = selectList.value[colIndex][index]
319
+ if (item.disabled) return
320
+
321
+ const newPickerColSelected = pickerColSelected.value.slice(0, colIndex)
322
+ newPickerColSelected.push(item[props.valueKey])
323
+ isChange.value = true
324
+ pickerColSelected.value = newPickerColSelected
325
+ selectList.value = selectList.value.slice(0, colIndex + 1)
326
+ selectShowList.value = newPickerColSelected.map((item, colIndex) => {
327
+ return getSelectedItem(item, colIndex, selectList.value)[props.labelKey]
328
+ })
329
+
330
+ if (selectShowList.value[colIndex] && colIndex === currentCol.value) {
331
+ updateLineAndScroll(true)
332
+ }
333
+
334
+ handleColChange(colIndex, item, index)
335
+ }
336
+
337
+ function handleColChange(colIndex: number, item: Record<string, any>, index: number, callback?: () => void) {
338
+ loading.value = true
339
+ const { columnChange, beforeConfirm } = props
340
+ columnChange &&
341
+ columnChange({
342
+ selectedItem: item,
343
+ index: colIndex,
344
+ rowIndex: index,
345
+ resolve: (nextColumn: Record<string, any>[]) => {
346
+ if (!isArray(nextColumn)) {
347
+ console.error('[Oxy ui] error(oxy-col-picker): the data of each column of oxy-col-picker should be an array')
348
+ return
349
+ }
350
+
351
+ const newSelectList = selectList.value.slice(0)
352
+ newSelectList[colIndex + 1] = nextColumn
353
+
354
+ selectList.value = newSelectList
355
+ loading.value = false
356
+ currentCol.value = colIndex + 1
357
+
358
+ updateLineAndScroll(true)
359
+ if (typeof callback === 'function') {
360
+ isCompleting.value = false
361
+ selectShowList.value = pickerColSelected.value.map((item, colIndex) => {
362
+ return getSelectedItem(item, colIndex, selectList.value)[props.labelKey]
363
+ })
364
+ callback()
365
+ }
366
+ },
367
+ finish: (isOk?: boolean) => {
368
+ // 每设置展示数据回显
369
+ if (typeof callback === 'function') {
370
+ loading.value = false
371
+ isCompleting.value = false
372
+ return
373
+ }
374
+ if (isBoolean(isOk) && !isOk) {
375
+ loading.value = false
376
+ return
377
+ }
378
+
379
+ if (beforeConfirm) {
380
+ beforeConfirm(
381
+ pickerColSelected.value,
382
+ pickerColSelected.value.map((item, colIndex) => {
383
+ return getSelectedItem(item, colIndex, selectList.value)
384
+ }),
385
+ (isPass: boolean) => {
386
+ if (isPass) {
387
+ onConfirm()
388
+ } else {
389
+ loading.value = false
390
+ }
391
+ }
392
+ )
393
+ } else {
394
+ onConfirm()
395
+ }
396
+ }
397
+ })
398
+ }
399
+ function onConfirm() {
400
+ isChange.value = false
401
+ loading.value = false
402
+ pickerShow.value = false
403
+
404
+ emit('update:modelValue', pickerColSelected.value)
405
+ emit('confirm', {
406
+ value: pickerColSelected.value,
407
+ selectedItems: pickerColSelected.value.map((item, colIndex) => {
408
+ return getSelectedItem(item, colIndex, selectList.value)
409
+ })
410
+ })
411
+ }
412
+ function handleColClick(index: number) {
413
+ isChange.value = true
414
+ currentCol.value = index
415
+ updateLineAndScroll(true)
416
+ }
417
+ /**
418
+ * @description 更新navBar underline的偏移量
419
+ * @param {Boolean} animation 是否伴随动画
420
+ */
421
+ function setLineStyle(animation: boolean = true) {
422
+ if (!inited.value) return
423
+ const { lineWidth, lineHeight } = props
424
+ getRect($item, true, proxy)
425
+ .then((rects) => {
426
+ const lineStyle: CSSProperties = {}
427
+ if (isDef(lineWidth)) {
428
+ lineStyle.width = addUnit(lineWidth)
429
+ }
430
+ if (isDef(lineHeight)) {
431
+ lineStyle.height = addUnit(lineHeight)
432
+ lineStyle.borderRadius = `calc(${addUnit(lineHeight)} / 2)`
433
+ }
434
+ const rect = rects[currentCol.value]
435
+ let left = rects.slice(0, currentCol.value).reduce((prev, curr) => prev + Number(curr.width), 0) + Number(rect.width) / 2
436
+ lineStyle.transform = `translateX(${left}px) translateX(-50%)`
437
+
438
+ if (animation) {
439
+ lineStyle.transition = 'width 300ms ease, transform 300ms ease'
440
+ }
441
+
442
+ state.lineStyle = objToStyle(lineStyle)
443
+ })
444
+ .catch(() => {})
445
+ }
446
+ /**
447
+ * @description scroll-view滑动到active的tab_nav
448
+ */
449
+ function lineScrollIntoView() {
450
+ if (!inited.value) return
451
+ Promise.all([getRect($item, true, proxy), getRect($container, false, proxy)])
452
+ .then(([navItemsRects, navRect]) => {
453
+ if (!isArray(navItemsRects) || navItemsRects.length === 0) return
454
+ // 选中元素
455
+ const selectItem = navItemsRects[currentCol.value]
456
+ // 选中元素之前的节点的宽度总和
457
+ const offsetLeft = navItemsRects.slice(0, currentCol.value).reduce((prev, curr) => prev + Number(curr.width), 0)
458
+ // scroll-view滑动到selectItem的偏移量
459
+ scrollLeft.value = offsetLeft - ((navRect as any).width - Number(selectItem.width)) / 2
460
+ })
461
+ .catch(() => {})
462
+ }
463
+
464
+ // 递归列数据补齐
465
+ function diffColumns(colIndex: number) {
466
+ // colIndex 为 -1 时,item 为空对象,>=0 时则具有 value 属性
467
+ const item = colIndex === -1 ? {} : { [props.valueKey]: props.modelValue[colIndex] }
468
+ handleColChange(colIndex, item, -1, () => {
469
+ // 如果 columns 长度还小于 value 长度,colIndex + 1,继续递归补齐
470
+ if (selectList.value.length < props.modelValue.length) {
471
+ diffColumns(colIndex + 1)
472
+ }
473
+ })
474
+ }
475
+ function handleAutoComplete() {
476
+ if (props.autoComplete) {
477
+ // 如果 columns 数组长度为空,或者长度小于 value 的长度,自动触发 columnChange 来补齐数据
478
+ if (selectList.value.length < props.modelValue.length || selectList.value.length === 0) {
479
+ // isCompleting 是否在自动补全,锁操作
480
+ if (!isCompleting.value) {
481
+ // 如果 columns 长度为空,则传入的 colIndex 为 -1
482
+ const colIndex = selectList.value.length === 0 ? -1 : selectList.value.length - 1
483
+ diffColumns(colIndex)
484
+ }
485
+ isCompleting.value = true
486
+ }
487
+ }
488
+ }
489
+
490
+ defineExpose<ColPickerExpose>({
491
+ close,
492
+ open
493
+ })
494
+ </script>
495
+
496
+ <style lang="scss" scoped>
497
+ @import './index.scss';
498
+ </style>
@@ -0,0 +1,166 @@
1
+ import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
2
+ import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp, numericProp } from '../common/props'
3
+ import type { FormItemRule } from '../oxy-form/types'
4
+
5
+ export const colPickerProps = {
6
+ ...baseProps,
7
+ /**
8
+ * 选中项
9
+ */
10
+ modelValue: makeRequiredProp(Array as PropType<Array<string | number>>),
11
+ /**
12
+ * 选择器数据,二维数组
13
+ */
14
+ columns: makeArrayProp<Record<string, any>[]>(),
15
+ /**
16
+ * 选择器左侧文案
17
+ */
18
+ label: String,
19
+ /**
20
+ * 设置左侧标题宽度
21
+ */
22
+ labelWidth: makeStringProp('33%'),
23
+ /**
24
+ * 使用 label 插槽时设置该选项
25
+ */
26
+ useLabelSlot: makeBooleanProp(false),
27
+ /**
28
+ * 使用默认插槽时设置该选项
29
+ */
30
+ useDefaultSlot: makeBooleanProp(false),
31
+ /**
32
+ * 禁用
33
+ */
34
+ disabled: makeBooleanProp(false),
35
+ /**
36
+ * 只读
37
+ */
38
+ readonly: makeBooleanProp(false),
39
+ /**
40
+ * 选择器占位符
41
+ */
42
+ placeholder: String,
43
+ /**
44
+ * 弹出层标题
45
+ */
46
+ title: String,
47
+ /**
48
+ * 接收当前列的选中项 item、当前列下标、当前列选中项下标下一列数据处理函数 resolve、结束选择 finish
49
+ */
50
+ columnChange: Function as PropType<ColPickerColumnChange>,
51
+ /**
52
+ * 自定义展示文案的格式化函数,返回一个字符串
53
+ */
54
+ displayFormat: Function as PropType<ColPickerDisplayFormat>,
55
+ /**
56
+ * 确定前校验函数,接收 (value, resolve) 参数,通过 resolve 继续执行 picker,resolve 接收 1 个 boolean 参数
57
+ */
58
+ beforeConfirm: Function as PropType<ColPickerBeforeConfirm>,
59
+ /**
60
+ * 选择器的值靠右展示
61
+ */
62
+ alignRight: makeBooleanProp(false),
63
+ /**
64
+ * 是否为错误状态,错误状态时右侧内容为红色
65
+ */
66
+ error: makeBooleanProp(false),
67
+ /**
68
+ * 是否必填
69
+ */
70
+ required: makeBooleanProp(false),
71
+ /**
72
+ * 设置选择器大小,可选值:large
73
+ */
74
+ size: String,
75
+ /**
76
+ * 选项对象中,value 对应的 key
77
+ */
78
+ valueKey: makeStringProp('value'),
79
+ /**
80
+ * 选项对象中,展示的文本对应的 key
81
+ */
82
+ labelKey: makeStringProp('label'),
83
+ /**
84
+ * 选项对象中,提示文案对应的 key
85
+ */
86
+ tipKey: makeStringProp('tip'),
87
+ /**
88
+ * loading 图标的颜色
89
+ */
90
+ loadingColor: makeStringProp('#4D80F0'),
91
+ /**
92
+ * 点击遮罩是否关闭
93
+ */
94
+ closeOnClickModal: makeBooleanProp(true),
95
+ /**
96
+ * 自动触发 column-change 事件来补全数据,当 columns 为空数组或者 columns 数组长度小于 value 数组长度时,会自动触发 column-change
97
+ */
98
+ autoComplete: makeBooleanProp(false),
99
+ /**
100
+ * 弹窗层级
101
+ */
102
+ zIndex: makeNumberProp(15),
103
+ /**
104
+ * 弹出面板是否设置底部安全距离(iphone X 类型的机型)
105
+ */
106
+ safeAreaInsetBottom: makeBooleanProp(true),
107
+ /**
108
+ * 是否超出隐藏
109
+ */
110
+ ellipsis: makeBooleanProp(false),
111
+ /**
112
+ * 表单域 model 字段名,在使用表单校验功能的情况下,该属性是必填的
113
+ */
114
+ prop: String,
115
+ /**
116
+ * 表单验证规则,结合oxy-form组件使用
117
+ */
118
+ rules: makeArrayProp<FormItemRule>(),
119
+ /**
120
+ * 底部条宽度,单位像素
121
+ */
122
+ lineWidth: numericProp,
123
+ /**
124
+ * 底部条高度,单位像素
125
+ */
126
+ lineHeight: numericProp,
127
+ /**
128
+ * label 外部自定义样式
129
+ */
130
+ customViewClass: makeStringProp(''),
131
+ /**
132
+ * value 外部自定义样式
133
+ */
134
+ customLabelClass: makeStringProp(''),
135
+ customValueClass: makeStringProp(''),
136
+ /**
137
+ * 是否从页面中脱离出来,用于解决各种 fixed 失效问题 (H5: teleport, APP: renderjs, 小程序: root-portal)
138
+ */
139
+ rootPortal: makeBooleanProp(false),
140
+ /**
141
+ * 必填标记位置,可选值:before、after
142
+ */
143
+ markerSide: makeStringProp<'before' | 'after'>('before')
144
+ }
145
+
146
+ export type ColPickerProps = ExtractPropTypes<typeof colPickerProps>
147
+
148
+ export type ColPickerColumnChangeOption = {
149
+ selectedItem: Record<string, any>
150
+ index: number
151
+ rowIndex: number
152
+ resolve: (nextColumn: Record<string, any>[]) => void
153
+ finish: (isOk?: boolean) => void
154
+ }
155
+ export type ColPickerColumnChange = (option: ColPickerColumnChangeOption) => void
156
+ export type ColPickerDisplayFormat = (selectedItems: Record<string, any>[]) => string
157
+ export type ColPickerBeforeConfirm = (value: (string | number)[], selectedItems: Record<string, any>[], resolve: (isPass: boolean) => void) => void
158
+
159
+ export type ColPickerExpose = {
160
+ // 关闭picker弹框
161
+ close: () => void
162
+ // 打开picker弹框
163
+ open: () => void
164
+ }
165
+
166
+ export type ColPickerInstance = ComponentPublicInstance<ColPickerExpose, ColPickerProps>