@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,388 @@
1
+ <template>
2
+ <view class="wd-month-panel">
3
+ <view v-if="showPanelTitle" class="wd-month-panel__title">
4
+ {{ title }}
5
+ </view>
6
+ <view class="wd-month-panel__weeks">
7
+ <view v-for="item in 7" :key="item" class="wd-month-panel__week">
8
+ {{ weekLabel(item + firstDayOfWeek) }}
9
+ </view>
10
+ </view>
11
+ <scroll-view
12
+ :class="`wd-month-panel__container ${!!timeType ? 'wd-month-panel__container--time' : ''}`"
13
+ :style="`height: ${scrollHeight}px`"
14
+ scroll-y
15
+ @scroll="monthScroll"
16
+ :scroll-top="scrollTop"
17
+ >
18
+ <view v-for="(item, index) in months" :key="index" :id="`month${index}`">
19
+ <month
20
+ :type="type"
21
+ :date="item.date"
22
+ :value="value"
23
+ :min-date="minDate"
24
+ :max-date="maxDate"
25
+ :first-day-of-week="firstDayOfWeek"
26
+ :formatter="formatter"
27
+ :max-range="maxRange"
28
+ :range-prompt="rangePrompt"
29
+ :allow-same-day="allowSameDay"
30
+ :default-time="defaultTime"
31
+ @change="handleDateChange"
32
+ />
33
+ </view>
34
+ </scroll-view>
35
+ <view v-if="timeType" class="wd-month-panel__time">
36
+ <view v-if="type === 'datetimerange'" class="wd-month-panel__time-label">
37
+ <view class="wd-month-panel__time-text">
38
+ {{ timeType === 'start' ? translate('startTime') : translate('endTime') }}
39
+ </view>
40
+ </view>
41
+ <view class="wd-month-panel__time-picker">
42
+ <wd-picker-view
43
+ v-if="timeData.length"
44
+ v-model="timeValue"
45
+ :columns="timeData"
46
+ :columns-height="125"
47
+ :immediate-change="immediateChange"
48
+ @change="handleTimeChange"
49
+ @pickstart="handlePickStart"
50
+ @pickend="handlePickEnd"
51
+ />
52
+ </view>
53
+ </view>
54
+ </view>
55
+ </template>
56
+
57
+ <script lang="ts">
58
+ export default {
59
+ options: {
60
+ addGlobalClass: true,
61
+ virtualHost: true,
62
+ styleIsolation: 'shared',
63
+ },
64
+ }
65
+ </script>
66
+
67
+ <script lang="ts" setup>
68
+ import { computed, ref, watch, onMounted } from 'vue'
69
+ import { debounce, isArray, isEqual, isNumber, requestAnimationFrame } from '../../common/util'
70
+ import {
71
+ compareMonth,
72
+ formatMonthTitle,
73
+ getMonthEndDay,
74
+ getMonths,
75
+ getTimeData,
76
+ getWeekLabel,
77
+ } from '../utils'
78
+ import Month from '../month/month.vue'
79
+ import {
80
+ monthPanelProps,
81
+ type MonthInfo,
82
+ type MonthPanelTimeType,
83
+ type MonthPanelExpose,
84
+ } from './types'
85
+ import { useTranslate } from '../../composables/useTranslate'
86
+ import type { CalendarItem } from '../types'
87
+
88
+ const props = defineProps(monthPanelProps)
89
+ const emit = defineEmits(['change', 'pickstart', 'pickend'])
90
+
91
+ const { translate } = useTranslate('calendar-view')
92
+
93
+ const scrollTop = ref<number>(0) // 滚动位置
94
+ const scrollIndex = ref<number>(0) // 当前显示的月份索引
95
+ const timeValue = ref<number[]>([]) // 当前选中的时分秒
96
+
97
+ const timeType = ref<MonthPanelTimeType>('') // 当前时间类型,是开始还是结束
98
+ const innerValue = ref<string | number | (number | null)[]>('') // 内部保存一个值,用于判断新老值,避免监听器触发
99
+
100
+ const handleChange = debounce((value) => {
101
+ emit('change', {
102
+ value,
103
+ })
104
+ }, 50)
105
+
106
+ // 时间picker的列数据
107
+ const timeData = computed<Array<CalendarItem[]>>(() => {
108
+ let timeColumns: Array<CalendarItem[]> = []
109
+ if (props.type === 'datetime' && isNumber(props.value)) {
110
+ const date = new Date(props.value)
111
+ date.setHours(timeValue.value[0])
112
+ date.setMinutes(timeValue.value[1])
113
+ date.setSeconds(props.hideSecond ? 0 : timeValue.value[2])
114
+ const dateTime = date.getTime()
115
+ timeColumns = getTime(dateTime) || []
116
+ } else if (isArray(props.value) && props.type === 'datetimerange') {
117
+ const [start, end] = props.value!
118
+ const dataValue = timeType.value === 'start' ? start : end
119
+ const date = new Date(dataValue || '')
120
+ date.setHours(timeValue.value[0])
121
+ date.setMinutes(timeValue.value[1])
122
+ date.setSeconds(props.hideSecond ? 0 : timeValue.value[2])
123
+ const dateTime = date.getTime()
124
+ const finalValue = [start, end]
125
+ if (timeType.value === 'start') {
126
+ finalValue[0] = dateTime
127
+ } else {
128
+ finalValue[1] = dateTime
129
+ }
130
+ timeColumns = getTime(finalValue, timeType.value) || []
131
+ }
132
+ return timeColumns
133
+ })
134
+
135
+ // 标题
136
+ const title = computed(() => {
137
+ return formatMonthTitle(months.value[scrollIndex.value].date)
138
+ })
139
+
140
+ // 周标题
141
+ const weekLabel = computed(() => {
142
+ return (index: number) => {
143
+ return getWeekLabel(index - 1)
144
+ }
145
+ })
146
+
147
+ // 滚动区域的高度
148
+ const scrollHeight = computed(() => {
149
+ const scrollHeight: number = timeType.value
150
+ ? (props.panelHeight || 378) - 125
151
+ : props.panelHeight || 378
152
+ return scrollHeight
153
+ })
154
+
155
+ // 月份日期和月份高度
156
+ const months = computed<MonthInfo[]>(() => {
157
+ return getMonths(props.minDate, props.maxDate).map((month) => {
158
+ const offset = (7 + new Date(month).getDay() - props.firstDayOfWeek) % 7
159
+ const totalDay = getMonthEndDay(new Date(month).getFullYear(), new Date(month).getMonth() + 1)
160
+ return {
161
+ height: (offset + totalDay > 35 ? 64 * 6 : 64 * 5) + 45,
162
+ date: month,
163
+ }
164
+ })
165
+ })
166
+
167
+ watch(
168
+ () => props.type,
169
+ (val) => {
170
+ if (
171
+ (val === 'datetime' && props.value) ||
172
+ (val === 'datetimerange' &&
173
+ isArray(props.value) &&
174
+ props.value &&
175
+ props.value.length > 0 &&
176
+ props.value[0])
177
+ ) {
178
+ setTime(props.value, 'start')
179
+ }
180
+ },
181
+ {
182
+ deep: true,
183
+ immediate: true,
184
+ },
185
+ )
186
+
187
+ watch(
188
+ () => props.value,
189
+ (val) => {
190
+ if (isEqual(val, innerValue.value)) return
191
+
192
+ if (
193
+ (props.type === 'datetime' && val) ||
194
+ (props.type === 'datetimerange' && val && isArray(val) && val.length > 0 && val[0])
195
+ ) {
196
+ setTime(val, 'start')
197
+ }
198
+ },
199
+ {
200
+ deep: true,
201
+ immediate: true,
202
+ },
203
+ )
204
+
205
+ onMounted(() => {
206
+ scrollIntoView()
207
+ })
208
+
209
+ /**
210
+ * 使当前日期或者选中日期滚动到可视区域
211
+ */
212
+ function scrollIntoView() {
213
+ requestAnimationFrame(() => {
214
+ let activeDate: number | null = 0
215
+ if (isArray(props.value)) {
216
+ activeDate = props.value![0]
217
+ } else if (isNumber(props.value)) {
218
+ activeDate = props.value
219
+ }
220
+
221
+ if (!activeDate) {
222
+ activeDate = Date.now()
223
+ }
224
+
225
+ let top: number = 0
226
+ for (let index = 0; index < months.value.length; index++) {
227
+ if (compareMonth(months.value[index].date, activeDate) === 0) {
228
+ break
229
+ }
230
+ top += months.value[index] ? Number(months.value[index].height) : 0
231
+ }
232
+ scrollTop.value = 0
233
+ requestAnimationFrame(() => {
234
+ scrollTop.value = top
235
+ })
236
+ })
237
+ }
238
+ /**
239
+ * 获取时间 picker 的数据
240
+ * @param {timestamp|array} value 当前时间
241
+ * @param {string} type 类型,是开始还是结束
242
+ */
243
+ function getTime(value: number | (number | null)[], type?: string) {
244
+ if (props.type === 'datetime') {
245
+ return getTimeData({
246
+ date: value as number,
247
+ minDate: props.minDate,
248
+ maxDate: props.maxDate,
249
+ filter: props.timeFilter,
250
+ isHideSecond: props.hideSecond,
251
+ })
252
+ } else {
253
+ if (type === 'start' && isArray(props.value)) {
254
+ return getTimeData({
255
+ date: (value as Array<number>)[0],
256
+ minDate: props.minDate,
257
+ maxDate: props.value[1] ? props.value[1] : props.maxDate,
258
+ filter: props.timeFilter,
259
+ isHideSecond: props.hideSecond,
260
+ })
261
+ } else {
262
+ return getTimeData({
263
+ date: (value as Array<number>)[1],
264
+ minDate: (value as Array<number>)[0],
265
+ maxDate: props.maxDate,
266
+ filter: props.timeFilter,
267
+ isHideSecond: props.hideSecond,
268
+ })
269
+ }
270
+ }
271
+ }
272
+ /**
273
+ * 获取 date 的时分秒
274
+ * @param {timestamp} date 时间
275
+ * @param {string} type 类型,是开始还是结束
276
+ */
277
+ function getTimeValue(date: number | (number | null)[], type: MonthPanelTimeType) {
278
+ let dateValue: Date = new Date()
279
+ if (props.type === 'datetime') {
280
+ dateValue = new Date(date as number)
281
+ } else if (isArray(date)) {
282
+ if (type === 'start') {
283
+ dateValue = new Date(date[0] || '')
284
+ } else {
285
+ dateValue = new Date(date[1] || '')
286
+ }
287
+ }
288
+
289
+ const hour = dateValue.getHours()
290
+ const minute = dateValue.getMinutes()
291
+ const second = dateValue.getSeconds()
292
+ return props.hideSecond ? [hour, minute] : [hour, minute, second]
293
+ }
294
+
295
+ function setTime(value: number | (number | null)[], type?: MonthPanelTimeType) {
296
+ if (isArray(value) && value[0] && value[1] && type === 'start' && timeType.value === 'start') {
297
+ type = 'end'
298
+ }
299
+ timeType.value = type || ''
300
+ timeValue.value = getTimeValue(value, type || '')
301
+ }
302
+ function handleDateChange({
303
+ value,
304
+ type,
305
+ }: {
306
+ value: number | (number | null)[]
307
+ type?: MonthPanelTimeType
308
+ }) {
309
+ if (!isEqual(value, props.value)) {
310
+ // 内部保存一个值,用于判断新老值,避免监听器触发
311
+ innerValue.value = value
312
+ handleChange(value)
313
+ }
314
+ // datetime 和 datetimerange 类型,需要计算 timeData 并做展示
315
+ if (props.type.indexOf('time') > -1) {
316
+ setTime(value, type)
317
+ }
318
+ }
319
+ function handleTimeChange({ value }: { value: any[] }) {
320
+ if (!props.value) {
321
+ return
322
+ }
323
+ if (props.type === 'datetime' && isNumber(props.value)) {
324
+ const date = new Date(props.value)
325
+ date.setHours(value[0])
326
+ date.setMinutes(value[1])
327
+ date.setSeconds(props.hideSecond ? 0 : value[2])
328
+ const dateTime = date.getTime()
329
+ handleChange(dateTime)
330
+ } else if (isArray(props.value) && props.type === 'datetimerange') {
331
+ const [start, end] = props.value!
332
+ const dataValue = timeType.value === 'start' ? start : end
333
+ const date = new Date(dataValue || '')
334
+ date.setHours(value[0])
335
+ date.setMinutes(value[1])
336
+ date.setSeconds(props.hideSecond ? 0 : value[2])
337
+ const dateTime = date.getTime()
338
+
339
+ if (dateTime === dataValue) return
340
+
341
+ const finalValue = [start, end]
342
+ if (timeType.value === 'start') {
343
+ finalValue[0] = dateTime
344
+ } else {
345
+ finalValue[1] = dateTime
346
+ }
347
+ innerValue.value = finalValue // 内部保存一个值,用于判断新老值,避免监听器触发
348
+ handleChange(finalValue)
349
+ }
350
+ }
351
+ function handlePickStart() {
352
+ emit('pickstart')
353
+ }
354
+ function handlePickEnd() {
355
+ emit('pickend')
356
+ }
357
+
358
+ const monthScroll = (event: { detail: { scrollTop: number } }) => {
359
+ if (months.value.length <= 1) {
360
+ return
361
+ }
362
+ const scrollTop = Math.max(0, event.detail.scrollTop)
363
+ doSetSubtitle(scrollTop)
364
+ }
365
+
366
+ /**
367
+ * 设置小标题
368
+ * scrollTop 滚动条位置
369
+ */
370
+ function doSetSubtitle(scrollTop: number) {
371
+ let height: number = 0 // 月份高度和
372
+ for (let index = 0; index < months.value.length; index++) {
373
+ height = height + months.value[index].height
374
+ if (scrollTop < height + 45) {
375
+ scrollIndex.value = index
376
+ return
377
+ }
378
+ }
379
+ }
380
+
381
+ defineExpose<MonthPanelExpose>({
382
+ scrollIntoView,
383
+ })
384
+ </script>
385
+
386
+ <style lang="scss" scoped>
387
+ @import './index';
388
+ </style>
@@ -0,0 +1,48 @@
1
+ import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
2
+ import { makeBooleanProp, makeRequiredProp } from '../../common/props'
3
+ import type { CalendarFormatter, CalendarTimeFilter, CalendarType } from '../types'
4
+
5
+ /**
6
+ * 月份信息
7
+ */
8
+ export interface MonthInfo {
9
+ date: number
10
+ height: number
11
+ }
12
+
13
+ export const monthPanelProps = {
14
+ type: makeRequiredProp(String as PropType<CalendarType>),
15
+ value: makeRequiredProp([Number, Array, null] as PropType<number | (number | null)[] | null>),
16
+ minDate: makeRequiredProp(Number),
17
+ maxDate: makeRequiredProp(Number),
18
+ firstDayOfWeek: makeRequiredProp(Number),
19
+ formatter: Function as PropType<CalendarFormatter>,
20
+ maxRange: Number,
21
+ rangePrompt: String,
22
+ allowSameDay: makeBooleanProp(false),
23
+ showPanelTitle: makeBooleanProp(false),
24
+ defaultTime: {
25
+ type: [Array] as PropType<Array<number[]>>,
26
+ },
27
+ panelHeight: makeRequiredProp(Number),
28
+ // type 为 'datetime' 或 'datetimerange' 时有效,用于过滤时间选择器的数据
29
+ timeFilter: Function as PropType<CalendarTimeFilter>,
30
+ hideSecond: makeBooleanProp(false),
31
+ /**
32
+ * 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
33
+ */
34
+ immediateChange: makeBooleanProp(false),
35
+ }
36
+
37
+ export type MonthPanelProps = ExtractPropTypes<typeof monthPanelProps>
38
+
39
+ export type MonthPanelTimeType = 'start' | 'end' | ''
40
+
41
+ export type MonthPanelExpose = {
42
+ /**
43
+ * 使当前日期或者选中日期滚动到可视区域
44
+ */
45
+ scrollIntoView: () => void
46
+ }
47
+
48
+ export type MonthPanelInstance = ComponentPublicInstance<MonthPanelProps, MonthPanelExpose>
@@ -0,0 +1,134 @@
1
+ import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
2
+ import {
3
+ baseProps,
4
+ makeBooleanProp,
5
+ makeNumberProp,
6
+ makeRequiredProp,
7
+ makeStringProp,
8
+ } from '../common/props'
9
+
10
+ export type CalendarType =
11
+ | 'date'
12
+ | 'dates'
13
+ | 'datetime'
14
+ | 'week'
15
+ | 'month'
16
+ | 'daterange'
17
+ | 'datetimerange'
18
+ | 'weekrange'
19
+ | 'monthrange'
20
+
21
+ export const calendarViewProps = {
22
+ ...baseProps,
23
+ /**
24
+ * 选中值,为 13 位时间戳或时间戳数组
25
+ */
26
+ modelValue: makeRequiredProp([Number, Array, null] as PropType<number | number[] | null>),
27
+ /**
28
+ * 日期类型
29
+ */
30
+ type: makeStringProp<CalendarType>('date'),
31
+ /**
32
+ * 最小日期,为 13 位时间戳
33
+ */
34
+ minDate: makeNumberProp(
35
+ new Date(new Date().getFullYear(), new Date().getMonth() - 6, new Date().getDate()).getTime(),
36
+ ),
37
+ /**
38
+ * 最大日期,为 13 位时间戳
39
+ */
40
+ maxDate: makeNumberProp(
41
+ new Date(
42
+ new Date().getFullYear(),
43
+ new Date().getMonth() + 6,
44
+ new Date().getDate(),
45
+ 23,
46
+ 59,
47
+ 59,
48
+ ).getTime(),
49
+ ),
50
+ /**
51
+ * 周起始天
52
+ */
53
+ firstDayOfWeek: makeNumberProp(0),
54
+ /**
55
+ * 日期格式化函数
56
+ */
57
+ formatter: Function as PropType<CalendarFormatter>,
58
+ /**
59
+ * type 为范围选择时有效,最大日期范围
60
+ */
61
+ maxRange: Number,
62
+ /**
63
+ * type 为范围选择时有效,选择超出最大日期范围时的错误提示文案
64
+ */
65
+ rangePrompt: String,
66
+ /**
67
+ * type 为范围选择时有效,是否允许选择同一天
68
+ */
69
+ allowSameDay: makeBooleanProp(false),
70
+ // 是否展示面板标题,自动计算当前滚动的日期月份
71
+ showPanelTitle: makeBooleanProp(true),
72
+ /**
73
+ * 选中日期所使用的当日内具体时刻
74
+ */
75
+ defaultTime: {
76
+ type: [String, Array] as PropType<string | string[]>,
77
+ default: '00:00:00',
78
+ },
79
+ /**
80
+ * 可滚动面板的高度
81
+ */
82
+ panelHeight: makeNumberProp(378),
83
+ /**
84
+ * type 为 'datetime' 或 'datetimerange' 时有效,用于过滤时间选择器的数据
85
+ */
86
+ timeFilter: Function as PropType<CalendarTimeFilter>,
87
+ /**
88
+ * type 为 'datetime' 或 'datetimerange' 时有效,是否不展示秒修改
89
+ */
90
+ hideSecond: makeBooleanProp(false),
91
+ /**
92
+ * 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
93
+ */
94
+ immediateChange: makeBooleanProp(false),
95
+ }
96
+
97
+ export type CalendarViewProps = ExtractPropTypes<typeof calendarViewProps>
98
+
99
+ export type CalendarDayType = '' | 'start' | 'middle' | 'end' | 'selected' | 'same' | 'current'
100
+
101
+ export type CalendarDayItem = {
102
+ date: number
103
+ text?: number | string
104
+ topInfo?: string
105
+ bottomInfo?: string
106
+ type?: CalendarDayType
107
+ disabled?: boolean
108
+ }
109
+
110
+ export type CalendarFormatter = (day: CalendarDayItem) => CalendarDayItem
111
+
112
+ export type CalendarTimeFilterOptionType = 'hour' | 'minute' | 'second'
113
+
114
+ export type CalendarTimeFilterOption = {
115
+ type: CalendarTimeFilterOptionType
116
+ values: CalendarItem[]
117
+ }
118
+
119
+ export type CalendarTimeFilter = (option: CalendarTimeFilterOption) => CalendarItem[]
120
+
121
+ export type CalendarItem = {
122
+ label: string
123
+ value: number
124
+ disabled: boolean
125
+ }
126
+
127
+ export type CalendarViewExpose = {
128
+ /**
129
+ * 使当前日期或者选中日期滚动到可视区域
130
+ */
131
+ scrollIntoView: () => void
132
+ }
133
+
134
+ export type CalendarViewInstance = ComponentPublicInstance<CalendarViewExpose, CalendarViewProps>