@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,827 @@
1
+ <template>
2
+ <view
3
+ :class="`wd-picker ${disabled ? 'is-disabled' : ''} ${size ? 'is-' + size : ''} ${cell.border.value ? 'is-border' : ''} ${
4
+ alignRight ? 'is-align-right' : ''
5
+ } ${error ? 'is-error' : ''} ${customClass}`"
6
+ :style="customStyle"
7
+ >
8
+ <!--文案-->
9
+ <view class="wd-picker__field" @click="showPopup">
10
+ <slot v-if="useDefaultSlot"></slot>
11
+ <view v-else :class="['wd-picker__cell', customCellClass]">
12
+ <view
13
+ v-if="label || useLabelSlot"
14
+ :class="`wd-picker__label ${customLabelClass} ${isRequired ? 'is-required' : ''}`"
15
+ :style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
16
+ >
17
+ <block v-if="label">{{ label }}</block>
18
+ <slot v-else name="label"></slot>
19
+ </view>
20
+ <view class="wd-picker__body">
21
+ <view class="wd-picker__value-wraper">
22
+ <view :class="`wd-picker__value ${customValueClass}`">
23
+ <template v-if="region">
24
+ <view v-if="isArray(showValue)">
25
+ <text :class="showValue[0] ? '' : 'wd-picker__placeholder'">
26
+ {{ showValue[0] ? showValue[0] : placeholder || translate('placeholder') }}
27
+ </text>
28
+ {{ translate('to') }}
29
+ <text :class="showValue[1] ? '' : 'wd-picker__placeholder'">
30
+ {{ showValue[1] ? showValue[1] : placeholder || translate('placeholder') }}
31
+ </text>
32
+ </view>
33
+ <view v-else class="wd-picker__placeholder">
34
+ {{ placeholder || translate('placeholder') }}
35
+ </view>
36
+ </template>
37
+ <view v-else :class="showValue ? '' : 'wd-picker__placeholder'">
38
+ {{ showValue ? showValue : placeholder || translate('placeholder') }}
39
+ </view>
40
+ </view>
41
+ <wd-icon
42
+ v-if="!disabled && !readonly"
43
+ custom-class="wd-picker__arrow"
44
+ name="arrow-right"
45
+ />
46
+ </view>
47
+ <view v-if="errorMessage" class="wd-picker__error-message">{{ errorMessage }}</view>
48
+ </view>
49
+ </view>
50
+ </view>
51
+ <!--弹出层,picker-view 在隐藏时修改值,会触发多次change事件,从而导致所有列选中第一项,因此picker在关闭时不隐藏 -->
52
+ <wd-popup
53
+ v-model="popupShow"
54
+ position="bottom"
55
+ :hide-when-close="false"
56
+ :close-on-click-modal="closeOnClickModal"
57
+ :safe-area-inset-bottom="safeAreaInsetBottom"
58
+ :z-index="zIndex"
59
+ @close="onCancel"
60
+ custom-class="wd-picker__popup"
61
+ >
62
+ <view class="wd-picker__wraper">
63
+ <!--toolBar-->
64
+ <view class="wd-picker__toolbar" @touchmove="noop">
65
+ <!--取消按钮-->
66
+ <view class="wd-picker__action wd-picker__action--cancel" @click="onCancel">
67
+ {{ cancelButtonText || translate('cancel') }}
68
+ </view>
69
+ <!--标题-->
70
+ <view v-if="title" class="wd-picker__title">{{ title }}</view>
71
+ <!--确定按钮-->
72
+ <view
73
+ :class="`wd-picker__action ${loading || isLoading ? 'is-loading' : ''}`"
74
+ @click="onConfirm"
75
+ >
76
+ {{ confirmButtonText || translate('confirm') }}
77
+ </view>
78
+ </view>
79
+ <!-- 区域选择tab展示 -->
80
+ <view v-if="region" class="wd-picker__region-tabs">
81
+ <view :class="`wd-picker__region ${showStart ? 'is-active' : ''} `" @click="tabChange">
82
+ <view>{{ translate('start') }}</view>
83
+ <view class="wd-picker__region-time">{{ showTabLabel[0] }}</view>
84
+ </view>
85
+ <view :class="`wd-picker__region ${showStart ? '' : 'is-active'}`" @click="tabChange">
86
+ <view>{{ translate('end') }}</view>
87
+ <view class="wd-picker__region-time">{{ showTabLabel[1] }}</view>
88
+ </view>
89
+ </view>
90
+ <!--datetimePickerView-->
91
+ <view :class="showStart ? 'wd-picker__show' : 'wd-picker__hidden'">
92
+ <wd-datetime-picker-view
93
+ :custom-class="customViewClass"
94
+ ref="datetimePickerView"
95
+ :type="type"
96
+ v-model="innerValue"
97
+ :loading="loading || isLoading"
98
+ :loading-color="loadingColor"
99
+ :columns-height="columnsHeight"
100
+ :value-key="valueKey"
101
+ :label-key="labelKey"
102
+ :formatter="formatter"
103
+ :filter="filter"
104
+ :column-formatter="isArray(modelValue) ? customColumnFormatter : undefined"
105
+ :max-hour="maxHour"
106
+ :min-hour="minHour"
107
+ :max-date="maxDate"
108
+ :min-date="minDate"
109
+ :max-minute="maxMinute"
110
+ :min-minute="minMinute"
111
+ :start-symbol="true"
112
+ :immediate-change="immediateChange"
113
+ @change="onChangeStart"
114
+ @pickstart="onPickStart"
115
+ @pickend="onPickEnd"
116
+ />
117
+ </view>
118
+ <view :class="showStart ? 'wd-picker__hidden' : 'wd-picker__show'">
119
+ <wd-datetime-picker-view
120
+ :custom-class="customViewClass"
121
+ ref="datetimePickerView1"
122
+ :type="type"
123
+ v-model="endInnerValue"
124
+ :loading="loading || isLoading"
125
+ :loading-color="loadingColor"
126
+ :columns-height="columnsHeight"
127
+ :value-key="valueKey"
128
+ :label-key="labelKey"
129
+ :formatter="formatter"
130
+ :filter="filter"
131
+ :column-formatter="isArray(modelValue) ? customColumnFormatter : undefined"
132
+ :max-hour="maxHour"
133
+ :min-hour="minHour"
134
+ :max-date="maxDate"
135
+ :min-date="minDate"
136
+ :max-minute="maxMinute"
137
+ :min-minute="minMinute"
138
+ :start-symbol="false"
139
+ :immediate-change="immediateChange"
140
+ @change="onChangeEnd"
141
+ @pickstart="onPickStart"
142
+ @pickend="onPickEnd"
143
+ />
144
+ </view>
145
+ </view>
146
+ </wd-popup>
147
+ </view>
148
+ </template>
149
+
150
+ <script lang="ts">
151
+ export default {
152
+ name: 'wd-datetime-picker',
153
+ options: {
154
+ virtualHost: true,
155
+ addGlobalClass: true,
156
+ styleIsolation: 'shared',
157
+ },
158
+ }
159
+ </script>
160
+
161
+ <script lang="ts" setup>
162
+ import { computed, getCurrentInstance, nextTick, onBeforeMount, onMounted, ref, watch } from 'vue'
163
+ import { deepClone, isArray, isDef, isEqual, isFunction, padZero } from '../common/util'
164
+ import { useCell } from '../composables/useCell'
165
+ import {
166
+ getPickerValue,
167
+ type DatetimePickerViewInstance,
168
+ type DatetimePickerViewColumnFormatter,
169
+ type DatetimePickerViewColumnType,
170
+ } from '../wd-datetime-picker-view/types'
171
+ import { FORM_KEY, type FormItemRule } from '../wd-form/types'
172
+ import { useParent } from '../composables/useParent'
173
+ import { useTranslate } from '../composables/useTranslate'
174
+ import { datetimePickerProps, type DatetimePickerExpose } from './types'
175
+
176
+ const props = defineProps(datetimePickerProps)
177
+ const emit = defineEmits(['change', 'open', 'toggle', 'cancel', 'confirm', 'update:modelValue'])
178
+
179
+ const { translate } = useTranslate('datetime-picker')
180
+
181
+ const datetimePickerView = ref<DatetimePickerViewInstance>()
182
+ const datetimePickerView1 = ref<DatetimePickerViewInstance>()
183
+
184
+ const showValue = ref<string | Date | Array<string | Date>>('')
185
+ const popupShow = ref<boolean>(false)
186
+ const showStart = ref<boolean>(true)
187
+ const region = ref<boolean>(false)
188
+ const showTabLabel = ref<string[]>([])
189
+ const innerValue = ref<string | number>('')
190
+ const endInnerValue = ref<string | number>('')
191
+
192
+ const isPicking = ref<boolean>(false) // 判断pickview是否还在滑动中
193
+ const hasConfirmed = ref<boolean>(false) // 判断用户是否点击了确认按钮
194
+
195
+ const isLoading = ref<boolean>(false) // 加载
196
+ const { proxy } = getCurrentInstance() as any
197
+
198
+ const cell = useCell()
199
+
200
+ watch(
201
+ () => props.modelValue,
202
+ (val, oldVal) => {
203
+ if (isEqual(val, oldVal)) return
204
+
205
+ if (isArray(val)) {
206
+ region.value = true
207
+ innerValue.value = deepClone(getDefaultInnerValue(true))
208
+ endInnerValue.value = deepClone(getDefaultInnerValue(true, true))
209
+ } else {
210
+ // 每次value更新时都需要刷新整个列表
211
+ innerValue.value = deepClone(getDefaultInnerValue())
212
+ }
213
+ nextTick(() => {
214
+ setShowValue(false, false, true)
215
+ })
216
+ },
217
+ {
218
+ deep: true,
219
+ immediate: true,
220
+ },
221
+ )
222
+
223
+ watch(
224
+ () => props.displayFormat,
225
+ (fn) => {
226
+ if (fn && !isFunction(fn)) {
227
+ console.error('The type of displayFormat must be Function')
228
+ }
229
+ },
230
+ {
231
+ deep: true,
232
+ immediate: true,
233
+ },
234
+ )
235
+ watch(
236
+ () => props.filter,
237
+ (fn) => {
238
+ if (fn && !isFunction(fn)) {
239
+ console.error('The type of filter must be Function')
240
+ }
241
+ },
242
+ {
243
+ deep: true,
244
+ immediate: true,
245
+ },
246
+ )
247
+ watch(
248
+ () => props.formatter,
249
+ (fn) => {
250
+ if (fn && !isFunction(fn)) {
251
+ console.error('The type of formatter must be Function')
252
+ }
253
+ },
254
+ {
255
+ deep: true,
256
+ immediate: true,
257
+ },
258
+ )
259
+ watch(
260
+ () => props.beforeConfirm,
261
+ (fn) => {
262
+ if (fn && !isFunction(fn)) {
263
+ console.error('The type of beforeConfirm must be Function')
264
+ }
265
+ },
266
+ {
267
+ deep: true,
268
+ immediate: true,
269
+ },
270
+ )
271
+ watch(
272
+ () => props.displayFormatTabLabel,
273
+ (fn) => {
274
+ if (fn && !isFunction(fn)) {
275
+ console.error('The type of displayFormatTabLabel must be Function')
276
+ }
277
+ },
278
+ {
279
+ deep: true,
280
+ immediate: true,
281
+ },
282
+ )
283
+
284
+ watch(
285
+ () => props.defaultValue,
286
+ (val) => {
287
+ if (isArray(val) || region.value) {
288
+ innerValue.value = deepClone(getDefaultInnerValue(true))
289
+ endInnerValue.value = deepClone(getDefaultInnerValue(true, true))
290
+ } else {
291
+ innerValue.value = deepClone(getDefaultInnerValue())
292
+ }
293
+ },
294
+ {
295
+ deep: true,
296
+ immediate: true,
297
+ },
298
+ )
299
+
300
+ const { parent: form } = useParent(FORM_KEY)
301
+
302
+ // 表单校验错误信息
303
+ const errorMessage = computed(() => {
304
+ if (form && props.prop && form.errorMessages && form.errorMessages[props.prop]) {
305
+ return form.errorMessages[props.prop]
306
+ } else {
307
+ return ''
308
+ }
309
+ })
310
+
311
+ // 是否展示必填
312
+ const isRequired = computed(() => {
313
+ let formRequired = false
314
+ if (form && form.props.rules) {
315
+ const rules = form.props.rules
316
+ for (const key in rules) {
317
+ if (
318
+ Object.prototype.hasOwnProperty.call(rules, key) &&
319
+ key === props.prop &&
320
+ Array.isArray(rules[key])
321
+ ) {
322
+ formRequired = rules[key].some((rule: FormItemRule) => rule.required)
323
+ }
324
+ }
325
+ }
326
+ return props.required || props.rules.some((rule) => rule.required) || formRequired
327
+ })
328
+
329
+ /**
330
+ * @description 自定义列项筛选规则,对每列单项进行禁用校验,最终返回传入PickerView的columns数组
331
+ * @param {Component} picker datetimePickerView对象
332
+ * @return {Array} columns
333
+ */
334
+ const customColumnFormatter: DatetimePickerViewColumnFormatter = (picker) => {
335
+ if (!picker) {
336
+ return []
337
+ }
338
+ const { type } = props
339
+ const { startSymbol, formatter } = picker
340
+ // 校准上下方picker的value值,与内部innerValue对应
341
+ const start = picker.correctValue(innerValue.value)
342
+ const end = picker.correctValue(endInnerValue.value)
343
+
344
+ /**
345
+ * 如果是上方picekr 那么将下方picker的值作为下边界
346
+ * 如果是下方picekr 那么将上方picker的值作为上边界
347
+ */
348
+ const currentValue = startSymbol
349
+ ? picker.getPickerValue(start, type)
350
+ : picker.getPickerValue(end, type)
351
+ const boundary = startSymbol
352
+ ? picker.getPickerValue(end, type)
353
+ : picker.getPickerValue(start, type)
354
+ // 获取当前picekr中的源列数组
355
+ const columns = picker.getOriginColumns()
356
+
357
+ // 此时index是最外层知道当前的索引即可得到当前是哪个时间段
358
+ return columns.map((column, cIndex) => {
359
+ return column.values.map((value) => {
360
+ const disabled = columnDisabledRules(
361
+ startSymbol,
362
+ columns,
363
+ cIndex,
364
+ value,
365
+ currentValue,
366
+ boundary,
367
+ )
368
+ return {
369
+ label: formatter ? formatter(column.type, padZero(value)) : padZero(value),
370
+ value,
371
+ disabled,
372
+ }
373
+ })
374
+ })
375
+ }
376
+
377
+ onBeforeMount(() => {
378
+ const { modelValue: value } = props
379
+ if (isArray(value)) {
380
+ region.value = true
381
+ innerValue.value = deepClone(getDefaultInnerValue(true))
382
+ endInnerValue.value = deepClone(getDefaultInnerValue(true, true))
383
+ } else {
384
+ innerValue.value = deepClone(getDefaultInnerValue())
385
+ }
386
+ })
387
+
388
+ onMounted(() => {
389
+ setShowValue(false, false, true)
390
+ })
391
+
392
+ /**
393
+ * @description 根据传入的picker,picker组件获取当前cell展示值。
394
+ */
395
+ function getSelects(picker: 'before' | 'after') {
396
+ const value = picker === 'before' ? innerValue.value : endInnerValue.value
397
+ let selected: number[] = []
398
+ if (value) {
399
+ selected = getPickerValue(value, props.type)
400
+ }
401
+
402
+ const selects = selected.map((value) => {
403
+ return {
404
+ [props.labelKey]: padZero(value),
405
+ [props.valueKey]: value,
406
+ }
407
+ })
408
+ return selects
409
+ }
410
+
411
+ function noop() {}
412
+
413
+ function getDefaultInnerValue(isRegion?: boolean, isEnd?: boolean): string | number {
414
+ const { modelValue: value, defaultValue } = props
415
+
416
+ if (isRegion) {
417
+ if (isEnd) {
418
+ return (
419
+ (isArray(value) ? (value[1] as string) : '') ||
420
+ (defaultValue && isArray(defaultValue) ? (defaultValue[1] as string) : '') ||
421
+ props.maxDate
422
+ )
423
+ } else {
424
+ return (
425
+ (isArray(value) ? (value[0] as string) : '') ||
426
+ (defaultValue && isArray(defaultValue) ? (defaultValue[0] as string) : '') ||
427
+ props.minDate
428
+ )
429
+ }
430
+ } else {
431
+ return isDef(value || defaultValue) ? (value as string) || (defaultValue as string) : ''
432
+ }
433
+ }
434
+
435
+ // 对外暴露接口,打开弹框
436
+ function open() {
437
+ showPopup()
438
+ }
439
+
440
+ // 对外暴露接口,关闭弹框
441
+ function close() {
442
+ onCancel()
443
+ }
444
+
445
+ /**
446
+ * @description 展示popup,小程序有个bug,在picker-view弹出时设置value,会触发change事件,而且会将picker-view的value多次触发change重置为第一项
447
+ */
448
+ function showPopup() {
449
+ if (props.disabled || props.readonly) return
450
+
451
+ emit('open')
452
+ if (region.value) {
453
+ popupShow.value = true
454
+ showStart.value = true
455
+ innerValue.value = deepClone(getDefaultInnerValue(true, false))
456
+ endInnerValue.value = deepClone(getDefaultInnerValue(true, true))
457
+ } else {
458
+ popupShow.value = true
459
+ innerValue.value = deepClone(getDefaultInnerValue())
460
+ }
461
+ setShowValue(true, false, true)
462
+ }
463
+
464
+ /**
465
+ * @description 区域选择时tab标签切换时触发
466
+ */
467
+ function tabChange() {
468
+ showStart.value = !showStart.value
469
+ // 列项刷新多级联动挂载到datetimepickerView
470
+ const picker = showStart.value ? datetimePickerView.value : datetimePickerView1.value
471
+ picker!.setColumns(picker!.updateColumns())
472
+
473
+ emit('toggle', showStart.value ? innerValue.value : endInnerValue.value)
474
+ }
475
+
476
+ /**
477
+ * @description datetimePickerView change 事件
478
+ */
479
+ function onChangeStart({ value }: { value: number | string }) {
480
+ innerValue.value = deepClone(value)
481
+ if (region.value) {
482
+ showTabLabel.value = [setTabLabel(), deepClone(showTabLabel.value[1])]
483
+ emit('change', {
484
+ value: [value, endInnerValue.value],
485
+ })
486
+ datetimePickerView.value &&
487
+ datetimePickerView.value.setColumns(datetimePickerView.value.updateColumns())
488
+ datetimePickerView1.value &&
489
+ datetimePickerView1.value.setColumns(datetimePickerView1.value.updateColumns())
490
+ } else {
491
+ emit('change', {
492
+ value: innerValue.value,
493
+ })
494
+ }
495
+ }
496
+
497
+ /**
498
+ * @description 区域选择 下方 datetimePickerView change 事件
499
+ */
500
+ function onChangeEnd({ value }: { value: number | string }) {
501
+ endInnerValue.value = deepClone(value)
502
+ showTabLabel.value = [deepClone(showTabLabel.value[0]), setTabLabel(1)]
503
+ emit('change', {
504
+ value: [innerValue.value, value],
505
+ })
506
+ datetimePickerView.value &&
507
+ datetimePickerView.value.setColumns(datetimePickerView.value.updateColumns())
508
+ datetimePickerView1.value &&
509
+ datetimePickerView1.value.setColumns(datetimePickerView1.value.updateColumns())
510
+ }
511
+
512
+ /**
513
+ * @description 点击取消按钮触发。关闭popup,触发cancel事件。
514
+ */
515
+ function onCancel() {
516
+ popupShow.value = false
517
+ setTimeout(() => {
518
+ if (region.value) {
519
+ innerValue.value = deepClone(getDefaultInnerValue(true))
520
+ endInnerValue.value = deepClone(getDefaultInnerValue(true, true))
521
+ } else {
522
+ innerValue.value = deepClone(getDefaultInnerValue())
523
+ }
524
+ }, 200)
525
+
526
+ emit('cancel')
527
+ }
528
+
529
+ /** picker触发confirm事件,同步触发confirm事件 */
530
+ function onConfirm() {
531
+ if (props.loading || isLoading.value) return
532
+
533
+ // 如果当前还在滑动且未停止下来,则锁住先不确认,等滑完再自动确认,避免pickview值未更新
534
+ if (isPicking.value) {
535
+ hasConfirmed.value = true
536
+ return
537
+ }
538
+
539
+ const { beforeConfirm } = props
540
+ if (beforeConfirm) {
541
+ beforeConfirm(
542
+ region.value ? [innerValue.value, endInnerValue.value] : innerValue.value,
543
+ (isPass: boolean) => {
544
+ isPass && handleConfirm()
545
+ },
546
+ proxy.$.exposed,
547
+ )
548
+ } else {
549
+ handleConfirm()
550
+ }
551
+ }
552
+
553
+ function onPickStart() {
554
+ isPicking.value = true
555
+ }
556
+
557
+ function onPickEnd() {
558
+ isPicking.value = false
559
+
560
+ // 延迟一会,因为组件层级嵌套过多,日期的计算时间也较长
561
+ setTimeout(() => {
562
+ if (hasConfirmed.value) {
563
+ hasConfirmed.value = false
564
+ onConfirm()
565
+ }
566
+ }, 50)
567
+ }
568
+
569
+ function handleConfirm() {
570
+ if (props.loading || isLoading.value || props.disabled) {
571
+ popupShow.value = false
572
+ return
573
+ }
574
+ const value = region.value ? [innerValue.value, endInnerValue.value] : innerValue.value
575
+ popupShow.value = false
576
+ emit('update:modelValue', value)
577
+ emit('confirm', {
578
+ value,
579
+ })
580
+ setShowValue(false, true)
581
+ }
582
+
583
+ /**
584
+ * @description 设置区域选择 tab 标签展示值
585
+ * @param {Number} index 索引标志位,有三个有效值; 0(默认):上方picker索引; 1:下方picker索引;
586
+ * @return {String} showTabLabel
587
+ */
588
+ function setTabLabel(index: number = 0) {
589
+ if (region.value) {
590
+ let items: Record<string, any>[] = []
591
+ if (index === 0) {
592
+ items = ((datetimePickerView.value ? datetimePickerView.value!.getSelects() : undefined) ||
593
+ (innerValue.value && getSelects('before'))) as Record<string, any>[]
594
+ } else {
595
+ items = ((datetimePickerView1.value ? datetimePickerView1.value!.getSelects() : undefined) ||
596
+ (endInnerValue.value && getSelects('after'))) as Record<string, any>[]
597
+ }
598
+ return defaultDisplayFormat(items, true)
599
+ } else {
600
+ return ''
601
+ }
602
+ }
603
+
604
+ /**
605
+ * @description 设置展示值
606
+ * @param {Boolean} tab 是否修改tab展示值(尽在区域选择情况下生效)
607
+ * @param {Boolean} isConfirm 是否提交当前修改
608
+ */
609
+ function setShowValue(
610
+ tab: boolean = false,
611
+ isConfirm: boolean = false,
612
+ beforeMount: boolean = false,
613
+ ) {
614
+ if (region.value) {
615
+ const items = beforeMount
616
+ ? (innerValue.value && getSelects('before')) || []
617
+ : (datetimePickerView.value &&
618
+ datetimePickerView.value.getSelects &&
619
+ datetimePickerView.value.getSelects()) ||
620
+ []
621
+
622
+ const endItems = beforeMount
623
+ ? (endInnerValue.value && getSelects('after')) || []
624
+ : (datetimePickerView1.value &&
625
+ datetimePickerView1.value.getSelects &&
626
+ datetimePickerView1.value.getSelects()) ||
627
+ []
628
+
629
+ showValue.value = tab
630
+ ? showValue.value
631
+ : [
632
+ (props.modelValue as (string | number)[])[0] || isConfirm
633
+ ? defaultDisplayFormat(items as Record<string, any>[])
634
+ : '',
635
+ (props.modelValue as (string | number)[])[1] || isConfirm
636
+ ? defaultDisplayFormat(endItems as Record<string, any>[])
637
+ : '',
638
+ ]
639
+ showTabLabel.value = [
640
+ defaultDisplayFormat(items as Record<string, any>[], true),
641
+ defaultDisplayFormat(endItems as Record<string, any>[], true),
642
+ ]
643
+ } else {
644
+ const items = beforeMount
645
+ ? (innerValue.value && getSelects('before')) || []
646
+ : (datetimePickerView.value &&
647
+ datetimePickerView.value.getSelects &&
648
+ datetimePickerView.value.getSelects()) ||
649
+ []
650
+
651
+ showValue.value = deepClone(
652
+ props.modelValue || isConfirm ? defaultDisplayFormat(items as Record<string, any>[]) : '',
653
+ )
654
+ }
655
+ }
656
+
657
+ /**
658
+ * @description 设置展示值
659
+ * @param {Object} items 获取到的选中项 包含 { value, label }
660
+ * @param {Boolean} tabLabel 当前返回的是否是展示tab上的标签
661
+ * @return {String} showValue / showTabLabel
662
+ */
663
+ function defaultDisplayFormat(items: Record<string, any>[], tabLabel: boolean = false) {
664
+ if (items.length === 0) return ''
665
+
666
+ if (tabLabel && props.displayFormatTabLabel) {
667
+ return props.displayFormatTabLabel(items)
668
+ }
669
+
670
+ if (props.displayFormat) {
671
+ return props.displayFormat(items)
672
+ }
673
+
674
+ // 如果使用了自定义的的formatter,defaultDisplayFormat无效
675
+ if (props.formatter) {
676
+ /**
677
+ * 不建议使用 this.picker.picker.getLabels() 拉取
678
+ * 在初始展示时,需要使用模拟 nextTick 来等待内部 pickerView 渲染后labels才可得到format后的labels
679
+ * 但使用模拟nextTick会造成页面延迟展示问题,对用户感知来讲不友好,因此不适用该方法
680
+ */
681
+ const typeMaps = {
682
+ year: ['year'],
683
+ datetime: ['year', 'month', 'date', 'hour', 'minute'],
684
+ date: ['year', 'month', 'date'],
685
+ time: ['hour', 'minute'],
686
+ 'year-month': ['year', 'month'],
687
+ }
688
+ return items
689
+ .map((item, index) => {
690
+ return props.formatter!(typeMaps[props.type][index], item.value)
691
+ })
692
+ .join('')
693
+ }
694
+
695
+ switch (props.type) {
696
+ case 'year':
697
+ return items[0].label
698
+ case 'date':
699
+ return `${items[0].label}-${items[1].label}-${items[2].label}`
700
+ case 'year-month':
701
+ return `${items[0].label}-${items[1].label}`
702
+ case 'time':
703
+ return `${items[0].label}:${items[1].label}`
704
+ case 'datetime':
705
+ return `${items[0].label}-${items[1].label}-${items[2].label} ${items[3].label}:${items[4].label}`
706
+ }
707
+ }
708
+
709
+ /**
710
+ * @description 区域选择time禁用规则,根据传入的位置标志以及日期类型 返回该节点是否禁用
711
+ * @param {Boolean} isStart 时间段类型 true:start | false:end
712
+ * @param {Array} column 当前遍历到的列数组
713
+ * @param {Number} cindex 外层column的索引(对应每一个类型)
714
+ * @param {Number / String} value 遍历到的当前值
715
+ * @param {Array} currentValue 当前选中的值 this.pickerValue
716
+ * @param {Array} boundary 当前变量的限制值,决定禁用的边界值
717
+ * @return {Boolean} disabled
718
+ */
719
+ function columnDisabledRules(
720
+ isStart: boolean,
721
+ columns: {
722
+ type: DatetimePickerViewColumnType
723
+ values: number[]
724
+ }[],
725
+ cIndex: number,
726
+ value: number,
727
+ currentValue: number[],
728
+ boundary: number[],
729
+ ) {
730
+ const { type } = props
731
+ // 0年 1月 2日 3時 4分
732
+ // startPicker 除最小值外 还需要有一个时间限制, endPicker 时间选择后, startPicker 的 添加一个时间限制boundary min->boundary
733
+ // endPicker 除最小值外 还需要有一个时间限制, startPicker 时间选择后, endPicker 的 添加一个时间限制boundary boundary->max
734
+ const column = columns[cIndex]
735
+ // 根据当前选择年确认 ranges[0][0] minYear ranges[0][1] maxYear 以此类推
736
+ if (type === 'datetime') {
737
+ const year = boundary[0]
738
+ const month = boundary[1]
739
+ const date = boundary[2]
740
+ const hour = boundary[3]
741
+ const minute = boundary[4]
742
+
743
+ if (column.type === 'year') {
744
+ return isStart ? value > year : value < year
745
+ }
746
+ if (column.type === 'month' && currentValue[0] === year) {
747
+ return isStart ? value > month : value < month
748
+ }
749
+ if (column.type === 'date' && currentValue[0] === year && currentValue[1] === month) {
750
+ return isStart ? value > date : value < date
751
+ }
752
+ if (
753
+ column.type === 'hour' &&
754
+ currentValue[0] === year &&
755
+ currentValue[1] === month &&
756
+ currentValue[2] === date
757
+ ) {
758
+ return isStart ? value > hour : value < hour
759
+ }
760
+ if (
761
+ column.type === 'minute' &&
762
+ currentValue[0] === year &&
763
+ currentValue[1] === month &&
764
+ currentValue[2] === date &&
765
+ currentValue[3] === hour
766
+ ) {
767
+ return isStart ? value > minute : value < minute
768
+ }
769
+ } else if (type === 'year-month') {
770
+ const year = boundary[0]
771
+ const month = boundary[1]
772
+
773
+ if (column.type === 'year') {
774
+ return isStart ? value > year : value < year
775
+ }
776
+ if (column.type === 'month' && currentValue[0] === year) {
777
+ return isStart ? value > month : value < month
778
+ }
779
+ } else if (type === 'year') {
780
+ const year = boundary[0]
781
+
782
+ if (column.type === 'year') {
783
+ return isStart ? value > year : value < year
784
+ }
785
+ } else if (type === 'date') {
786
+ const year = boundary[0]
787
+ const month = boundary[1]
788
+ const date = boundary[2]
789
+
790
+ if (column.type === 'year') {
791
+ return isStart ? value > year : value < year
792
+ }
793
+ if (column.type === 'month' && currentValue[0] === year) {
794
+ return isStart ? value > month : value < month
795
+ }
796
+ if (column.type === 'date' && currentValue[0] === year && currentValue[1] === month) {
797
+ return isStart ? value > date : value < date
798
+ }
799
+ } else if (type === 'time') {
800
+ const hour = boundary[0]
801
+ const minute = boundary[1]
802
+
803
+ if (column.type === 'hour') {
804
+ return isStart ? value > hour : value < hour
805
+ }
806
+ if (column.type === 'minute' && currentValue[0] === hour) {
807
+ return isStart ? value > minute : value < minute
808
+ }
809
+ }
810
+
811
+ return false
812
+ }
813
+
814
+ function setLoading(loading: boolean) {
815
+ isLoading.value = loading
816
+ }
817
+
818
+ defineExpose<DatetimePickerExpose>({
819
+ open,
820
+ close,
821
+ setLoading,
822
+ })
823
+ </script>
824
+
825
+ <style lang="scss" scoped>
826
+ @import './index.scss';
827
+ </style>