@tplc/wot 0.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 (328) hide show
  1. package/components/common/AbortablePromise.ts +36 -0
  2. package/components/common/abstracts/_config.scss +7 -0
  3. package/components/common/abstracts/_function.scss +76 -0
  4. package/components/common/abstracts/_mixin.scss +339 -0
  5. package/components/common/abstracts/variable.scss +1346 -0
  6. package/components/common/base64.ts +30 -0
  7. package/components/common/canvasHelper.ts +49 -0
  8. package/components/common/clickoutside.ts +34 -0
  9. package/components/common/dayjs.ts +157 -0
  10. package/components/common/event.ts +8 -0
  11. package/components/common/props.ts +51 -0
  12. package/components/common/util.ts +751 -0
  13. package/components/composables/useCell.ts +13 -0
  14. package/components/composables/useChildren.ts +122 -0
  15. package/components/composables/useCountDown.ts +138 -0
  16. package/components/composables/useLockScroll.ts +39 -0
  17. package/components/composables/useParent.ts +41 -0
  18. package/components/composables/usePopover.ts +193 -0
  19. package/components/composables/useQueue.ts +52 -0
  20. package/components/composables/useRaf.ts +37 -0
  21. package/components/composables/useTouch.ts +44 -0
  22. package/components/composables/useTranslate.ts +22 -0
  23. package/components/wd-action-sheet/index.scss +204 -0
  24. package/components/wd-action-sheet/types.ts +128 -0
  25. package/components/wd-action-sheet/wd-action-sheet.vue +174 -0
  26. package/components/wd-backtop/index.scss +25 -0
  27. package/components/wd-backtop/types.ts +37 -0
  28. package/components/wd-backtop/wd-backtop.vue +48 -0
  29. package/components/wd-badge/index.scss +59 -0
  30. package/components/wd-badge/types.ts +53 -0
  31. package/components/wd-badge/wd-badge.vue +69 -0
  32. package/components/wd-button/index.scss +340 -0
  33. package/components/wd-button/types.ts +112 -0
  34. package/components/wd-button/wd-button.vue +176 -0
  35. package/components/wd-calendar/index.scss +244 -0
  36. package/components/wd-calendar/types.ts +235 -0
  37. package/components/wd-calendar/wd-calendar.vue +456 -0
  38. package/components/wd-calendar-view/index.scss +9 -0
  39. package/components/wd-calendar-view/month/index.scss +151 -0
  40. package/components/wd-calendar-view/month/month.vue +391 -0
  41. package/components/wd-calendar-view/month/types.ts +19 -0
  42. package/components/wd-calendar-view/monthPanel/index.scss +89 -0
  43. package/components/wd-calendar-view/monthPanel/month-panel.vue +388 -0
  44. package/components/wd-calendar-view/monthPanel/types.ts +48 -0
  45. package/components/wd-calendar-view/types.ts +134 -0
  46. package/components/wd-calendar-view/utils.ts +451 -0
  47. package/components/wd-calendar-view/wd-calendar-view.vue +111 -0
  48. package/components/wd-calendar-view/year/index.scss +148 -0
  49. package/components/wd-calendar-view/year/types.ts +19 -0
  50. package/components/wd-calendar-view/year/year.vue +220 -0
  51. package/components/wd-calendar-view/yearPanel/index.scss +24 -0
  52. package/components/wd-calendar-view/yearPanel/types.ts +38 -0
  53. package/components/wd-calendar-view/yearPanel/year-panel.vue +140 -0
  54. package/components/wd-card/index.scss +70 -0
  55. package/components/wd-card/types.ts +30 -0
  56. package/components/wd-card/wd-card.vue +40 -0
  57. package/components/wd-cell/index.scss +189 -0
  58. package/components/wd-cell/types.ts +96 -0
  59. package/components/wd-cell/wd-cell.vue +135 -0
  60. package/components/wd-cell-group/index.scss +55 -0
  61. package/components/wd-cell-group/types.ts +41 -0
  62. package/components/wd-cell-group/wd-cell-group.vue +45 -0
  63. package/components/wd-checkbox/index.scss +285 -0
  64. package/components/wd-checkbox/types.ts +68 -0
  65. package/components/wd-checkbox/wd-checkbox.vue +185 -0
  66. package/components/wd-checkbox-group/index.scss +20 -0
  67. package/components/wd-checkbox-group/types.ts +59 -0
  68. package/components/wd-checkbox-group/wd-checkbox-group.vue +103 -0
  69. package/components/wd-circle/index.scss +18 -0
  70. package/components/wd-circle/types.ts +54 -0
  71. package/components/wd-circle/wd-circle.vue +318 -0
  72. package/components/wd-col/index.scss +19 -0
  73. package/components/wd-col/types.ts +15 -0
  74. package/components/wd-col/wd-col.vue +91 -0
  75. package/components/wd-col-picker/index.scss +241 -0
  76. package/components/wd-col-picker/types.ts +170 -0
  77. package/components/wd-col-picker/wd-col-picker.vue +550 -0
  78. package/components/wd-collapse/index.scss +55 -0
  79. package/components/wd-collapse/types.ts +63 -0
  80. package/components/wd-collapse/wd-collapse.vue +160 -0
  81. package/components/wd-collapse-item/index.scss +79 -0
  82. package/components/wd-collapse-item/types.ts +36 -0
  83. package/components/wd-collapse-item/wd-collapse-item.vue +182 -0
  84. package/components/wd-config-provider/types.ts +1023 -0
  85. package/components/wd-config-provider/wd-config-provider.vue +82 -0
  86. package/components/wd-count-down/index.scss +14 -0
  87. package/components/wd-count-down/types.ts +41 -0
  88. package/components/wd-count-down/utils.ts +52 -0
  89. package/components/wd-count-down/wd-count-down.vue +60 -0
  90. package/components/wd-count-to/index.scss +6 -0
  91. package/components/wd-count-to/types.ts +110 -0
  92. package/components/wd-count-to/wd-count-to.vue +134 -0
  93. package/components/wd-curtain/index.scss +80 -0
  94. package/components/wd-curtain/types.ts +45 -0
  95. package/components/wd-curtain/wd-curtain.vue +174 -0
  96. package/components/wd-datetime-picker/index.scss +243 -0
  97. package/components/wd-datetime-picker/types.ts +225 -0
  98. package/components/wd-datetime-picker/wd-datetime-picker.vue +827 -0
  99. package/components/wd-datetime-picker-view/index.scss +0 -0
  100. package/components/wd-datetime-picker-view/types.ts +137 -0
  101. package/components/wd-datetime-picker-view/wd-datetime-picker-view.vue +514 -0
  102. package/components/wd-divider/index.scss +32 -0
  103. package/components/wd-divider/types.ts +12 -0
  104. package/components/wd-divider/wd-divider.vue +29 -0
  105. package/components/wd-drop-menu/index.scss +89 -0
  106. package/components/wd-drop-menu/types.ts +38 -0
  107. package/components/wd-drop-menu/wd-drop-menu.vue +128 -0
  108. package/components/wd-drop-menu-item/index.scss +66 -0
  109. package/components/wd-drop-menu-item/types.ts +78 -0
  110. package/components/wd-drop-menu-item/wd-drop-menu-item.vue +230 -0
  111. package/components/wd-fab/index.scss +115 -0
  112. package/components/wd-fab/types.ts +61 -0
  113. package/components/wd-fab/wd-fab.vue +257 -0
  114. package/components/wd-form/index.scss +10 -0
  115. package/components/wd-form/types.ts +93 -0
  116. package/components/wd-form/wd-form.vue +185 -0
  117. package/components/wd-form-item/index.scss +17 -0
  118. package/components/wd-form-item/types.ts +22 -0
  119. package/components/wd-form-item/wd-form-item.vue +65 -0
  120. package/components/wd-gap/index.scss +9 -0
  121. package/components/wd-gap/types.ts +23 -0
  122. package/components/wd-gap/wd-gap.vue +39 -0
  123. package/components/wd-grid/index.scss +9 -0
  124. package/components/wd-grid/types.ts +54 -0
  125. package/components/wd-grid/wd-grid.vue +107 -0
  126. package/components/wd-grid-item/index.scss +137 -0
  127. package/components/wd-grid-item/types.ts +74 -0
  128. package/components/wd-grid-item/wd-grid-item.vue +181 -0
  129. package/components/wd-icon/index.scss +1222 -0
  130. package/components/wd-icon/types.ts +21 -0
  131. package/components/wd-icon/wd-icon.vue +53 -0
  132. package/components/wd-icon/wd-icons.ttf +0 -0
  133. package/components/wd-img/index.scss +19 -0
  134. package/components/wd-img/types.ts +53 -0
  135. package/components/wd-img/wd-img.vue +76 -0
  136. package/components/wd-img-cropper/index.scss +227 -0
  137. package/components/wd-img-cropper/types.ts +87 -0
  138. package/components/wd-img-cropper/wd-img-cropper.vue +659 -0
  139. package/components/wd-index-anchor/index.scss +34 -0
  140. package/components/wd-index-anchor/type.ts +9 -0
  141. package/components/wd-index-anchor/wd-index-anchor.vue +57 -0
  142. package/components/wd-index-bar/index.scss +39 -0
  143. package/components/wd-index-bar/type.ts +28 -0
  144. package/components/wd-index-bar/wd-index-bar.vue +158 -0
  145. package/components/wd-input/index.scss +326 -0
  146. package/components/wd-input/types.ts +182 -0
  147. package/components/wd-input/wd-input.vue +327 -0
  148. package/components/wd-input-number/index.scss +132 -0
  149. package/components/wd-input-number/types.ts +78 -0
  150. package/components/wd-input-number/wd-input-number.vue +221 -0
  151. package/components/wd-loading/index.scss +34 -0
  152. package/components/wd-loading/types.ts +31 -0
  153. package/components/wd-loading/wd-loading.vue +90 -0
  154. package/components/wd-loadmore/index.scss +39 -0
  155. package/components/wd-loadmore/types.ts +24 -0
  156. package/components/wd-loadmore/wd-loadmore.vue +53 -0
  157. package/components/wd-message-box/index.scss +121 -0
  158. package/components/wd-message-box/index.ts +95 -0
  159. package/components/wd-message-box/types.ts +116 -0
  160. package/components/wd-message-box/wd-message-box.vue +326 -0
  161. package/components/wd-navbar/index.scss +103 -0
  162. package/components/wd-navbar/types.ts +52 -0
  163. package/components/wd-navbar/wd-navbar.vue +142 -0
  164. package/components/wd-navbar-capsule/index.scss +65 -0
  165. package/components/wd-navbar-capsule/types.ts +0 -0
  166. package/components/wd-navbar-capsule/wd-navbar-capsule.vue +31 -0
  167. package/components/wd-notice-bar/index.scss +86 -0
  168. package/components/wd-notice-bar/types.ts +56 -0
  169. package/components/wd-notice-bar/wd-notice-bar.vue +223 -0
  170. package/components/wd-notify/index.scss +34 -0
  171. package/components/wd-notify/index.ts +59 -0
  172. package/components/wd-notify/types.ts +62 -0
  173. package/components/wd-notify/wd-notify.vue +83 -0
  174. package/components/wd-number-keyboard/index.scss +78 -0
  175. package/components/wd-number-keyboard/key/index.scss +79 -0
  176. package/components/wd-number-keyboard/key/index.vue +76 -0
  177. package/components/wd-number-keyboard/key/types.ts +11 -0
  178. package/components/wd-number-keyboard/types.ts +79 -0
  179. package/components/wd-number-keyboard/wd-number-keyboard.vue +173 -0
  180. package/components/wd-overlay/index.scss +17 -0
  181. package/components/wd-overlay/types.ts +25 -0
  182. package/components/wd-overlay/wd-overlay.vue +46 -0
  183. package/components/wd-pagination/index.scss +57 -0
  184. package/components/wd-pagination/types.ts +41 -0
  185. package/components/wd-pagination/wd-pagination.vue +121 -0
  186. package/components/wd-password-input/index.scss +123 -0
  187. package/components/wd-password-input/types.ts +48 -0
  188. package/components/wd-password-input/wd-password-input.vue +58 -0
  189. package/components/wd-picker/index.scss +216 -0
  190. package/components/wd-picker/types.ts +186 -0
  191. package/components/wd-picker/wd-picker.vue +409 -0
  192. package/components/wd-picker-view/index.scss +91 -0
  193. package/components/wd-picker-view/types.ts +162 -0
  194. package/components/wd-picker-view/wd-picker-view.vue +361 -0
  195. package/components/wd-popover/index.scss +123 -0
  196. package/components/wd-popover/types.ts +69 -0
  197. package/components/wd-popover/wd-popover.vue +216 -0
  198. package/components/wd-popup/index.scss +112 -0
  199. package/components/wd-popup/types.ts +68 -0
  200. package/components/wd-popup/wd-popup.vue +227 -0
  201. package/components/wd-progress/index.scss +62 -0
  202. package/components/wd-progress/types.ts +40 -0
  203. package/components/wd-progress/wd-progress.vue +201 -0
  204. package/components/wd-radio/index.scss +300 -0
  205. package/components/wd-radio/types.ts +42 -0
  206. package/components/wd-radio/wd-radio.vue +136 -0
  207. package/components/wd-radio-group/index.scss +23 -0
  208. package/components/wd-radio-group/types.ts +36 -0
  209. package/components/wd-radio-group/wd-radio-group.vue +54 -0
  210. package/components/wd-rate/index.scss +24 -0
  211. package/components/wd-rate/types.ts +91 -0
  212. package/components/wd-rate/wd-rate.vue +131 -0
  213. package/components/wd-resize/index.scss +26 -0
  214. package/components/wd-resize/types.ts +6 -0
  215. package/components/wd-resize/wd-resize.vue +155 -0
  216. package/components/wd-row/index.scss +10 -0
  217. package/components/wd-row/types.ts +16 -0
  218. package/components/wd-row/wd-row.vue +63 -0
  219. package/components/wd-search/index.scss +148 -0
  220. package/components/wd-search/types.ts +83 -0
  221. package/components/wd-search/wd-search.vue +237 -0
  222. package/components/wd-segmented/index.scss +97 -0
  223. package/components/wd-segmented/types.ts +68 -0
  224. package/components/wd-segmented/wd-segmented.vue +143 -0
  225. package/components/wd-select-picker/index.scss +177 -0
  226. package/components/wd-select-picker/types.ts +116 -0
  227. package/components/wd-select-picker/wd-select-picker.vue +486 -0
  228. package/components/wd-sidebar/index.scss +25 -0
  229. package/components/wd-sidebar/types.ts +28 -0
  230. package/components/wd-sidebar/wd-sidebar.vue +41 -0
  231. package/components/wd-sidebar-item/index.scss +93 -0
  232. package/components/wd-sidebar-item/types.ts +31 -0
  233. package/components/wd-sidebar-item/wd-sidebar-item.vue +114 -0
  234. package/components/wd-skeleton/index.scss +101 -0
  235. package/components/wd-skeleton/index.ts +1 -0
  236. package/components/wd-skeleton/types.ts +69 -0
  237. package/components/wd-skeleton/wd-skeleton.vue +135 -0
  238. package/components/wd-slider/index.scss +91 -0
  239. package/components/wd-slider/types.ts +104 -0
  240. package/components/wd-slider/wd-slider.vue +377 -0
  241. package/components/wd-sort-button/index.scss +86 -0
  242. package/components/wd-sort-button/types.ts +43 -0
  243. package/components/wd-sort-button/wd-sort-button.vue +76 -0
  244. package/components/wd-status-tip/index.scss +37 -0
  245. package/components/wd-status-tip/types.ts +59 -0
  246. package/components/wd-status-tip/wd-status-tip.vue +94 -0
  247. package/components/wd-step/index.scss +236 -0
  248. package/components/wd-step/types.ts +33 -0
  249. package/components/wd-step/wd-step.vue +151 -0
  250. package/components/wd-steps/index.scss +10 -0
  251. package/components/wd-steps/types.ts +59 -0
  252. package/components/wd-steps/wd-steps.vue +37 -0
  253. package/components/wd-sticky/index.scss +9 -0
  254. package/components/wd-sticky/types.ts +13 -0
  255. package/components/wd-sticky/wd-sticky.vue +190 -0
  256. package/components/wd-sticky-box/index.scss +6 -0
  257. package/components/wd-sticky-box/types.ts +20 -0
  258. package/components/wd-sticky-box/wd-sticky-box.vue +154 -0
  259. package/components/wd-swipe-action/index.scss +22 -0
  260. package/components/wd-swipe-action/types.ts +43 -0
  261. package/components/wd-swipe-action/wd-swipe-action.vue +307 -0
  262. package/components/wd-swiper/index.scss +23 -0
  263. package/components/wd-swiper/types.ts +189 -0
  264. package/components/wd-swiper/wd-swiper.vue +202 -0
  265. package/components/wd-swiper-nav/index.scss +153 -0
  266. package/components/wd-swiper-nav/types.ts +42 -0
  267. package/components/wd-swiper-nav/wd-swiper-nav.vue +37 -0
  268. package/components/wd-switch/index.scss +58 -0
  269. package/components/wd-switch/types.ts +56 -0
  270. package/components/wd-switch/wd-switch.vue +83 -0
  271. package/components/wd-tab/index.scss +8 -0
  272. package/components/wd-tab/types.ts +20 -0
  273. package/components/wd-tab/wd-tab.vue +100 -0
  274. package/components/wd-tabbar/index.scss +57 -0
  275. package/components/wd-tabbar/types.ts +88 -0
  276. package/components/wd-tabbar/wd-tabbar.vue +104 -0
  277. package/components/wd-tabbar-item/index.scss +52 -0
  278. package/components/wd-tabbar-item/types.ts +51 -0
  279. package/components/wd-tabbar-item/wd-tabbar-item.vue +101 -0
  280. package/components/wd-table/index.scss +132 -0
  281. package/components/wd-table/types.ts +69 -0
  282. package/components/wd-table/wd-table.vue +255 -0
  283. package/components/wd-table-col/index.scss +44 -0
  284. package/components/wd-table-col/types.ts +54 -0
  285. package/components/wd-table-col/wd-table-col.vue +149 -0
  286. package/components/wd-tabs/index.scss +280 -0
  287. package/components/wd-tabs/types.ts +71 -0
  288. package/components/wd-tabs/wd-tabs.vue +528 -0
  289. package/components/wd-tag/index.scss +115 -0
  290. package/components/wd-tag/types.ts +81 -0
  291. package/components/wd-tag/wd-tag.vue +154 -0
  292. package/components/wd-text/index.scss +34 -0
  293. package/components/wd-text/types.ts +98 -0
  294. package/components/wd-text/wd-text.vue +138 -0
  295. package/components/wd-textarea/index.scss +343 -0
  296. package/components/wd-textarea/types.ts +298 -0
  297. package/components/wd-textarea/wd-textarea.vue +303 -0
  298. package/components/wd-toast/index.scss +66 -0
  299. package/components/wd-toast/index.ts +109 -0
  300. package/components/wd-toast/types.ts +76 -0
  301. package/components/wd-toast/wd-toast.vue +212 -0
  302. package/components/wd-tooltip/index.scss +61 -0
  303. package/components/wd-tooltip/types.ts +102 -0
  304. package/components/wd-tooltip/wd-tooltip.vue +167 -0
  305. package/components/wd-transition/index.scss +91 -0
  306. package/components/wd-transition/types.ts +89 -0
  307. package/components/wd-transition/wd-transition.vue +221 -0
  308. package/components/wd-upload/index.scss +173 -0
  309. package/components/wd-upload/types.ts +378 -0
  310. package/components/wd-upload/utils.ts +152 -0
  311. package/components/wd-upload/wd-upload.vue +737 -0
  312. package/components/wd-video-preview/index.scss +34 -0
  313. package/components/wd-video-preview/types.ts +32 -0
  314. package/components/wd-video-preview/wd-video-preview.vue +76 -0
  315. package/components/wd-watermark/index.scss +18 -0
  316. package/components/wd-watermark/types.ts +82 -0
  317. package/components/wd-watermark/wd-watermark.vue +592 -0
  318. package/components/wot-design-uni/wot-design-uni.vue +14 -0
  319. package/global.d.ts +108 -0
  320. package/index.ts +30 -0
  321. package/locale/index.ts +41 -0
  322. package/locale/lang/en-US.ts +128 -0
  323. package/locale/lang/th-TH.ts +127 -0
  324. package/locale/lang/vi-VN.ts +89 -0
  325. package/locale/lang/zh-CN.ts +127 -0
  326. package/locale/lang/zh-HK.ts +84 -0
  327. package/locale/lang/zh-TW.ts +84 -0
  328. package/package.json +20 -0
@@ -0,0 +1,162 @@
1
+ import type { ComponentPublicInstance, ExtractPropTypes, PropType, Ref } from 'vue'
2
+ import {
3
+ baseProps,
4
+ makeArrayProp,
5
+ makeBooleanProp,
6
+ makeNumberProp,
7
+ makeStringProp,
8
+ } from '../common/props'
9
+ import { getType, isArray, isObj } from '../common/util'
10
+
11
+ export type ColumnItem = {
12
+ [key: string]: any
13
+ value?: string | number | boolean
14
+ label?: string
15
+ disabled?: boolean
16
+ }
17
+
18
+ export type PickerViewColumnChange = (
19
+ pickerView: PickerViewInstance,
20
+ selects: Record<string, any> | Record<string, any>[],
21
+ index: number,
22
+ reslove: () => void,
23
+ ) => void
24
+
25
+ export const pickerViewProps = {
26
+ ...baseProps,
27
+ /**
28
+ * 加载状态
29
+ */
30
+ loading: makeBooleanProp(false),
31
+ /**
32
+ * 加载的颜色,只能使用十六进制的色值写法,且不能使用缩写
33
+ */
34
+ loadingColor: makeStringProp('#4D80F0'),
35
+ /**
36
+ * picker内部滚筒高
37
+ */
38
+ columnsHeight: makeNumberProp(217),
39
+ /**
40
+ * 选项对象中,value对应的 key
41
+ */
42
+ valueKey: makeStringProp('value'),
43
+ /**
44
+ * 选项对象中,展示的文本对应的 key
45
+ */
46
+ labelKey: makeStringProp('label'),
47
+ /**
48
+ * 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
49
+ */
50
+ immediateChange: makeBooleanProp(false),
51
+ /**
52
+ * 选中项,如果为多列选择器,则其类型应为数组
53
+ */
54
+ modelValue: {
55
+ type: [String, Number, Boolean, Array<number>, Array<string>, Array<boolean>] as PropType<
56
+ string | number | boolean | Array<number> | Array<string> | Array<boolean>
57
+ >,
58
+ default: '',
59
+ required: true,
60
+ },
61
+ /**
62
+ * 选择器数据,可以为字符串数组,也可以为对象数组,如果为二维数组,则为多列选择器
63
+ */
64
+ columns: makeArrayProp<
65
+ string | number | ColumnItem | Array<number> | Array<string> | Array<ColumnItem>
66
+ >(),
67
+ /**
68
+ * 接收 pickerView 实例、选中项、当前修改列的下标、resolve 作为入参,根据选中项和列下标进行判断,通过 pickerView 实例暴露出来的 setColumnData 方法修改其他列的数据源。
69
+ */
70
+ columnChange: Function as PropType<PickerViewColumnChange>,
71
+ }
72
+
73
+ export type PickerViewExpose = {
74
+ getSelects: () => Record<string, any> | Record<string, any>[]
75
+ getValues: () => string | string[]
76
+ setColumnData: (
77
+ columnIndex: number,
78
+ data: Array<string | number | ColumnItem | Array<string | number | ColumnItem>>,
79
+ rowIndex?: number,
80
+ ) => void
81
+ getColumnsData: () => Record<string, string>[][]
82
+ getColumnData: (columnIndex: number) => Record<string, string>[]
83
+ getColumnIndex: (columnIndex: number) => number
84
+ getLabels: () => string[]
85
+ getSelectedIndex: () => number[]
86
+ }
87
+
88
+ export type PickerViewProps = ExtractPropTypes<typeof pickerViewProps>
89
+
90
+ export type PickerViewInstance = ComponentPublicInstance<PickerViewProps, PickerViewExpose>
91
+
92
+ /**
93
+ * 格式化传入的列数据
94
+ * 列数据统一格式化为二维数组
95
+ * @param array 列数据
96
+ * @param valueKey
97
+ * @param labelKey
98
+ * @returns
99
+ */
100
+ export function formatArray(
101
+ array: Array<string | number | ColumnItem | Array<string | number | ColumnItem>>,
102
+ valueKey: string,
103
+ labelKey: string,
104
+ ): ColumnItem[][] {
105
+ let tempArray: Array<string | number | ColumnItem | Array<string | number | ColumnItem>> =
106
+ isArray(array) ? array : [array]
107
+ // 判断数组第一层的数据类型,如果存在多种类型,则抛错
108
+ const firstLevelTypeList = new Set(array.map(getType))
109
+ /**
110
+ * 存在三种类型的合法数据
111
+ * 1.数组是一维元素,所有元素都是原始值
112
+ * 2.数组是一维元素,所有元素都是object
113
+ * 3.数组是二维元素,二维元素可以是任意内容
114
+ */
115
+ if (firstLevelTypeList.size !== 1 && firstLevelTypeList.has('object')) {
116
+ // 原始值和引用类型不用混用
117
+ throw Error('The columns are correct')
118
+ }
119
+ /**
120
+ * 简单处理,如果数组第一项不是数组则认为它是一个一维数组
121
+ * 所以需要把一维的转成二维,这样方便统一处理
122
+ */
123
+ if (!isArray(array[0])) {
124
+ tempArray = [tempArray as Array<string | number | ColumnItem>]
125
+ }
126
+ // 转化为二维数组后需要将每一项包装成ColumnItem
127
+ const result: Array<Array<ColumnItem>> = (
128
+ tempArray as Array<Array<string | number | ColumnItem>>
129
+ ).map((col) => {
130
+ return col.map((row) => {
131
+ // 非对象类型直接将值作为label和value
132
+ if (!isObj(row)) {
133
+ return {
134
+ [valueKey]: row,
135
+ [labelKey]: row,
136
+ }
137
+ }
138
+ /**
139
+ * 针对已经是object的,修补成{valueKey,labelKey}
140
+ * 如果没有labelKey,用valueKey代替
141
+ * 如果没有valueKey,用labelKey代替
142
+ * valueKey,labelKey都没有,直接抛错
143
+ */
144
+ // eslint-disable-next-line no-prototype-builtins
145
+ if (!row.hasOwnProperty(valueKey) && !row.hasOwnProperty(labelKey)) {
146
+ // eslint-disable-next-line prettier/prettier
147
+ throw Error("Can't find valueKey and labelKey in columns")
148
+ }
149
+ // eslint-disable-next-line no-prototype-builtins
150
+ if (!row.hasOwnProperty(labelKey)) {
151
+ row[labelKey] = row[valueKey]
152
+ }
153
+ // eslint-disable-next-line no-prototype-builtins
154
+ if (!row.hasOwnProperty(valueKey)) {
155
+ row[valueKey] = row[labelKey]
156
+ }
157
+ return row
158
+ })
159
+ })
160
+
161
+ return result
162
+ }
@@ -0,0 +1,361 @@
1
+ <template>
2
+ <view :class="`wd-picker-view ${customClass}`" :style="customStyle">
3
+ <view class="wd-picker-view__loading" v-if="loading">
4
+ <wd-loading :color="loadingColor" />
5
+ </view>
6
+ <view :style="`height: ${columnsHeight - 20}px;`">
7
+ <picker-view
8
+ mask-class="wd-picker-view__mask"
9
+ indicator-class="wd-picker-view__roller"
10
+ :indicator-style="`height: ${itemHeight}px;`"
11
+ :style="`height: ${columnsHeight - 20}px;`"
12
+ :value="selectedIndex"
13
+ :immediate-change="immediateChange"
14
+ @change="onChange"
15
+ @pickstart="onPickStart"
16
+ @pickend="onPickEnd"
17
+ >
18
+ <picker-view-column
19
+ v-for="(col, colIndex) in formatColumns"
20
+ :key="colIndex"
21
+ class="wd-picker-view-column"
22
+ >
23
+ <view
24
+ v-for="(row, rowIndex) in col"
25
+ :key="rowIndex"
26
+ :class="`wd-picker-view-column__item ${row['disabled'] ? 'wd-picker-view-column__item--disabled' : ''} ${
27
+ selectedIndex[colIndex] == rowIndex ? 'wd-picker-view-column__item--active' : ''
28
+ }`"
29
+ :style="`line-height: ${itemHeight}px;`"
30
+ >
31
+ {{ row[labelKey] }}
32
+ </view>
33
+ </picker-view-column>
34
+ </picker-view>
35
+ </view>
36
+ </view>
37
+ </template>
38
+
39
+ <script lang="ts">
40
+ export default {
41
+ name: 'wd-picker-view',
42
+ options: {
43
+ virtualHost: true,
44
+ addGlobalClass: true,
45
+ styleIsolation: 'shared',
46
+ },
47
+ }
48
+ </script>
49
+ <script lang="ts" setup>
50
+ import { getCurrentInstance, ref, watch, nextTick } from 'vue'
51
+ import { deepClone, getType, isArray, isDef, isEqual, range } from '../common/util'
52
+ import { formatArray, pickerViewProps, type ColumnItem, type PickerViewExpose } from './types'
53
+
54
+ const props = defineProps(pickerViewProps)
55
+ const emit = defineEmits(['change', 'pickstart', 'pickend', 'update:modelValue'])
56
+
57
+ const formatColumns = ref<ColumnItem[][]>([]) // 格式化后的列数据
58
+ const itemHeight = ref<number>(35)
59
+ const selectedIndex = ref<Array<number>>([]) // 格式化之后,每列选中的下标集合
60
+
61
+ watch(
62
+ [() => props.modelValue, () => props.columns],
63
+ (newValue, oldValue) => {
64
+ if (!isEqual(oldValue[1], newValue[1]) && isArray(newValue[1]) && newValue[1].length > 0) {
65
+ formatColumns.value = formatArray(newValue[1], props.valueKey, props.labelKey)
66
+ }
67
+ if (isDef(newValue[0])) {
68
+ selectWithValue(newValue[0])
69
+ }
70
+ },
71
+ {
72
+ deep: true,
73
+ immediate: true,
74
+ },
75
+ )
76
+
77
+ const { proxy } = getCurrentInstance() as any
78
+
79
+ /**
80
+ * 根据传入的value,寻找对应的索引,并传递给原生选择器。
81
+ * 需要保证formatColumns先设置,之后会修改selectedIndex。
82
+ * @param {String|Number|Boolean|Array<String|Number|Boolean|Array<any>>}value
83
+ */
84
+ function selectWithValue(value: string | number | boolean | number[] | string[] | boolean[]) {
85
+ if (formatColumns.value.length === 0) return
86
+ // 使其默认选中首项
87
+ if (value === '' || !isDef(value) || (isArray(value) && value.length === 0)) {
88
+ value = formatColumns.value.map((col) => {
89
+ return col[0][props.valueKey]
90
+ })
91
+ }
92
+ const valueType = getType(value)
93
+ const type = ['string', 'number', 'boolean', 'array']
94
+ if (type.indexOf(valueType) === -1) console.error(`value must be one of ${type.toString()}`)
95
+
96
+ /**
97
+ * 1.单key转为Array<key>
98
+ * 2.根据formatColumns的长度截取Array<String>,保证下面的遍历不溢出
99
+ * 3.根据每列的key值找到选项中value为此key的下标并记录
100
+ */
101
+ value = isArray(value) ? value : [value as string]
102
+ value = value.slice(0, formatColumns.value.length)
103
+
104
+ let selected: number[] = deepClone(selectedIndex.value)
105
+ value.forEach((target, col) => {
106
+ let row = formatColumns.value[col].findIndex((row) => {
107
+ return row[props.valueKey].toString() === target.toString()
108
+ })
109
+ row = row === -1 ? 0 : row
110
+ selected = correctSelectedIndex(col, row, selected)
111
+ })
112
+ /** 根据formatColumns的长度去除selectWithIndex无用的部分。
113
+ * 始终保持value、selectWithIndex、formatColumns长度一致
114
+ */
115
+ selectedIndex.value = selected.slice(0, value.length)
116
+ }
117
+
118
+ /**
119
+ * 修正选中项的值
120
+ * @param value 当前picker选择器选中的值
121
+ * @param origin 原始选中的值
122
+ */
123
+ function correctSelected(value: number[]) {
124
+ let selected = deepClone(value)
125
+ value.forEach((row, col) => {
126
+ row = range(row, 0, formatColumns.value[col].length - 1)
127
+ selected = correctSelectedIndex(col, row, selected)
128
+ })
129
+ return selected
130
+ }
131
+
132
+ /**
133
+ * 修正选中项指定列行的值
134
+ * @param columnIndex 列下标
135
+ * @param rowIndex 行下标
136
+ * @param selected 选中值列表
137
+ */
138
+ function correctSelectedIndex(columnIndex: number, rowIndex: number, selected: number[]) {
139
+ const col = formatColumns.value[columnIndex]
140
+ if (!col || !col[rowIndex]) {
141
+ throw Error(`The value to select with Col:${columnIndex} Row:${rowIndex} is incorrect`)
142
+ }
143
+ const select: number[] = deepClone(selected)
144
+ select[columnIndex] = rowIndex
145
+
146
+ // 被禁用的无法选中,选中距离它最近的未被禁用的
147
+ if (col[rowIndex].disabled) {
148
+ // 寻找值为0或最最近的未被禁用的节点的索引
149
+ const prev = col
150
+ .slice(0, rowIndex)
151
+ .reverse()
152
+ .findIndex((s) => !s.disabled)
153
+ const next = col.slice(rowIndex + 1).findIndex((s) => !s.disabled)
154
+ if (prev !== -1) {
155
+ select[columnIndex] = rowIndex - 1 - prev
156
+ } else if (next !== -1) {
157
+ select[columnIndex] = rowIndex + 1 + next
158
+ } else if (select[columnIndex] === undefined) {
159
+ select[columnIndex] = 0
160
+ }
161
+ }
162
+ return select
163
+ }
164
+
165
+ /**
166
+ * 选择器选中项变化时触发
167
+ * @param param0
168
+ */
169
+ function onChange({ detail: { value } }: { detail: { value: number[] } }) {
170
+ value = value.map((v: any) => {
171
+ return Number(v || 0)
172
+ })
173
+ const index = getChangeDiff(value)
174
+ // 先将picker选择器的值赋给selectedIndex,然后重新赋予修正后的值,防止两次操作修正结果一致时pikcer视图不刷新
175
+ selectedIndex.value = deepClone(value)
176
+ nextTick(() => {
177
+ // 重新赋予修正后的值
178
+ selectedIndex.value = correctSelected(value)
179
+ if (props.columnChange) {
180
+ // columnsChange 可能有异步操作,需要添加 resolve 进行回调通知,形参小于4个则为同步
181
+ if (props.columnChange.length < 4) {
182
+ props.columnChange(proxy.$.exposed, getSelects(), index || 0, () => {})
183
+ handleChange(index || 0)
184
+ } else {
185
+ props.columnChange(proxy.$.exposed, getSelects(), index || 0, () => {
186
+ // 如果selectedIndex只有一列,返回此项;如果是多项,返回所有选中项。
187
+ handleChange(index || 0)
188
+ })
189
+ }
190
+ } else {
191
+ // 如果selectedIndex只有一列,返回此项;如果是多项,返回所有选中项。
192
+ handleChange(index || 0)
193
+ }
194
+ })
195
+ }
196
+
197
+ /**
198
+ * 获取选中项变化的列的下标
199
+ * @param now 当前选中项值
200
+ * @param origin 旧选中项值
201
+ */
202
+ function getChangeColumn(now: number[], origin: number[]) {
203
+ if (!now || !origin) return -1
204
+ const index = now.findIndex((row, index) => row !== origin[index])
205
+ return index
206
+ }
207
+
208
+ function getChangeDiff(value: number[]) {
209
+ value = value.slice(0, formatColumns.value.length)
210
+
211
+ // 保留选中前的
212
+ const origin: number[] = deepClone(selectedIndex.value)
213
+ // 存储赋值旧值,便于外部比较
214
+ let selected: number[] = deepClone(selectedIndex.value)
215
+
216
+ value.forEach((row, col) => {
217
+ row = range(row, 0, formatColumns.value[col].length - 1)
218
+ if (row === origin[col]) return
219
+ selected = correctSelectedIndex(col, row, selected)
220
+ })
221
+
222
+ // 值变化的列
223
+ const diffCol = getChangeColumn(selected, origin)
224
+ if (diffCol === -1) return
225
+
226
+ // 获取变化的的行
227
+ const diffRow = selected[diffCol]
228
+
229
+ // 如果selectedIndex只有一列,返回选中项的索引;如果是多项,返回选中项所在的列。
230
+ return selected.length === 1 ? diffRow : diffCol
231
+ }
232
+
233
+ /**
234
+ * 列更新
235
+ * @param index 列下标
236
+ */
237
+ function handleChange(index: number) {
238
+ const value = getValues()
239
+
240
+ // 避免多次触发change
241
+ if (isEqual(value, props.modelValue)) return
242
+
243
+ emit('update:modelValue', value)
244
+ // 延迟一下,避免组件刚渲染时调用者的事件未初始化好
245
+ setTimeout(() => {
246
+ emit('change', {
247
+ picker: proxy.$.exposed,
248
+ value,
249
+ index,
250
+ })
251
+ }, 0)
252
+ }
253
+
254
+ /**
255
+ * @description 获取所有列选中项,返回值为一个数组
256
+ */
257
+ function getSelects() {
258
+ const selects = selectedIndex.value.map((row, col) => formatColumns.value[col][row])
259
+ // 单列选择器,则返回单项
260
+ if (selects.length === 1) {
261
+ return selects[0]
262
+ }
263
+ return selects
264
+ }
265
+
266
+ /**
267
+ * 获取所有列的选中值
268
+ * 如果values只有一项则将第一项返回
269
+ */
270
+ function getValues() {
271
+ const { valueKey } = props
272
+ const values = selectedIndex.value.map((row, col) => {
273
+ return formatColumns.value[col][row][valueKey]
274
+ })
275
+
276
+ if (values.length === 1) {
277
+ return values[0]
278
+ }
279
+ return values
280
+ }
281
+
282
+ /**
283
+ * 获取所有列选中项的label,返回值为一个数组
284
+ */
285
+ function getLabels() {
286
+ const { labelKey } = props
287
+ return selectedIndex.value.map((row, col) => formatColumns.value[col][row][labelKey])
288
+ }
289
+
290
+ /**
291
+ * 获取某一列的选中项下标
292
+ * @param {Number} columnIndex 列的下标
293
+ * @returns {Number} 下标
294
+ */
295
+ function getColumnIndex(columnIndex: number) {
296
+ return selectedIndex.value[columnIndex]
297
+ }
298
+
299
+ /**
300
+ * 获取某一列的选项
301
+ * @param {Number} columnIndex 列的下标
302
+ * @returns {Array<{valueKey,labelKey}>} 当前列的集合
303
+ */
304
+ function getColumnData(columnIndex: number) {
305
+ return formatColumns.value[columnIndex]
306
+ }
307
+
308
+ /**
309
+ * 设置列数据
310
+ * @param columnIndex 列下标
311
+ * @param data // 列数据
312
+ * @param rowIndex // 行下标
313
+ */
314
+ function setColumnData(
315
+ columnIndex: number,
316
+ data: Array<string | number | ColumnItem | Array<string | number | ColumnItem>>,
317
+ rowIndex: number = 0,
318
+ ) {
319
+ formatColumns.value[columnIndex] = formatArray(data, props.valueKey, props.labelKey).reduce(
320
+ (acc, val) => acc.concat(val),
321
+ [],
322
+ )
323
+ selectedIndex.value = correctSelectedIndex(columnIndex, rowIndex, selectedIndex.value)
324
+ }
325
+
326
+ /**
327
+ * 获取列数据
328
+ */
329
+ function getColumnsData() {
330
+ return deepClone(formatColumns.value)
331
+ }
332
+
333
+ /**
334
+ * 获取选中数据
335
+ */
336
+ function getSelectedIndex() {
337
+ return selectedIndex.value
338
+ }
339
+
340
+ function onPickStart() {
341
+ emit('pickstart')
342
+ }
343
+
344
+ function onPickEnd() {
345
+ emit('pickend')
346
+ }
347
+
348
+ defineExpose<PickerViewExpose>({
349
+ getSelects,
350
+ getValues,
351
+ setColumnData,
352
+ getColumnsData,
353
+ getColumnData,
354
+ getColumnIndex,
355
+ getLabels,
356
+ getSelectedIndex,
357
+ })
358
+ </script>
359
+ <style lang="scss" scoped>
360
+ @import './index';
361
+ </style>
@@ -0,0 +1,123 @@
1
+ @import './../common/abstracts/_mixin';
2
+ @import './../common/abstracts/variable';
3
+
4
+ .wot-theme-dark {
5
+ @include b(popover) {
6
+ @include e(pos) {
7
+ color: $-dark-color;
8
+ background: rgb(75, 76, 77);
9
+ box-shadow: 0px 2px 10px 0px rgba(75, 76, 77, 0.1);
10
+ }
11
+
12
+ @include e(menu) {
13
+ background: rgb(75, 76, 77);
14
+ }
15
+
16
+ @include e(inner) {
17
+ background-color: rgb(75, 76, 77);
18
+ }
19
+
20
+ @include e(menu-inner) {
21
+ @include halfPixelBorder('top', 0, $-dark-border-color);
22
+ }
23
+
24
+ @include squareArrow(
25
+ $-popover-arrow-size,
26
+ rgb(75, 76, 77),
27
+ $-popover-z-index - 1,
28
+ $-popover-arrow-box-shadow
29
+ );
30
+ }
31
+ }
32
+
33
+ @include b(popover) {
34
+ position: relative;
35
+ display: inline-block;
36
+
37
+ @include edeep(icon) {
38
+ margin-right: 5px;
39
+ font-size: 18px;
40
+ vertical-align: middle;
41
+ }
42
+
43
+ @include e(menu-inner) {
44
+ position: relative;
45
+ display: flex;
46
+ align-items: center;
47
+ padding: $-popover-padding 0;
48
+
49
+ @include halfPixelBorder('top', 0, $-popover-border-color);
50
+
51
+ &:first-child::after {
52
+ display: none;
53
+ }
54
+ }
55
+
56
+ @include e(menu) {
57
+ position: relative;
58
+ z-index: $-popover-z-index;
59
+ display: inline-block;
60
+ padding: 0 $-popover-padding;
61
+ white-space: nowrap;
62
+ background: $-popover-bg;
63
+ border-radius: $-popover-radius;
64
+ }
65
+
66
+ @include edeep(pos) {
67
+ position: absolute;
68
+ z-index: $-popover-z-index;
69
+ box-sizing: border-box;
70
+ min-height: 36px;
71
+ font-size: $-popover-fs;
72
+ line-height: $-popover-line-height;
73
+ color: $-popover-color;
74
+ text-align: center;
75
+ background: $-popover-bg;
76
+ background-clip: padding-box;
77
+ border-radius: $-popover-radius;
78
+ box-shadow: $-popover-box-shadow;
79
+ transition: opacity 0.2s;
80
+ }
81
+
82
+ // @include edeep(transition) {
83
+ // position: relative;
84
+ // z-index: $-popover-z-index;
85
+ // }
86
+
87
+ @include e(hidden) {
88
+ left: -100vw;
89
+ visibility: hidden;
90
+ }
91
+
92
+ @include e(container) {
93
+ position: relative;
94
+ font-size: $-tooltip-fs;
95
+ line-height: $-tooltip-line-height;
96
+ }
97
+
98
+ @include e(inner) {
99
+ position: relative;
100
+ z-index: $-popover-z-index;
101
+ padding: $-popover-padding;
102
+ line-height: $-popover-line-height;
103
+ white-space: nowrap;
104
+ background-color: $-popover-bg;
105
+ border-radius: $-popover-radius;
106
+ }
107
+
108
+ @include edeep(close-icon) {
109
+ position: absolute;
110
+ top: -10px;
111
+ right: -8px;
112
+ padding: 10px;
113
+ font-size: 12px;
114
+ transform: scale(0.5);
115
+ }
116
+
117
+ @include squareArrow(
118
+ $-popover-arrow-size,
119
+ $-popover-bg,
120
+ $-popover-z-index - 1,
121
+ $-popover-arrow-box-shadow
122
+ );
123
+ }
@@ -0,0 +1,69 @@
1
+ import type { ExtractPropTypes, PropType } from 'vue'
2
+ import { baseProps, makeBooleanProp, makeNumberProp, makeStringProp } from '../common/props'
3
+
4
+ export type PlacementType =
5
+ | 'top'
6
+ | 'top-start'
7
+ | 'top-end'
8
+ | 'bottom'
9
+ | 'bottom-start'
10
+ | 'bottom-end'
11
+ | 'left'
12
+ | 'left-start'
13
+ | 'left-end'
14
+ | 'right'
15
+ | 'right-start'
16
+ | 'right-end'
17
+
18
+ export type PopoverMode = 'menu' | 'normal'
19
+
20
+ export const popoverProps = {
21
+ ...baseProps,
22
+ customArrow: makeStringProp(''),
23
+ customPop: makeStringProp(''),
24
+ /**
25
+ * 是否显示 popover 箭头
26
+ */
27
+ visibleArrow: makeBooleanProp(true),
28
+ /**
29
+ * 显示的内容,也可以通过 slot#content 传入
30
+ */
31
+ content: [String, Object] as PropType<string | Record<string, any>[]>,
32
+ /**
33
+ * 指定 popover 的放置位置:top / top-start / top-end / bottom / bottom-start / bottom-end / left / left-start / left-end / right / right-start / right-end
34
+ */
35
+ placement: makeStringProp<PlacementType>('bottom'),
36
+ /**
37
+ * 偏移量
38
+ */
39
+ offset: makeNumberProp(0),
40
+ /**
41
+ * 是否使用内容插槽
42
+ */
43
+ useContentSlot: makeBooleanProp(false),
44
+ /**
45
+ * 是否禁用 popover
46
+ */
47
+ disabled: makeBooleanProp(false),
48
+ /**
49
+ * 是否显示关闭按钮
50
+ */
51
+ showClose: makeBooleanProp(false),
52
+ /**
53
+ * 控制 popover 的显示状态
54
+ */
55
+ modelValue: makeBooleanProp(false),
56
+ /**
57
+ * 当前显示的模式,决定内容的展现形式,可选值:normal(普通模式)/ menu(菜单模式)
58
+ */
59
+ mode: makeStringProp<PopoverMode>('normal'),
60
+ }
61
+
62
+ export type PopoverProps = ExtractPropTypes<typeof popoverProps>
63
+
64
+ export type PopoverExpose = {
65
+ // 打开popover
66
+ open: () => void
67
+ // 关闭popover
68
+ close: () => void
69
+ }