@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,307 @@
1
+ <template>
2
+ <!--注意阻止横向滑动的穿透:横向移动时阻止冒泡-->
3
+ <view
4
+ :class="`wd-swipe-action ${customClass}`"
5
+ :style="customStyle"
6
+ @click.stop="onClick()"
7
+ @touchstart="startDrag"
8
+ @touchmove="onDrag"
9
+ @touchend="endDrag"
10
+ @touchcancel="endDrag"
11
+ >
12
+ <!--容器-->
13
+ <view class="wd-swipe-action__wrapper" :style="wrapperStyle">
14
+ <!--左侧操作-->
15
+ <view class="wd-swipe-action__left" @click="onClick('left')">
16
+ <slot name="left" />
17
+ </view>
18
+ <!--内容-->
19
+ <slot />
20
+ <!--右侧操作-->
21
+ <view class="wd-swipe-action__right" @click="onClick('right')">
22
+ <slot name="right" />
23
+ </view>
24
+ </view>
25
+ </view>
26
+ </template>
27
+ <script lang="ts">
28
+ export default {
29
+ name: 'wd-swipe-action',
30
+ options: {
31
+ addGlobalClass: true,
32
+ virtualHost: true,
33
+ styleIsolation: 'shared',
34
+ },
35
+ }
36
+ </script>
37
+ <script lang="ts" setup>
38
+ import {
39
+ getCurrentInstance,
40
+ inject,
41
+ onBeforeMount,
42
+ onBeforeUnmount,
43
+ onMounted,
44
+ ref,
45
+ watch,
46
+ } from 'vue'
47
+ import { closeOther, pushToQueue, removeFromQueue } from '../common/clickoutside'
48
+ import { type Queue, queueKey } from '../composables/useQueue'
49
+ import { useTouch } from '../composables/useTouch'
50
+ import { getRect } from '../common/util'
51
+ import {
52
+ swipeActionProps,
53
+ type SwipeActionPosition,
54
+ type SwipeActionReason,
55
+ type SwipeActionStatus,
56
+ } from './types'
57
+
58
+ const props = defineProps(swipeActionProps)
59
+ const emit = defineEmits(['click', 'update:modelValue'])
60
+
61
+ const queue = inject<Queue | null>(queueKey, null)
62
+
63
+ const wrapperStyle = ref<string>('')
64
+
65
+ // 滑动开始时,wrapper的偏移量
66
+ const originOffset = ref<number>(0)
67
+ // wrapper现在的偏移量
68
+ const wrapperOffset = ref<number>(0)
69
+ // 是否处于滑动状态
70
+ const touching = ref<boolean>(false)
71
+
72
+ const touch = useTouch()
73
+
74
+ const { proxy } = getCurrentInstance() as any
75
+
76
+ watch(
77
+ () => props.modelValue,
78
+ (value, old) => {
79
+ changeState(value, old)
80
+ },
81
+ {
82
+ deep: true,
83
+ },
84
+ )
85
+
86
+ onBeforeMount(() => {
87
+ if (queue && queue.pushToQueue) {
88
+ queue.pushToQueue(proxy)
89
+ } else {
90
+ pushToQueue(proxy)
91
+ }
92
+ // 滑动开始时,wrapper的偏移量
93
+ originOffset.value = 0
94
+ // wrapper现在的偏移量
95
+ wrapperOffset.value = 0
96
+ // 是否处于滑动状态
97
+ touching.value = false
98
+ })
99
+
100
+ onMounted(() => {
101
+ touching.value = true
102
+ changeState(props.modelValue)
103
+ touching.value = false
104
+ })
105
+
106
+ onBeforeUnmount(() => {
107
+ if (queue && queue.removeFromQueue) {
108
+ queue.removeFromQueue(proxy)
109
+ } else {
110
+ removeFromQueue(proxy)
111
+ }
112
+ })
113
+
114
+ function changeState(value: SwipeActionStatus, old?: SwipeActionStatus) {
115
+ if (props.disabled) {
116
+ return
117
+ }
118
+ getWidths().then(([leftWidth, rightWidth]) => {
119
+ switch (value) {
120
+ case 'close':
121
+ // 调用此函数时,偏移量本就是0
122
+ if (wrapperOffset.value === 0) return
123
+ close('value', old)
124
+ break
125
+ case 'left':
126
+ swipeMove(leftWidth)
127
+ break
128
+ case 'right':
129
+ swipeMove(-rightWidth)
130
+ break
131
+ }
132
+ })
133
+ }
134
+
135
+ /**
136
+ * @description 获取左/右操作按钮的宽度
137
+ * @return {Promise<[Number, Number]>} 左宽度、右宽度
138
+ */
139
+ function getWidths() {
140
+ return Promise.all([
141
+ getRect('.wd-swipe-action__left', false, proxy).then((rect) => {
142
+ return rect.width ? rect.width : 0
143
+ }),
144
+ getRect('.wd-swipe-action__right', false, proxy).then((rect) => {
145
+ return rect.width ? rect.width : 0
146
+ }),
147
+ ])
148
+ }
149
+ /**
150
+ * @description wrapper滑动函数
151
+ * @param {Number} offset 滑动漂移量
152
+ */
153
+ function swipeMove(offset = 0) {
154
+ // this.offset = offset
155
+ const transform = `translate3d(${offset}px, 0, 0)`
156
+ // 跟随手指滑动,不需要动画
157
+ const transition = touching.value ? 'none' : '.6s cubic-bezier(0.18, 0.89, 0.32, 1)'
158
+ wrapperStyle.value = `
159
+ -webkit-transform: ${transform};
160
+ -webkit-transition: ${transition};
161
+ transform: ${transform};
162
+ transition: ${transition};
163
+ `
164
+ // 记录容器当前偏移的量
165
+ wrapperOffset.value = offset
166
+ }
167
+ /**
168
+ * @description click的handler
169
+ * @param event
170
+ */
171
+ function onClick(position?: SwipeActionPosition) {
172
+ if (props.disabled || wrapperOffset.value === 0) {
173
+ return
174
+ }
175
+
176
+ position = position || 'inside'
177
+ close('click', position)
178
+ emit('click', {
179
+ value: position,
180
+ })
181
+ }
182
+ /**
183
+ * @description 开始滑动
184
+ */
185
+ function startDrag(event: TouchEvent) {
186
+ if (props.disabled) return
187
+
188
+ originOffset.value = wrapperOffset.value
189
+ touch.touchStart(event)
190
+ if (queue && queue.closeOther) {
191
+ queue.closeOther(proxy)
192
+ } else {
193
+ closeOther(proxy)
194
+ }
195
+ }
196
+ /**
197
+ * @description 滑动时,逐渐展示按钮
198
+ * @param event
199
+ */
200
+ function onDrag(event: TouchEvent) {
201
+ if (props.disabled) return
202
+
203
+ touch.touchMove(event)
204
+ if (touch.direction.value === 'vertical') {
205
+ return
206
+ } else {
207
+ event.preventDefault()
208
+ event.stopPropagation()
209
+ }
210
+
211
+ touching.value = true
212
+
213
+ // 本次滑动,wrapper应该设置的偏移量
214
+ const offset = originOffset.value + touch.deltaX.value
215
+ getWidths().then(([leftWidth, rightWidth]) => {
216
+ // 如果需要想滑出来的按钮不存在,对应的按钮肯定滑不出来,容器处于初始状态。此时需要模拟一下位于此处的start事件。
217
+ if ((leftWidth === 0 && offset > 0) || (rightWidth === 0 && offset < 0)) {
218
+ swipeMove(0)
219
+ return startDrag(event)
220
+ }
221
+ // 按钮已经展示完了,再滑动没有任何意义,相当于滑动结束。此时需要模拟一下位于此处的start事件。
222
+ if (leftWidth !== 0 && offset >= leftWidth) {
223
+ swipeMove(leftWidth)
224
+ return startDrag(event)
225
+ } else if (rightWidth !== 0 && -offset >= rightWidth) {
226
+ swipeMove(-rightWidth)
227
+ return startDrag(event)
228
+ }
229
+ swipeMove(offset)
230
+ })
231
+ }
232
+ /**
233
+ * @description 滑动结束,自动修正位置
234
+ */
235
+ function endDrag() {
236
+ if (props.disabled) return
237
+ // 滑出"操作按钮"的阈值
238
+ const THRESHOLD = 0.3
239
+ touching.value = false
240
+
241
+ getWidths().then(([leftWidth, rightWidth]) => {
242
+ if (
243
+ originOffset.value < 0 && // 之前展示的是右按钮
244
+ wrapperOffset.value < 0 && // 目前仍然是右按钮
245
+ wrapperOffset.value - originOffset.value < rightWidth * THRESHOLD // 并且滑动的范围不超过右边框阀值
246
+ ) {
247
+ swipeMove(-rightWidth) // 回归右按钮
248
+ emit('update:modelValue', 'right')
249
+ } else if (
250
+ originOffset.value > 0 && // 之前展示的是左按钮
251
+ wrapperOffset.value > 0 && // 现在仍然是左按钮
252
+ originOffset.value - wrapperOffset.value < leftWidth * THRESHOLD // 并且滑动的范围不超过左按钮阀值
253
+ ) {
254
+ swipeMove(leftWidth) // 回归左按钮
255
+ emit('update:modelValue', 'left')
256
+ } else if (
257
+ rightWidth > 0 &&
258
+ originOffset.value >= 0 && // 之前是初始状态或者展示左按钮显
259
+ wrapperOffset.value < 0 && // 现在展示右按钮
260
+ Math.abs(wrapperOffset.value) > rightWidth * THRESHOLD // 视图中已经展示的右按钮长度超过阀值
261
+ ) {
262
+ swipeMove(-rightWidth)
263
+ emit('update:modelValue', 'right')
264
+ } else if (
265
+ leftWidth > 0 &&
266
+ originOffset.value <= 0 && // 之前初始状态或者右按钮显示
267
+ wrapperOffset.value > 0 && // 现在左按钮
268
+ Math.abs(wrapperOffset.value) > leftWidth * THRESHOLD // 视图中已经展示的左按钮长度超过阀值
269
+ ) {
270
+ swipeMove(leftWidth)
271
+ emit('update:modelValue', 'left')
272
+ } else {
273
+ // 回归初始状态
274
+ close('swipe')
275
+ }
276
+ })
277
+ }
278
+ /**
279
+ * @description 关闭操过按钮,并在合适的时候调用 beforeClose
280
+ */
281
+ function close(reason: SwipeActionReason, position?: SwipeActionPosition) {
282
+ if (reason === 'swipe' && originOffset.value === 0) {
283
+ // offset:0 ——> offset:0
284
+ return swipeMove(0)
285
+ } else if (reason === 'swipe' && originOffset.value > 0) {
286
+ // offset > 0 ——> offset:0
287
+ position = 'left'
288
+ } else if (reason === 'swipe' && originOffset.value < 0) {
289
+ // offset < 0 ——> offset:0
290
+ position = 'right'
291
+ }
292
+
293
+ if (reason && position) {
294
+ props.beforeClose && props.beforeClose(reason, position)
295
+ }
296
+
297
+ swipeMove(0)
298
+ if (props.modelValue !== 'close') {
299
+ emit('update:modelValue', 'close')
300
+ }
301
+ }
302
+
303
+ defineExpose({ close })
304
+ </script>
305
+ <style lang="scss" scoped>
306
+ @import './index';
307
+ </style>
@@ -0,0 +1,23 @@
1
+ @import '../common/abstracts/variable';
2
+ @import '../common/abstracts/mixin';
3
+
4
+ @include b(swiper) {
5
+ position: relative;
6
+ @include e(track) {
7
+ overflow: hidden;
8
+ border-radius: $-swiper-radius;
9
+ transform: translateY(0);
10
+ }
11
+
12
+ @include e(item) {
13
+ box-sizing: border-box;
14
+ display: flex;
15
+ align-items: center;
16
+ padding: $-swiper-item-padding;
17
+ }
18
+
19
+ @include e(image) {
20
+ width: 100%;
21
+ transition: all 0.3s ease;
22
+ }
23
+ }
@@ -0,0 +1,189 @@
1
+ import type { ExtractPropTypes, PropType } from 'vue'
2
+ import {
3
+ baseProps,
4
+ makeBooleanProp,
5
+ makeNumberProp,
6
+ makeNumericProp,
7
+ makeStringProp,
8
+ } from '../common/props'
9
+ import type { SwiperNavProps } from '../wd-swiper-nav/types'
10
+ import type { ImageMode } from '../wd-img/types'
11
+
12
+ /**
13
+ * 轮播滑动方向
14
+ */
15
+ export type DirectionType = 'horizontal' | 'vertical'
16
+
17
+ /**
18
+ * 切换动画
19
+ */
20
+ export type EasingType = 'default' | 'linear' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic'
21
+
22
+ /**
23
+ * 指示器位置
24
+ */
25
+ export type IndicatorPositionType =
26
+ | 'left'
27
+ | 'top-left'
28
+ | 'top'
29
+ | 'top-right'
30
+ | 'bottom-left'
31
+ | 'bottom'
32
+ | 'bottom-right'
33
+ | 'right'
34
+
35
+ export interface SwiperList {
36
+ [key: string]: any
37
+ value?: string
38
+ }
39
+
40
+ export const swiperProps = {
41
+ ...baseProps,
42
+
43
+ /**
44
+ * 是否自动播放轮播图
45
+ * 类型:boolean
46
+ * 默认值:true
47
+ */
48
+ autoplay: makeBooleanProp(true),
49
+
50
+ /**
51
+ * 当前轮播在哪一项(下标)
52
+ * 类型:number
53
+ * 默认值:0
54
+ */
55
+ current: makeNumberProp(0),
56
+
57
+ /**
58
+ * 轮播滑动方向,可选值:'horizontal'(水平)或'vertical'(垂直)
59
+ * 类型:string
60
+ * 默认值:'horizontal'
61
+ */
62
+ direction: makeStringProp<DirectionType>('horizontal'),
63
+
64
+ /**
65
+ * 同时显示的滑块数量
66
+ * 类型:number
67
+ * 默认值:1
68
+ */
69
+ displayMultipleItems: makeNumberProp(1),
70
+
71
+ /**
72
+ * 滑动动画时长,单位为毫秒
73
+ * 类型:number
74
+ * 默认值:300
75
+ */
76
+ duration: makeNumberProp(300),
77
+
78
+ /**
79
+ * 指定 swiper 切换缓动动画类型
80
+ * 类型:string
81
+ * 默认值:'default'
82
+ */
83
+ easingFunction: makeStringProp<EasingType>('default'),
84
+
85
+ /**
86
+ * 轮播的高度
87
+ * 类型:number 或 string(数字或可转换为数字的字符串)
88
+ * 默认值:'192'
89
+ */
90
+ height: makeNumericProp('192'),
91
+
92
+ /**
93
+ * 轮播间隔时间,单位为毫秒
94
+ * 类型:number
95
+ * 默认值:5000
96
+ */
97
+ interval: makeNumberProp(5000),
98
+
99
+ /**
100
+ * 图片列表,可以是一个图片对象数组或字符串数组
101
+ * 类型:array
102
+ * 默认值:空数组
103
+ */
104
+ list: {
105
+ type: Array as PropType<SwiperList[] | string[]>,
106
+ default: () => [],
107
+ },
108
+
109
+ /**
110
+ * 是否循环播放轮播图
111
+ * 类型:boolean
112
+ * 默认值:true
113
+ */
114
+ loop: makeBooleanProp(true),
115
+
116
+ /**
117
+ * 后边距
118
+ * 类型:number 或 string(数字或可转换为数字的字符串)
119
+ * 默认值:'0'
120
+ */
121
+ nextMargin: makeNumericProp('0'),
122
+
123
+ /**
124
+ * 页码信息展示位置,可选值:'bottom'(底部)等
125
+ * 类型:string
126
+ * 默认值:'bottom'
127
+ */
128
+ indicatorPosition: makeStringProp<IndicatorPositionType>('bottom'),
129
+
130
+ /**
131
+ * 前边距
132
+ * 类型:number 或 string(数字或可转换为数字的字符串)
133
+ * 默认值:'0'
134
+ */
135
+ previousMargin: makeNumericProp('0'),
136
+
137
+ /**
138
+ * 是否应用边距到第一个、最后一个元素
139
+ * 类型:boolean
140
+ * 默认值:false
141
+ */
142
+ snapToEdge: makeBooleanProp(false),
143
+
144
+ /**
145
+ * 指示器全部配置,可以是布尔值或指示器配置对象
146
+ * 类型:boolean 或 object
147
+ * 默认值:true
148
+ */
149
+ indicator: {
150
+ type: [Boolean, Object] as PropType<boolean | Partial<SwiperNavProps>>,
151
+ default: true,
152
+ },
153
+
154
+ /**
155
+ * 图片裁剪、缩放的模式
156
+ * 类型:string
157
+ * 默认值:'aspectFill'
158
+ */
159
+ imageMode: makeStringProp<ImageMode>('aspectFill'),
160
+ /**
161
+ * 选项对象中,value 对应的 key
162
+ */
163
+ valueKey: makeStringProp('value'),
164
+ /**
165
+ * 自定义指示器类名
166
+ * 类型:string
167
+ */
168
+ customIndicatorClass: makeStringProp(''),
169
+
170
+ /**
171
+ * 自定义图片类名
172
+ * 类型:string
173
+ */
174
+ customImageClass: makeStringProp(''),
175
+
176
+ /**
177
+ * 自定义上一个图片类名
178
+ * 类型:string
179
+ */
180
+ customPrevImageClass: makeStringProp(''),
181
+
182
+ /**
183
+ * 自定义下一个图片类名
184
+ * 类型:string
185
+ */
186
+ customNextImageClass: makeStringProp(''),
187
+ }
188
+
189
+ export type SwiperProps = ExtractPropTypes<typeof swiperProps>
@@ -0,0 +1,202 @@
1
+ <template>
2
+ <view :class="`wd-swiper ${customClass}`" :style="customStyle">
3
+ <swiper
4
+ class="wd-swiper__track"
5
+ :autoplay="autoplay"
6
+ :current="current"
7
+ :interval="interval"
8
+ :duration="duration"
9
+ :circular="loop"
10
+ :vertical="direction == 'vertical'"
11
+ :easing-function="easingFunction"
12
+ :previous-margin="previousMargin"
13
+ :next-margin="nextMargin"
14
+ :snap-to-edge="snapToEdge"
15
+ :display-multiple-items="displayMultipleItems"
16
+ :style="{ height: addUnit(height) }"
17
+ @change="handleChange"
18
+ @animationfinish="handleAnimationfinish"
19
+ >
20
+ <swiper-item
21
+ v-for="(item, index) in list"
22
+ :key="index"
23
+ class="wd-swiper__item"
24
+ @click="handleClick(index, item)"
25
+ >
26
+ <image
27
+ :src="isObj(item) ? item[valueKey] : item"
28
+ :class="`wd-swiper__image ${customImageClass} ${getCustomImageClass(navCurrent, index, list)}`"
29
+ :style="{ height: addUnit(height) }"
30
+ :mode="imageMode"
31
+ />
32
+ </swiper-item>
33
+ </swiper>
34
+
35
+ <template v-if="indicator">
36
+ <slot name="indicator" :current="navCurrent" :total="list.length"></slot>
37
+ <wd-swiper-nav
38
+ v-if="!$slots.indicator"
39
+ :custom-class="customIndicatorClass"
40
+ :type="swiperIndicator.type"
41
+ :current="swiperIndicator.current"
42
+ :total="swiperIndicator.total"
43
+ :direction="swiperIndicator.direction"
44
+ :indicator-position="swiperIndicator.indicatorPosition"
45
+ :min-show-num="swiperIndicator.minShowNum"
46
+ :show-controls="swiperIndicator.showControls"
47
+ @change="handleIndicatorChange"
48
+ />
49
+ </template>
50
+ </view>
51
+ </template>
52
+
53
+ <script lang="ts" setup>
54
+ import { computed, watch, ref } from 'vue'
55
+ import { addUnit, isObj } from '../common/util'
56
+ import { swiperProps, type SwiperList } from './types'
57
+ import type { SwiperNavProps } from '../wd-swiper-nav/types'
58
+
59
+ const props = defineProps(swiperProps)
60
+ const emit = defineEmits(['click', 'change', 'animationfinish', 'update:current'])
61
+ const navCurrent = ref<number>(0) // 当前滑块
62
+
63
+ watch(
64
+ () => props.current,
65
+ (val) => {
66
+ if (val < 0) {
67
+ props.loop ? goToEnd() : goToStart()
68
+ } else if (val >= props.list.length) {
69
+ props.loop ? goToStart() : goToEnd()
70
+ } else {
71
+ go(val)
72
+ }
73
+ emit('update:current', navCurrent.value)
74
+ },
75
+ { immediate: true },
76
+ )
77
+
78
+ const swiperIndicator = computed(() => {
79
+ const { list, direction, indicatorPosition, indicator } = props
80
+ const swiperIndicator: Partial<SwiperNavProps> = {
81
+ current: navCurrent.value || 0,
82
+ total: list.length || 0,
83
+ direction: direction || 'horizontal',
84
+ indicatorPosition: indicatorPosition || 'bottom',
85
+ }
86
+ if (isObj(indicator)) {
87
+ swiperIndicator.type = indicator.type || 'dots'
88
+ swiperIndicator.minShowNum = indicator.minShowNum || 2
89
+ swiperIndicator.showControls = indicator.showControls || false
90
+ }
91
+ return swiperIndicator
92
+ })
93
+
94
+ function go(index: number) {
95
+ navCurrent.value = index
96
+ }
97
+
98
+ function goToStart() {
99
+ navCurrent.value = 0
100
+ }
101
+
102
+ function goToEnd() {
103
+ navCurrent.value = props.list.length - 1
104
+ }
105
+
106
+ /**
107
+ * 是否为当前滑块的前一个滑块
108
+ * @param current
109
+ * @param index
110
+ * @param list
111
+ */
112
+ function isPrev(current: number, index: number, list: string[] | SwiperList[]) {
113
+ return (current - 1 + list.length) % list.length === index
114
+ }
115
+
116
+ /**
117
+ * 是否为当前滑块的后一个滑块
118
+ * @param current
119
+ * @param index
120
+ * @param list
121
+ */
122
+ function isNext(current: number, index: number, list: string[] | SwiperList[]) {
123
+ return (current + 1 + list.length) % list.length === index
124
+ }
125
+
126
+ function getCustomImageClass(current: number, index: number, list: string[] | SwiperList[]) {
127
+ let customImageClass: string = ''
128
+ if (isPrev(current, index, list)) {
129
+ customImageClass = props.customPrevImageClass
130
+ }
131
+ if (isNext(current, index, list)) {
132
+ customImageClass = props.customNextImageClass
133
+ }
134
+ return customImageClass
135
+ }
136
+
137
+ /**
138
+ * 轮播滑块切换时触发
139
+ * @param e
140
+ */
141
+ function handleChange(e: { detail: { current: any; source: string } }) {
142
+ const { current, source } = e.detail
143
+ navCurrent.value = current
144
+ // #ifndef MP-WEIXIN
145
+ emit('update:current', navCurrent.value)
146
+ // #endif
147
+ emit('change', { current, source })
148
+ }
149
+
150
+ /**
151
+ * 滑块动画结束
152
+ */
153
+ function handleAnimationfinish(e: { detail: { current: any; source: string } }) {
154
+ const { current, source } = e.detail
155
+ // #ifdef MP-WEIXIN
156
+ // 兼容微信swiper抖动的问题
157
+ emit('update:current', navCurrent.value)
158
+ // #endif
159
+
160
+ /**
161
+ * 滑块动画结束时触发
162
+ */
163
+ emit('animationfinish', { current, source })
164
+ }
165
+
166
+ /**
167
+ * 点击滑块事件
168
+ * @param index 点击的滑块下标
169
+ * @param item 点击的滑块内容
170
+ */
171
+ function handleClick(index: number, item: string | SwiperList) {
172
+ emit('click', { index, item })
173
+ }
174
+
175
+ function handleIndicatorChange(e: { dir: any; source: string }) {
176
+ const { dir, source } = e
177
+ doIndicatorBtnChange(dir, source)
178
+ }
179
+
180
+ function doIndicatorBtnChange(dir: string, source: string) {
181
+ const { list, loop } = props
182
+ const total = list.length
183
+ let nextPos = dir === 'next' ? navCurrent.value + 1 : navCurrent.value - 1
184
+
185
+ if (loop) {
186
+ nextPos =
187
+ dir === 'next' ? (navCurrent.value + 1) % total : (navCurrent.value - 1 + total) % total
188
+ } else {
189
+ nextPos = nextPos < 0 || nextPos >= total ? navCurrent.value : nextPos
190
+ }
191
+
192
+ if (nextPos === navCurrent.value) return
193
+
194
+ navCurrent.value = nextPos
195
+ emit('change', { current: nextPos, source })
196
+ emit('update:current', navCurrent.value)
197
+ }
198
+ </script>
199
+
200
+ <style lang="scss" scoped>
201
+ @import './index';
202
+ </style>