@mpxjs/webpack-plugin 2.10.17 → 2.10.18-beta.10

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 (275) hide show
  1. package/lib/config.js +60 -0
  2. package/lib/file-loader.js +4 -1
  3. package/lib/global.d.ts +231 -0
  4. package/lib/index.js +71 -74
  5. package/lib/init.js +3 -0
  6. package/lib/json-compiler/index.js +13 -4
  7. package/lib/loader.js +4 -0
  8. package/lib/platform/json/wx/index.js +6 -0
  9. package/lib/platform/style/wx/index.js +102 -72
  10. package/lib/platform/template/wx/component-config/ad.js +5 -0
  11. package/lib/platform/template/wx/component-config/button.js +10 -3
  12. package/lib/platform/template/wx/component-config/camera.js +25 -3
  13. package/lib/platform/template/wx/component-config/canvas.js +8 -1
  14. package/lib/platform/template/wx/component-config/cover-image.js +7 -2
  15. package/lib/platform/template/wx/component-config/cover-view.js +3 -1
  16. package/lib/platform/template/wx/component-config/form.js +27 -2
  17. package/lib/platform/template/wx/component-config/image.js +5 -0
  18. package/lib/platform/template/wx/component-config/input.js +10 -0
  19. package/lib/platform/template/wx/component-config/label.js +10 -2
  20. package/lib/platform/template/wx/component-config/map.js +11 -0
  21. package/lib/platform/template/wx/component-config/movable-area.js +4 -1
  22. package/lib/platform/template/wx/component-config/movable-view.js +17 -2
  23. package/lib/platform/template/wx/component-config/navigator.js +26 -0
  24. package/lib/platform/template/wx/component-config/picker-view.js +12 -0
  25. package/lib/platform/template/wx/component-config/picker.js +3 -1
  26. package/lib/platform/template/wx/component-config/progress.js +11 -1
  27. package/lib/platform/template/wx/component-config/rich-text.js +5 -0
  28. package/lib/platform/template/wx/component-config/scroll-view.js +12 -1
  29. package/lib/platform/template/wx/component-config/slider.js +8 -0
  30. package/lib/platform/template/wx/component-config/swiper-item.js +5 -2
  31. package/lib/platform/template/wx/component-config/swiper.js +10 -0
  32. package/lib/platform/template/wx/component-config/text.js +5 -0
  33. package/lib/platform/template/wx/component-config/textarea.js +19 -2
  34. package/lib/platform/template/wx/component-config/titlebar.js +12 -0
  35. package/lib/platform/template/wx/component-config/unsupported.js +10 -1
  36. package/lib/platform/template/wx/component-config/video.js +10 -0
  37. package/lib/platform/template/wx/index.js +21 -1
  38. package/lib/react/LoadAsyncChunkModule.js +3 -6
  39. package/lib/react/processStyles.js +21 -9
  40. package/lib/react/script-helper.js +2 -2
  41. package/lib/react/style-helper.js +76 -13
  42. package/lib/resolver/AddModePlugin.js +17 -7
  43. package/lib/resolver/ExtendComponentsPlugin.js +60 -0
  44. package/lib/runtime/components/ali/mpx-section-list.mpx +566 -0
  45. package/lib/runtime/components/ali/mpx-sticky-header.mpx +212 -0
  46. package/lib/runtime/components/ali/mpx-sticky-section.mpx +17 -0
  47. package/lib/runtime/components/react/animationHooks/index.ts +75 -0
  48. package/lib/runtime/components/react/animationHooks/useAnimationAPIHooks.ts +197 -0
  49. package/lib/runtime/components/react/animationHooks/useTransitionHooks.ts +301 -0
  50. package/lib/runtime/components/react/animationHooks/utils.ts +197 -0
  51. package/lib/runtime/components/react/context.ts +12 -3
  52. package/lib/runtime/components/react/dist/animationHooks/index.d.ts +15 -0
  53. package/lib/runtime/components/react/dist/animationHooks/index.js +67 -0
  54. package/lib/runtime/components/react/dist/animationHooks/useAnimationAPIHooks.d.ts +3 -0
  55. package/lib/runtime/components/react/dist/animationHooks/useAnimationAPIHooks.js +181 -0
  56. package/lib/runtime/components/react/dist/animationHooks/useTransitionHooks.d.ts +3 -0
  57. package/lib/runtime/components/react/dist/animationHooks/useTransitionHooks.js +279 -0
  58. package/lib/runtime/components/react/dist/animationHooks/utils.d.ts +109 -0
  59. package/lib/runtime/components/react/dist/animationHooks/utils.js +151 -0
  60. package/lib/runtime/components/react/dist/context.d.ts +10 -3
  61. package/lib/runtime/components/react/dist/context.js +1 -2
  62. package/lib/runtime/components/react/dist/event.config.d.ts +0 -1
  63. package/lib/runtime/components/react/dist/getInnerListeners.d.ts +0 -1
  64. package/lib/runtime/components/react/dist/mpx-async-suspense.d.ts +0 -1
  65. package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +3 -1
  66. package/lib/runtime/components/react/dist/mpx-button.d.ts +0 -1
  67. package/lib/runtime/components/react/dist/mpx-camera.d.ts +31 -0
  68. package/lib/runtime/components/react/dist/mpx-camera.jsx +236 -0
  69. package/lib/runtime/components/react/dist/mpx-canvas/Bus.d.ts +0 -1
  70. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.d.ts +0 -1
  71. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.d.ts +0 -1
  72. package/lib/runtime/components/react/dist/mpx-canvas/Image.d.ts +0 -1
  73. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.d.ts +0 -1
  74. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.d.ts +0 -1
  75. package/lib/runtime/components/react/dist/mpx-canvas/html.d.ts +0 -1
  76. package/lib/runtime/components/react/dist/mpx-canvas/index.d.ts +0 -1
  77. package/lib/runtime/components/react/dist/mpx-canvas/utils.d.ts +0 -1
  78. package/lib/runtime/components/react/dist/mpx-checkbox-group.d.ts +0 -1
  79. package/lib/runtime/components/react/dist/mpx-checkbox.d.ts +0 -1
  80. package/lib/runtime/components/react/dist/mpx-form.d.ts +0 -1
  81. package/lib/runtime/components/react/dist/mpx-icon/index.d.ts +0 -1
  82. package/lib/runtime/components/react/dist/mpx-image.d.ts +0 -1
  83. package/lib/runtime/components/react/dist/mpx-image.jsx +2 -2
  84. package/lib/runtime/components/react/dist/mpx-inline-text.d.ts +0 -1
  85. package/lib/runtime/components/react/dist/mpx-input.d.ts +2 -1
  86. package/lib/runtime/components/react/dist/mpx-input.jsx +69 -50
  87. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.d.ts +0 -1
  88. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +35 -6
  89. package/lib/runtime/components/react/dist/mpx-label.d.ts +0 -1
  90. package/lib/runtime/components/react/dist/mpx-movable-area.d.ts +0 -1
  91. package/lib/runtime/components/react/dist/mpx-movable-view.d.ts +0 -1
  92. package/lib/runtime/components/react/dist/mpx-nav.d.ts +0 -1
  93. package/lib/runtime/components/react/dist/mpx-navigator.d.ts +0 -1
  94. package/lib/runtime/components/react/dist/mpx-picker/date.d.ts +0 -1
  95. package/lib/runtime/components/react/dist/mpx-picker/dateData.d.ts +0 -1
  96. package/lib/runtime/components/react/dist/mpx-picker/index.d.ts +0 -1
  97. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.d.ts +0 -1
  98. package/lib/runtime/components/react/dist/mpx-picker/region.d.ts +0 -1
  99. package/lib/runtime/components/react/dist/mpx-picker/regionData.d.ts +0 -1
  100. package/lib/runtime/components/react/dist/mpx-picker/selector.d.ts +0 -1
  101. package/lib/runtime/components/react/dist/mpx-picker/time.d.ts +0 -1
  102. package/lib/runtime/components/react/dist/mpx-picker/type.d.ts +0 -1
  103. package/lib/runtime/components/react/dist/mpx-picker-view/index.d.ts +0 -1
  104. package/lib/runtime/components/react/dist/mpx-picker-view/pickerVIewContext.d.ts +0 -1
  105. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.d.ts +0 -1
  106. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.d.ts +0 -1
  107. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.d.ts +0 -1
  108. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewFaces.d.ts +0 -1
  109. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewIndicator.d.ts +0 -1
  110. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewMask.d.ts +0 -1
  111. package/lib/runtime/components/react/dist/mpx-popup/index.d.ts +0 -1
  112. package/lib/runtime/components/react/dist/mpx-popup/popupBase.d.ts +0 -1
  113. package/lib/runtime/components/react/dist/mpx-portal/index.d.ts +0 -1
  114. package/lib/runtime/components/react/dist/mpx-portal/portal-host.d.ts +0 -1
  115. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.d.ts +0 -1
  116. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +2 -2
  117. package/lib/runtime/components/react/dist/mpx-progress.d.ts +0 -1
  118. package/lib/runtime/components/react/dist/mpx-radio-group.d.ts +0 -1
  119. package/lib/runtime/components/react/dist/mpx-radio.d.ts +0 -1
  120. package/lib/runtime/components/react/dist/mpx-rich-text/html.d.ts +0 -1
  121. package/lib/runtime/components/react/dist/mpx-rich-text/index.d.ts +0 -1
  122. package/lib/runtime/components/react/dist/mpx-root-portal.d.ts +0 -1
  123. package/lib/runtime/components/react/dist/mpx-scroll-view.d.ts +0 -1
  124. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +84 -78
  125. package/lib/runtime/components/react/dist/mpx-section-list.d.ts +48 -0
  126. package/lib/runtime/components/react/dist/mpx-section-list.jsx +292 -0
  127. package/lib/runtime/components/react/dist/mpx-simple-text.d.ts +0 -1
  128. package/lib/runtime/components/react/dist/mpx-simple-view.d.ts +0 -1
  129. package/lib/runtime/components/react/dist/mpx-slider.d.ts +0 -1
  130. package/lib/runtime/components/react/dist/mpx-sticky-header.d.ts +0 -1
  131. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +20 -20
  132. package/lib/runtime/components/react/dist/mpx-sticky-section.d.ts +0 -1
  133. package/lib/runtime/components/react/dist/mpx-swiper-item.d.ts +0 -1
  134. package/lib/runtime/components/react/dist/mpx-swiper.d.ts +11 -1
  135. package/lib/runtime/components/react/dist/mpx-swiper.jsx +136 -83
  136. package/lib/runtime/components/react/dist/mpx-switch.d.ts +0 -1
  137. package/lib/runtime/components/react/dist/mpx-text.d.ts +0 -1
  138. package/lib/runtime/components/react/dist/mpx-textarea.d.ts +0 -1
  139. package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -0
  140. package/lib/runtime/components/react/dist/mpx-video.d.ts +0 -1
  141. package/lib/runtime/components/react/dist/mpx-view.d.ts +3 -3
  142. package/lib/runtime/components/react/dist/mpx-view.jsx +22 -8
  143. package/lib/runtime/components/react/dist/mpx-web-view.d.ts +0 -1
  144. package/lib/runtime/components/react/dist/mpx-web-view.jsx +1 -1
  145. package/lib/runtime/components/react/dist/parser.d.ts +0 -1
  146. package/lib/runtime/components/react/dist/useNodesRef.d.ts +0 -1
  147. package/lib/runtime/components/react/dist/utils.d.ts +10 -9
  148. package/lib/runtime/components/react/dist/utils.jsx +47 -24
  149. package/lib/runtime/components/react/mpx-async-suspense.tsx +3 -1
  150. package/lib/runtime/components/react/mpx-camera.tsx +327 -0
  151. package/lib/runtime/components/react/mpx-image.tsx +2 -2
  152. package/lib/runtime/components/react/mpx-input.tsx +71 -52
  153. package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +35 -6
  154. package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +10 -0
  155. package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +2 -2
  156. package/lib/runtime/components/react/mpx-scroll-view.tsx +110 -114
  157. package/lib/runtime/components/react/mpx-section-list.tsx +439 -0
  158. package/lib/runtime/components/react/mpx-sticky-header.tsx +24 -24
  159. package/lib/runtime/components/react/mpx-swiper.tsx +174 -84
  160. package/lib/runtime/components/react/mpx-textarea.tsx +1 -0
  161. package/lib/runtime/components/react/mpx-view.tsx +27 -12
  162. package/lib/runtime/components/react/mpx-web-view.tsx +1 -1
  163. package/lib/runtime/components/react/tsconfig.json +26 -0
  164. package/lib/runtime/components/react/types/global.d.ts +1 -0
  165. package/lib/runtime/components/react/utils.tsx +51 -27
  166. package/lib/runtime/components/web/mpx-scroll-view.vue +5 -2
  167. package/lib/runtime/components/web/mpx-section-list.vue +551 -0
  168. package/lib/runtime/components/web/mpx-titlebar.vue +244 -0
  169. package/lib/runtime/components/wx/mpx-section-list-default/list-footer.mpx +26 -0
  170. package/lib/runtime/components/wx/mpx-section-list-default/list-header.mpx +26 -0
  171. package/lib/runtime/components/wx/mpx-section-list-default/list-item.mpx +26 -0
  172. package/lib/runtime/components/wx/mpx-section-list-default/section-header.mpx +26 -0
  173. package/lib/runtime/components/wx/mpx-section-list.mpx +209 -0
  174. package/lib/runtime/components/wx/mpx-sticky-header.mpx +40 -0
  175. package/lib/runtime/components/wx/mpx-sticky-section.mpx +31 -0
  176. package/lib/runtime/optionProcessor.js +5 -0
  177. package/lib/runtime/optionProcessorReact.js +7 -0
  178. package/lib/runtime/stringify.wxs +2 -2
  179. package/lib/script-setup-compiler/index.js +1 -2
  180. package/lib/style-compiler/strip-conditional.js +244 -0
  181. package/lib/template-compiler/compiler.js +89 -9
  182. package/lib/utils/const.js +29 -0
  183. package/lib/utils/dom-tag-config.js +1 -1
  184. package/lib/utils/string.js +25 -1
  185. package/lib/web/processMainScript.js +3 -1
  186. package/lib/wxss/loader.js +4 -1
  187. package/lib/wxss/utils.js +7 -2
  188. package/package.json +7 -14
  189. package/LICENSE +0 -433
  190. package/lib/runtime/components/react/dist/context.d.ts.map +0 -1
  191. package/lib/runtime/components/react/dist/event.config.d.ts.map +0 -1
  192. package/lib/runtime/components/react/dist/getInnerListeners.d.ts.map +0 -1
  193. package/lib/runtime/components/react/dist/mpx-async-suspense.d.ts.map +0 -1
  194. package/lib/runtime/components/react/dist/mpx-button.d.ts.map +0 -1
  195. package/lib/runtime/components/react/dist/mpx-canvas/Bus.d.ts.map +0 -1
  196. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.d.ts.map +0 -1
  197. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.d.ts.map +0 -1
  198. package/lib/runtime/components/react/dist/mpx-canvas/Image.d.ts.map +0 -1
  199. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.d.ts.map +0 -1
  200. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.d.ts.map +0 -1
  201. package/lib/runtime/components/react/dist/mpx-canvas/html.d.ts.map +0 -1
  202. package/lib/runtime/components/react/dist/mpx-canvas/index.d.ts.map +0 -1
  203. package/lib/runtime/components/react/dist/mpx-canvas/utils.d.ts.map +0 -1
  204. package/lib/runtime/components/react/dist/mpx-checkbox-group.d.ts.map +0 -1
  205. package/lib/runtime/components/react/dist/mpx-checkbox.d.ts.map +0 -1
  206. package/lib/runtime/components/react/dist/mpx-form.d.ts.map +0 -1
  207. package/lib/runtime/components/react/dist/mpx-icon/icons/cancel.png +0 -0
  208. package/lib/runtime/components/react/dist/mpx-icon/icons/clear.png +0 -0
  209. package/lib/runtime/components/react/dist/mpx-icon/icons/download.png +0 -0
  210. package/lib/runtime/components/react/dist/mpx-icon/icons/info.png +0 -0
  211. package/lib/runtime/components/react/dist/mpx-icon/icons/search.png +0 -0
  212. package/lib/runtime/components/react/dist/mpx-icon/icons/success.png +0 -0
  213. package/lib/runtime/components/react/dist/mpx-icon/icons/success_no_circle.png +0 -0
  214. package/lib/runtime/components/react/dist/mpx-icon/icons/waiting.png +0 -0
  215. package/lib/runtime/components/react/dist/mpx-icon/icons/warn.png +0 -0
  216. package/lib/runtime/components/react/dist/mpx-icon/index.d.ts.map +0 -1
  217. package/lib/runtime/components/react/dist/mpx-image.d.ts.map +0 -1
  218. package/lib/runtime/components/react/dist/mpx-inline-text.d.ts.map +0 -1
  219. package/lib/runtime/components/react/dist/mpx-input.d.ts.map +0 -1
  220. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.d.ts.map +0 -1
  221. package/lib/runtime/components/react/dist/mpx-label.d.ts.map +0 -1
  222. package/lib/runtime/components/react/dist/mpx-movable-area.d.ts.map +0 -1
  223. package/lib/runtime/components/react/dist/mpx-movable-view.d.ts.map +0 -1
  224. package/lib/runtime/components/react/dist/mpx-nav.d.ts.map +0 -1
  225. package/lib/runtime/components/react/dist/mpx-navigator.d.ts.map +0 -1
  226. package/lib/runtime/components/react/dist/mpx-picker/date.d.ts.map +0 -1
  227. package/lib/runtime/components/react/dist/mpx-picker/dateData.d.ts.map +0 -1
  228. package/lib/runtime/components/react/dist/mpx-picker/index.d.ts.map +0 -1
  229. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.d.ts.map +0 -1
  230. package/lib/runtime/components/react/dist/mpx-picker/region.d.ts.map +0 -1
  231. package/lib/runtime/components/react/dist/mpx-picker/regionData.d.ts.map +0 -1
  232. package/lib/runtime/components/react/dist/mpx-picker/selector.d.ts.map +0 -1
  233. package/lib/runtime/components/react/dist/mpx-picker/time.d.ts.map +0 -1
  234. package/lib/runtime/components/react/dist/mpx-picker/type.d.ts.map +0 -1
  235. package/lib/runtime/components/react/dist/mpx-picker-view/index.d.ts.map +0 -1
  236. package/lib/runtime/components/react/dist/mpx-picker-view/pickerVIewContext.d.ts.map +0 -1
  237. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.d.ts.map +0 -1
  238. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.d.ts.map +0 -1
  239. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.d.ts.map +0 -1
  240. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewFaces.d.ts.map +0 -1
  241. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewIndicator.d.ts.map +0 -1
  242. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewMask.d.ts.map +0 -1
  243. package/lib/runtime/components/react/dist/mpx-popup/index.d.ts.map +0 -1
  244. package/lib/runtime/components/react/dist/mpx-popup/popupBase.d.ts.map +0 -1
  245. package/lib/runtime/components/react/dist/mpx-portal/index.d.ts.map +0 -1
  246. package/lib/runtime/components/react/dist/mpx-portal/portal-host.d.ts.map +0 -1
  247. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.d.ts.map +0 -1
  248. package/lib/runtime/components/react/dist/mpx-progress.d.ts.map +0 -1
  249. package/lib/runtime/components/react/dist/mpx-radio-group.d.ts.map +0 -1
  250. package/lib/runtime/components/react/dist/mpx-radio.d.ts.map +0 -1
  251. package/lib/runtime/components/react/dist/mpx-rich-text/html.d.ts.map +0 -1
  252. package/lib/runtime/components/react/dist/mpx-rich-text/index.d.ts.map +0 -1
  253. package/lib/runtime/components/react/dist/mpx-root-portal.d.ts.map +0 -1
  254. package/lib/runtime/components/react/dist/mpx-scroll-view.d.ts.map +0 -1
  255. package/lib/runtime/components/react/dist/mpx-simple-text.d.ts.map +0 -1
  256. package/lib/runtime/components/react/dist/mpx-simple-view.d.ts.map +0 -1
  257. package/lib/runtime/components/react/dist/mpx-slider.d.ts.map +0 -1
  258. package/lib/runtime/components/react/dist/mpx-sticky-header.d.ts.map +0 -1
  259. package/lib/runtime/components/react/dist/mpx-sticky-section.d.ts.map +0 -1
  260. package/lib/runtime/components/react/dist/mpx-swiper-item.d.ts.map +0 -1
  261. package/lib/runtime/components/react/dist/mpx-swiper.d.ts.map +0 -1
  262. package/lib/runtime/components/react/dist/mpx-switch.d.ts.map +0 -1
  263. package/lib/runtime/components/react/dist/mpx-text.d.ts.map +0 -1
  264. package/lib/runtime/components/react/dist/mpx-textarea.d.ts.map +0 -1
  265. package/lib/runtime/components/react/dist/mpx-video.d.ts.map +0 -1
  266. package/lib/runtime/components/react/dist/mpx-view.d.ts.map +0 -1
  267. package/lib/runtime/components/react/dist/mpx-web-view.d.ts.map +0 -1
  268. package/lib/runtime/components/react/dist/parser.d.ts.map +0 -1
  269. package/lib/runtime/components/react/dist/useAnimationHooks.d.ts +0 -33
  270. package/lib/runtime/components/react/dist/useAnimationHooks.d.ts.map +0 -1
  271. package/lib/runtime/components/react/dist/useAnimationHooks.js +0 -289
  272. package/lib/runtime/components/react/dist/useNodesRef.d.ts.map +0 -1
  273. package/lib/runtime/components/react/dist/utils.d.ts.map +0 -1
  274. package/lib/runtime/components/react/useAnimationHooks.ts +0 -320
  275. package/lib/style-compiler/strip-conditional-loader.js +0 -289
@@ -11,6 +11,11 @@ import Portal from './mpx-portal'
11
11
  /**
12
12
  * ✔ indicator-dots
13
13
  * ✔ indicator-color
14
+ * ✔ indicator-width
15
+ * ✔ indicator-height
16
+ * ✔ indicator-radius
17
+ * ✔ indicator-spacing
18
+ * ✔ indicator-margin
14
19
  * ✔ indicator-active-color
15
20
  * ✔ autoplay
16
21
  * ✔ current
@@ -33,6 +38,10 @@ type EventDataType = {
33
38
  // onUpdate时根据上一个判断方向,onFinalize根据transformStart判断
34
39
  transdir: number
35
40
  }
41
+ // 只基于方向 + offset 计算最终的索引
42
+ type EventEndType = {
43
+ transdir: number
44
+ }
36
45
 
37
46
  interface SwiperProps {
38
47
  children?: ReactNode
@@ -46,6 +55,11 @@ interface SwiperProps {
46
55
  scale?: boolean
47
56
  'indicator-dots'?: boolean
48
57
  'indicator-color'?: string
58
+ 'indicator-width'?: number
59
+ 'indicator-height'?: number
60
+ 'indicator-spacing'?: number
61
+ 'indicator-radius'?: number
62
+ 'indicator-margin'?: number
49
63
  'indicator-active-color'?: string
50
64
  vertical?: boolean
51
65
  style: {
@@ -63,7 +77,9 @@ interface SwiperProps {
63
77
  'wait-for'?: Array<GestureHandler>
64
78
  'simultaneous-handlers'?: Array<GestureHandler>
65
79
  disableGesture?: boolean
80
+ 'display-multiple-items'?: number
66
81
  bindchange?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
82
+ bindchangestart?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
67
83
  }
68
84
 
69
85
  /**
@@ -72,23 +88,23 @@ interface SwiperProps {
72
88
  const styles: { [key: string]: Object } = {
73
89
  pagination_x: {
74
90
  position: 'absolute',
75
- bottom: 25,
91
+ bottom: 0,
76
92
  left: 0,
77
93
  right: 0,
78
94
  flexDirection: 'row',
79
95
  flex: 1,
80
96
  justifyContent: 'center',
81
- alignItems: 'center'
97
+ alignItems: 'flex-end'
82
98
  },
83
99
  pagination_y: {
84
100
  position: 'absolute',
85
- right: 15,
101
+ right: 0,
86
102
  top: 0,
87
103
  bottom: 0,
88
104
  flexDirection: 'column',
89
105
  flex: 1,
90
106
  justifyContent: 'center',
91
- alignItems: 'center'
107
+ alignItems: 'flex-end'
92
108
  },
93
109
  pagerWrapperx: {
94
110
  position: 'absolute',
@@ -109,16 +125,6 @@ const styles: { [key: string]: Object } = {
109
125
  }
110
126
  }
111
127
 
112
- const dotCommonStyle = {
113
- width: 8,
114
- height: 8,
115
- borderRadius: 4,
116
- marginLeft: 3,
117
- marginRight: 3,
118
- marginTop: 3,
119
- marginBottom: 3,
120
- zIndex: 98
121
- }
122
128
  const activeDotStyle = {
123
129
  zIndex: 99
124
130
  }
@@ -136,6 +142,11 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
136
142
  const {
137
143
  'indicator-dots': showPagination,
138
144
  'indicator-color': dotColor = 'rgba(0, 0, 0, .3)',
145
+ 'indicator-width': dotWidth = 8,
146
+ 'indicator-height': dotHeight = 8,
147
+ 'indicator-radius': dotRadius = 4,
148
+ 'indicator-spacing': dotSpacing = 4,
149
+ 'indicator-margin': paginationMargin = 10,
139
150
  'indicator-active-color': activeDotColor = '#000000',
140
151
  'enable-var': enableVar = false,
141
152
  'parent-font-size': parentFontSize,
@@ -149,8 +160,21 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
149
160
  circular = false,
150
161
  disableGesture = false,
151
162
  current: propCurrent = 0,
152
- bindchange
163
+ bindchange,
164
+ bindchangestart
153
165
  } = props
166
+
167
+ const dotCommonStyle = {
168
+ width: dotWidth,
169
+ height: dotHeight,
170
+ borderRadius: dotRadius,
171
+ marginLeft: dotSpacing,
172
+ marginRight: dotSpacing,
173
+ marginTop: dotSpacing,
174
+ marginBottom: dotSpacing,
175
+ zIndex: 98
176
+ }
177
+ const displayMultipleItems = props['display-multiple-items'] || 1
154
178
  const easeingFunc = props['easing-function'] || 'default'
155
179
  const easeDuration = props.duration || 500
156
180
  const horizontal = props.vertical !== undefined ? !props.vertical : true
@@ -184,18 +208,19 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
184
208
  const preMarginShared = useSharedValue(preMargin)
185
209
  const nextMarginShared = useSharedValue(nextMargin)
186
210
  const autoplayShared = useSharedValue(autoplay)
211
+ const children = Array.isArray(props.children) ? props.children.filter(child => child) : (props.children ? [props.children] : [])
187
212
  // 默认前后补位的元素个数
188
- const patchElmNum = circular ? (preMargin ? 2 : 1) : 0
213
+ const patchElmNum = (circular && children.length > 1) ? displayMultipleItems + 1 : 0
189
214
  const patchElmNumShared = useSharedValue(patchElmNum)
215
+ const displayMultipleItemsShared = useSharedValue(displayMultipleItems)
190
216
  const circularShared = useSharedValue(circular)
191
- const children = Array.isArray(props.children) ? props.children.filter(child => child) : (props.children ? [props.children] : [])
192
217
  // 对有变化的变量,在worklet中只能使用sharedValue变量,useRef不能更新
193
218
  const childrenLength = useSharedValue(children.length)
194
219
  const initWidth = typeof normalStyle?.width === 'number' ? normalStyle.width - preMargin - nextMargin : normalStyle.width
195
220
  const initHeight = typeof normalStyle?.height === 'number' ? normalStyle.height - preMargin - nextMargin : normalStyle.height
196
221
  const dir = horizontal === false ? 'y' : 'x'
197
222
  const pstep = dir === 'x' ? initWidth : initHeight
198
- const initStep: number = isNaN(pstep) ? 0 : pstep
223
+ const initStep: number = isNaN(pstep) ? 0 : pstep / displayMultipleItems
199
224
  // 每个元素的宽度 or 高度,有固定值直接初始化无则0
200
225
  const step = useSharedValue(initStep)
201
226
  // 记录选中元素的索引值
@@ -211,8 +236,12 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
211
236
  const preAbsolutePos = useSharedValue(0)
212
237
  // 记录从onBegin 到 onTouchesUp 时移动的距离
213
238
  const moveTranstion = useSharedValue(0)
239
+ // 记录用户手滑动的方向
240
+ const moveDir = useSharedValue(0)
214
241
  const timerId = useRef(0 as number | ReturnType<typeof setTimeout>)
215
242
  const intervalTimer = props.interval || 500
243
+ // 记录是否首次,首次不能触发bindchange回调
244
+ const isFirstRef = useRef(true)
216
245
 
217
246
  const simultaneousHandlers = flatGesture(originSimultaneousHandlers)
218
247
  const waitForHandlers = flatGesture(waitFor)
@@ -252,6 +281,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
252
281
  'style',
253
282
  'indicator-dots',
254
283
  'indicator-color',
284
+ 'indicator-width',
255
285
  'indicator-active-color',
256
286
  'previous-margin',
257
287
  'vertical',
@@ -268,7 +298,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
268
298
  const { width, height } = e.nativeEvent.layout
269
299
  const realWidth = dir === 'x' ? width - preMargin - nextMargin : width
270
300
  const realHeight = dir === 'y' ? height - preMargin - nextMargin : height
271
- const iStep = dir === 'x' ? realWidth : realHeight
301
+ const iStep = (dir === 'x' ? realWidth : realHeight) / displayMultipleItems
272
302
  if (iStep !== step.value) {
273
303
  step.value = iStep
274
304
  updateCurrent(propCurrent, iStep)
@@ -294,8 +324,18 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
294
324
  for (let i = 0; i < children.length; i++) {
295
325
  dots.push(<View style={[dotCommonStyle, { backgroundColor: unActionColor }]} key={i}></View>)
296
326
  }
327
+ let paginationStyle = styles['pagination_' + dir]
328
+ if (paginationMargin) {
329
+ paginationStyle = {
330
+ ...paginationStyle,
331
+ marginBottom: paginationMargin,
332
+ marginLeft: paginationMargin,
333
+ marginRight: paginationMargin,
334
+ marginTop: paginationMargin
335
+ }
336
+ }
297
337
  return (
298
- <View pointerEvents="none" style={styles['pagination_' + dir]}>
338
+ <View pointerEvents="none" style={paginationStyle} key="pagination">
299
339
  <View style={[styles['pagerWrapper' + dir]]}>
300
340
  <Animated.View style={[
301
341
  dotCommonStyle,
@@ -317,18 +357,35 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
317
357
  function renderItems () {
318
358
  const intLen = children.length
319
359
  let renderChild = children.slice()
360
+ // if (circular && intLen > 1) {
361
+ // // 最前面加最后一个元素
362
+ // const lastChild = React.cloneElement(children[intLen - 1] as ReactElement, { key: 'clone0' })
363
+ // // 最后面加第一个元素
364
+ // const firstChild = React.cloneElement(children[0] as ReactElement, { key: 'clone1' })
365
+ // if (preMargin) {
366
+ // const lastChild1 = React.cloneElement(children[intLen - 2] as ReactElement, { key: 'clone2' })
367
+ // const firstChild1 = React.cloneElement(children[1] as ReactElement, { key: 'clone3' })
368
+ // renderChild = [lastChild1, lastChild].concat(renderChild).concat([firstChild, firstChild1])
369
+ // } else {
370
+ // renderChild = [lastChild].concat(renderChild).concat([firstChild])
371
+ // }
372
+ // }
320
373
  if (circular && intLen > 1) {
321
- // 最前面加最后一个元素
322
- const lastChild = React.cloneElement(children[intLen - 1] as ReactElement, { key: 'clone0' })
323
- // 最后面加第一个元素
324
- const firstChild = React.cloneElement(children[0] as ReactElement, { key: 'clone1' })
325
- if (preMargin) {
326
- const lastChild1 = React.cloneElement(children[intLen - 2] as ReactElement, { key: 'clone2' })
327
- const firstChild1 = React.cloneElement(children[1] as ReactElement, { key: 'clone3' })
328
- renderChild = [lastChild1, lastChild].concat(renderChild).concat([firstChild, firstChild1])
329
- } else {
330
- renderChild = [lastChild].concat(renderChild).concat([firstChild])
374
+ // 动态生成前置补位元素
375
+ const frontClones = []
376
+ // 计算补位序列的起始索引。例如 len=3, patch=2 -> start=1 (即从B开始)
377
+ const startIndex = intLen - (patchElmNum % intLen)
378
+ for (let i = 0; i < patchElmNum; i++) {
379
+ const sourceIndex = (startIndex + i) % intLen
380
+ frontClones.push(React.cloneElement(children[sourceIndex], { key: `clone_front_${i}` }))
381
+ }
382
+ // 动态生成后置补位元素
383
+ const backClones = []
384
+ for (let i = 0; i < patchElmNum; i++) {
385
+ const sourceIndex = i % intLen
386
+ backClones.push(React.cloneElement(children[sourceIndex], { key: `clone_back_${i}` }))
331
387
  }
388
+ renderChild = [...frontClones, ...renderChild, ...backClones]
332
389
  }
333
390
  const arrChildren = renderChild.map((child, index) => {
334
391
  const extraStyle = {} as { [key: string]: any }
@@ -363,13 +420,14 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
363
420
  let nextIndex = currentIndex.value
364
421
  if (!circularShared.value) {
365
422
  // 获取下一个位置的坐标, 循环到最后一个元素,直接停止, 取消定时器
366
- if (currentIndex.value === childrenLength.value - 1) {
423
+ if (currentIndex.value === childrenLength.value - displayMultipleItemsShared.value) {
367
424
  pauseLoop()
368
425
  return
369
426
  }
370
427
  nextIndex += 1
371
428
  // targetOffset = -nextIndex * step.value - preMarginShared.value
372
429
  targetOffset = -nextIndex * step.value
430
+ runOnJSCallback('handleSwiperChangeStart', nextIndex)
373
431
  offset.value = withTiming(targetOffset, {
374
432
  duration: easeDuration,
375
433
  easing: easeMap[easeingFunc]
@@ -383,6 +441,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
383
441
  nextIndex = 0
384
442
  targetOffset = -(childrenLength.value + patchElmNumShared.value) * step.value + preMarginShared.value
385
443
  // 执行动画到下一帧
444
+ runOnJSCallback('handleSwiperChangeStart', nextIndex)
386
445
  offset.value = withTiming(targetOffset, {
387
446
  duration: easeDuration
388
447
  }, () => {
@@ -396,6 +455,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
396
455
  nextIndex = currentIndex.value + 1
397
456
  targetOffset = -(nextIndex + patchElmNumShared.value) * step.value + preMarginShared.value
398
457
  // 执行动画到下一帧
458
+ runOnJSCallback('handleSwiperChangeStart', nextIndex)
399
459
  offset.value = withTiming(targetOffset, {
400
460
  duration: easeDuration,
401
461
  easing: easeMap[easeingFunc]
@@ -429,18 +489,22 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
429
489
  }
430
490
  }, [])
431
491
 
432
- function handleSwiperChange (current: number, pCurrent: number) {
433
- if (pCurrent !== currentIndex.value) {
434
- const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef })
435
- bindchange && bindchange(eventData)
436
- }
492
+ function handleSwiperChange (current: number) {
493
+ const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef })
494
+ bindchange && bindchange(eventData)
495
+ }
496
+
497
+ function handleSwiperChangeStart (current: number) {
498
+ const eventData = getCustomEvent('changestart', {}, { detail: { current }, layoutRef: layoutRef })
499
+ bindchangestart && bindchangestart(eventData)
437
500
  }
438
501
 
439
502
  const runOnJSCallbackRef = useRef({
440
503
  loop,
441
504
  pauseLoop,
442
505
  resumeLoop,
443
- handleSwiperChange
506
+ handleSwiperChange,
507
+ handleSwiperChangeStart
444
508
  })
445
509
  const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
446
510
 
@@ -461,6 +525,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
461
525
  if (targetOffset !== offset.value) {
462
526
  // 内部基于props.current!==currentIndex.value决定是否使用动画及更新currentIndex.value
463
527
  if (propCurrent !== undefined && propCurrent !== currentIndex.value) {
528
+ runOnJSCallback('handleSwiperChangeStart', propCurrent)
464
529
  offset.value = withTiming(targetOffset, {
465
530
  duration: easeDuration,
466
531
  easing: easeMap[easeingFunc]
@@ -482,9 +547,10 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
482
547
  // 1. 用户在当前页切换选中项,动画;用户携带选中index打开到swiper页直接选中不走动画
483
548
  useAnimatedReaction(() => currentIndex.value, (newIndex: number, preIndex: number) => {
484
549
  // 这里必须传递函数名, 直接写()=> {}形式会报 访问了未sharedValue信息
485
- if (newIndex !== preIndex && bindchange) {
550
+ if (newIndex !== preIndex && bindchange && !isFirstRef.current) {
486
551
  runOnJS(runOnJSCallback)('handleSwiperChange', newIndex, propCurrent)
487
552
  }
553
+ isFirstRef.current = false
488
554
  })
489
555
 
490
556
  useEffect(() => {
@@ -533,16 +599,17 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
533
599
  }
534
600
  }
535
601
  }, [autoplay])
536
-
537
602
  useEffect(() => {
538
- if (circular !== circularShared.value) {
603
+ if (circular !== circularShared.value || patchElmNum !== patchElmNumShared.value || displayMultipleItems !== displayMultipleItemsShared.value) {
539
604
  circularShared.value = circular
540
- patchElmNumShared.value = circular ? (preMargin ? 2 : 1) : 0
605
+ patchElmNumShared.value = patchElmNum
606
+ displayMultipleItemsShared.value = displayMultipleItems
541
607
  offset.value = getOffset(currentIndex.value, step.value)
542
608
  }
543
- }, [circular, preMargin])
609
+ }, [circular, patchElmNum, displayMultipleItems])
544
610
  const { gestureHandler } = useMemo(() => {
545
- function getTargetPosition (eventData: EventDataType) {
611
+ // 基于transdir + 当前offset计算索引
612
+ function getTargetPosition (eventData: EventEndType) {
546
613
  'worklet'
547
614
  // 移动的距离
548
615
  const { transdir } = eventData
@@ -558,7 +625,8 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
558
625
  const moveToIndex = transdir < 0 ? Math.ceil(computedIndex) : Math.floor(computedIndex)
559
626
  // 实际应该定位的索引值
560
627
  if (!circularShared.value) {
561
- selectedIndex = moveToIndex
628
+ const maxIndex = Math.max(0, childrenLength.value - displayMultipleItemsShared.value)
629
+ selectedIndex = Math.min(Math.max(moveToIndex, 0), maxIndex)
562
630
  moveToTargetPos = selectedIndex * step.value
563
631
  } else {
564
632
  if (moveToIndex >= childrenLength.value + patchElmNumShared.value) {
@@ -591,7 +659,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
591
659
  const gestureMovePos = offset.value + translation
592
660
  if (!circularShared.value) {
593
661
  // 如果只判断区间,中间非滑动状态(handleResistanceMove)向左滑动,突然改为向右滑动,但是还在非滑动态,本应该可滑动判断为了不可滑动
594
- const posEnd = -step.value * (childrenLength.value - 1)
662
+ const posEnd = -step.value * (childrenLength.value - displayMultipleItemsShared.value)
595
663
  if (transdir < 0) {
596
664
  return gestureMovePos > posEnd
597
665
  } else {
@@ -601,7 +669,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
601
669
  return true
602
670
  }
603
671
  }
604
- function handleEnd (eventData: EventDataType) {
672
+ function handleEnd (eventData: EventEndType) {
605
673
  'worklet'
606
674
  const { isCriticalItem, targetOffset, resetOffset, selectedIndex } = getTargetPosition(eventData)
607
675
  if (isCriticalItem) {
@@ -627,7 +695,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
627
695
  })
628
696
  }
629
697
  }
630
- function handleBack (eventData: EventDataType) {
698
+ function handleBack (eventData: EventEndType) {
631
699
  'worklet'
632
700
  const { transdir } = eventData
633
701
  // 向右滑动的back:trans < 0, 向左滑动的back: trans < 0
@@ -648,10 +716,8 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
648
716
  }
649
717
  })
650
718
  }
651
- // 当前的offset和index多对应的offset进行对比,判断是否超过一半
652
- function computeHalf (eventData: EventDataType) {
719
+ function computeHalf () {
653
720
  'worklet'
654
- const { transdir } = eventData
655
721
  const currentOffset = Math.abs(offset.value)
656
722
  let preOffset = (currentIndex.value + patchElmNumShared.value) * step.value
657
723
  if (circularShared.value) {
@@ -660,32 +726,14 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
660
726
  // 正常事件中拿到的translation值(正向滑动<0,倒着滑>0)
661
727
  const diffOffset = preOffset - currentOffset
662
728
  const half = Math.abs(diffOffset) > step.value / 2
663
- const isTriggerUpdateHalf = (transdir < 0 && currentOffset < preOffset) || (transdir > 0 && currentOffset > preOffset)
664
- return {
665
- diffOffset,
666
- half,
667
- isTriggerUpdateHalf
668
- }
669
- }
670
- function handleLongPress (eventData: EventDataType) {
671
- 'worklet'
672
- const { diffOffset, half, isTriggerUpdateHalf } = computeHalf(eventData)
673
- if (+diffOffset === 0) {
674
- runOnJS(runOnJSCallback)('resumeLoop')
675
- } else if (isTriggerUpdateHalf) {
676
- // 如果触发了onUpdate时的索引变更
677
- handleEnd(eventData)
678
- } else if (half) {
679
- handleEnd(eventData)
680
- } else {
681
- handleBack(eventData)
682
- }
729
+ return half
683
730
  }
684
731
  function reachBoundary (eventData: EventDataType) {
685
732
  'worklet'
686
733
  // 1. 基于当前的offset和translation判断是否超过当前边界值
687
734
  const { translation } = eventData
688
- const boundaryStart = -patchElmNumShared.value * step.value
735
+ // 与终点的逻辑对齐,都是超过补位元素对应的起点offset
736
+ const boundaryStart = 0
689
737
  const boundaryEnd = -(childrenLength.value + patchElmNumShared.value) * step.value
690
738
  const moveToOffset = offset.value + translation
691
739
  let isBoundary = false
@@ -702,7 +750,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
702
750
  // 超过边界的距离
703
751
  const exceedLength = Math.abs(boundaryStart) - Math.abs(moveToOffset)
704
752
  // 计算对标正常元素所在的offset
705
- resetOffset = (patchElmNumShared.value + childrenLength.value - 1) * step.value + (step.value - exceedLength)
753
+ resetOffset = (patchElmNumShared.value + childrenLength.value - 1) * step.value - exceedLength
706
754
  }
707
755
  return {
708
756
  isBoundary,
@@ -715,7 +763,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
715
763
  const { translation, transdir } = eventData
716
764
  const moveToOffset = offset.value + translation
717
765
  const maxOverDrag = Math.floor(step.value / 2)
718
- const maxOffset = translation < 0 ? -(childrenLength.value - 1) * step.value : 0
766
+ const maxOffset = translation < 0 ? -(childrenLength.value - displayMultipleItemsShared.value) * step.value : 0
719
767
  let resistance = 0.1
720
768
  let overDrag = 0
721
769
  let finalOffset = 0
@@ -739,6 +787,14 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
739
787
  }
740
788
  return finalOffset
741
789
  }
790
+ // 设置手势移动的方向
791
+ function setMoveDir (curAbsoPos: number) {
792
+ 'worklet'
793
+ const distance = curAbsoPos - preAbsolutePos.value
794
+ if (distance) {
795
+ moveDir.value = curAbsoPos - preAbsolutePos.value
796
+ }
797
+ }
742
798
  const gesturePan = Gesture.Pan()
743
799
  .onBegin((e: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
744
800
  'worklet'
@@ -758,10 +814,13 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
758
814
  transdir: moveDistance
759
815
  }
760
816
  // 1. 支持滑动中超出一半更新索引的能力:只更新索引并不会影响onFinalize依据当前offset计算的索引
761
- const { half } = computeHalf(eventData)
762
- if (childrenLength.value > 1 && half) {
763
- const { selectedIndex } = getTargetPosition(eventData)
764
- currentIndex.value = selectedIndex
817
+ const offsetHalf = computeHalf()
818
+ if (childrenLength.value > 1 && offsetHalf) {
819
+ const { selectedIndex } = getTargetPosition({ transdir: moveDistance } as EventEndType)
820
+ if (selectedIndex !== currentIndex.value) {
821
+ currentIndex.value = selectedIndex
822
+ runOnJS(runOnJSCallback)('handleSwiperChangeStart', selectedIndex)
823
+ }
765
824
  }
766
825
  // 2. 非循环: 处理用户一直拖拽到临界点的场景,如果放到onFinalize无法阻止offset.value更新为越界的值
767
826
  if (!circularShared.value) {
@@ -771,6 +830,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
771
830
  const finalOffset = handleResistanceMove(eventData)
772
831
  offset.value = finalOffset
773
832
  }
833
+ setMoveDir(e[strAbso])
774
834
  preAbsolutePos.value = e[strAbso]
775
835
  return
776
836
  }
@@ -778,6 +838,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
778
838
  if (circularShared.value && childrenLength.value === 1) {
779
839
  const finalOffset = handleResistanceMove(eventData)
780
840
  offset.value = finalOffset
841
+ setMoveDir(e[strAbso])
781
842
  preAbsolutePos.value = e[strAbso]
782
843
  return
783
844
  }
@@ -788,6 +849,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
788
849
  } else {
789
850
  offset.value = moveDistance + offset.value
790
851
  }
852
+ setMoveDir(e[strAbso])
791
853
  preAbsolutePos.value = e[strAbso]
792
854
  })
793
855
  .onFinalize((e: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
@@ -795,10 +857,21 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
795
857
  if (touchfinish.value) return
796
858
  touchfinish.value = true
797
859
  // 触发过onUpdate正常情况下e[strAbso] - preAbsolutePos.value=0; 未触发过onUpdate的情况下e[strAbso] - preAbsolutePos.value 不为0
860
+ // 正常状态下基于onUpdate时的moveDir判断方向、未触发onUpdate的则基于onBegin的moveTranstion判断方向
798
861
  const moveDistance = e[strAbso] - preAbsolutePos.value
862
+ // 默认兜底方向: 以onBegin为起点,因一些原因未触发onUpdate但是触发了位移
863
+ const defaultDir = e[strAbso] - moveTranstion.value
864
+ // 实时方向:方向基于onUpdate时的方向,滑动的速度超过阈值时基于实时的滑动方向计算
865
+ const realtimeData = {
866
+ transdir: moveDir.value || defaultDir
867
+ }
868
+ // 起始方向:基于用户起始手势
869
+ const originData = {
870
+ transdir: defaultDir
871
+ }
799
872
  const eventData = {
800
873
  translation: moveDistance,
801
- transdir: moveDistance !== 0 ? moveDistance : e[strAbso] - moveTranstion.value
874
+ transdir: realtimeData.transdir
802
875
  }
803
876
  // 1. 只有一个元素:循环 和 非循环状态,都走回弹效果
804
877
  if (childrenLength.value === 1) {
@@ -812,19 +885,35 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
812
885
  // 非循环支持最后元素可滑动能力后,向左快速移动未超过最大可移动范围一半,因为offset为正值,向左滑动handleBack,默认向上取整
813
886
  // 但是在offset大于0时,取0。[-100, 0](back取0), [0, 100](back取1), 所以handleLongPress里的处理逻辑需要兼容支持,因此这里直接单独处理,不耦合下方公共的判断逻辑。
814
887
  if (!circularShared.value && !canMove(eventData)) {
815
- if (eventData.transdir < 0) {
816
- handleBack(eventData)
888
+ if (realtimeData.transdir < 0) {
889
+ handleBack(realtimeData)
817
890
  } else {
818
- handleEnd(eventData)
891
+ handleEnd(realtimeData)
819
892
  }
820
893
  return
821
894
  }
822
895
  // 3. 非循环状态可移动态、循环状态, 正常逻辑处理
823
896
  const velocity = e[strVelocity]
824
- if (Math.abs(velocity) < longPressRatio) {
825
- handleLongPress(eventData)
897
+ // 用于判断是否超过一半,基于索引判断是否超过一半不可行(1.滑动过程中索引会变更导致计算反向, 2.边界场景会更新offset也会导致基于索引+offset判断实效)
898
+ const tmp = offset.value % step.value > step.value / 2
899
+ // 小于0手向左滑动
900
+ const offsetHalf = originData.transdir < 0 ? tmp : !tmp
901
+ if (offsetHalf) {
902
+ if (Math.abs(velocity) > longPressRatio) {
903
+ // 超过速度阈值,按照实时方向(快速来回滑动)
904
+ handleEnd(realtimeData)
905
+ } else {
906
+ // 超过速度阈值,按照起始方向(慢速长按)
907
+ handleEnd(originData)
908
+ }
826
909
  } else {
827
- handleEnd(eventData)
910
+ if (Math.abs(velocity) > longPressRatio) {
911
+ // 超过速度阈值,按照实时方向(快速来回滑动)
912
+ handleEnd(realtimeData)
913
+ } else {
914
+ // 超过速度阈值,按照起始方向(慢速长按)
915
+ handleBack(originData)
916
+ }
828
917
  }
829
918
  })
830
919
  .withRef(swiperGestureRef)
@@ -861,6 +950,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
861
950
  style: [normalStyle, layoutStyle, styles.swiper]
862
951
  }, layoutProps, innerProps)
863
952
  const animateComponent = createElement(Animated.View, {
953
+ key: 'swiperContainer',
864
954
  style: [{ flexDirection: dir === 'x' ? 'row' : 'column', width: '100%', height: '100%' }, animatedStyles]
865
955
  }, wrapChildren({
866
956
  children: arrPages
@@ -4,6 +4,7 @@
4
4
  * type, password, confirm-hold
5
5
  * Addition:
6
6
  * ✔ confirm-type
7
+ * ✘ confirm-hold
7
8
  * ✔ auto-height
8
9
  * ✘ fixed
9
10
  * ✘ show-confirm-bar
@@ -8,8 +8,8 @@ import { View, TextStyle, NativeSyntheticEvent, ViewProps, ImageStyle, StyleShee
8
8
  import { useRef, useState, useEffect, forwardRef, ReactNode, JSX, createElement } from 'react'
9
9
  import useInnerProps from './getInnerListeners'
10
10
  import Animated from 'react-native-reanimated'
11
- import useAnimationHooks from './useAnimationHooks'
12
- import type { AnimationProp } from './useAnimationHooks'
11
+ import useAnimationHooks, { AnimationType } from './animationHooks/index'
12
+ import type { AnimationProp } from './animationHooks/utils'
13
13
  import { ExtendedViewStyle } from './types/common'
14
14
  import useNodesRef, { HandlerRef } from './useNodesRef'
15
15
  import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle, extendObject, useHover } from './utils'
@@ -32,7 +32,7 @@ export interface _ViewProps extends ViewProps {
32
32
  'parent-font-size'?: number
33
33
  'parent-width'?: number
34
34
  'parent-height'?: number
35
- 'enable-animation'?: boolean
35
+ 'enable-animation'?: boolean | AnimationType
36
36
  bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
37
37
  bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
38
38
  bindtouchend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
@@ -287,7 +287,7 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
287
287
  } else { // 数值类型 ImageStyle
288
288
  // 数值类型设置为 stretch
289
289
  imageProps.resizeMode = 'stretch'
290
- if (type === 'linear' && (!layoutWidth || !layoutHeight)) {
290
+ if (type === 'linear' && (!layoutWidth || !layoutHeight) && (isPercent(width) || isPercent(height))) {
291
291
  // ios 上 linear 组件只要重新触发渲染,在渲染过程中外层容器 width 或者 height 被设置为 0,通过设置 % 的方式会渲染不出来,即使后面再更新为正常宽高也渲染不出来
292
292
  // 所以 hack 手动先将 linear 宽高也设置为 0,后面再更新为正确的数值或 %。
293
293
  dimensions = {
@@ -369,6 +369,17 @@ function normalizeBackgroundPosition (parts: PositionVal[]): backgroundPositionL
369
369
  let vStart: 'top' | 'bottom' = 'top'
370
370
  let vOffset: PositionVal = 0
371
371
 
372
+ if (!Array.isArray(parts)) {
373
+ // 模板 style 属性传入单个数值时不会和 class 一样转成数组,需要手动转换
374
+ parts = [parts]
375
+ }
376
+ // 模板 style 属性传入时, 需要额外转换处理单位 px/rpx/vh 以及 center 转化为 50%
377
+ parts = (parts as (PositionVal | string)[]).map((part) => {
378
+ if (typeof part !== 'string') return part
379
+ if (part === 'center') return '50%'
380
+ return global.__formatValue(part) as PositionVal
381
+ })
382
+
372
383
  if (parts.length === 4) return parts as backgroundPositionList
373
384
 
374
385
  // 归一化
@@ -514,19 +525,24 @@ function parseBgImage (text: string): {
514
525
  }
515
526
  }
516
527
 
517
- function normalizeBackgroundSize (backgroundSize: Exclude<ExtendedViewStyle['backgroundSize'], undefined>, type: 'image' | 'linear' | undefined) {
528
+ function normalizeBackgroundSize (
529
+ backgroundSize: NonNullable<ExtendedViewStyle['backgroundSize']>,
530
+ type: 'image' | 'linear' | undefined
531
+ ): DimensionValue[] {
518
532
  const sizeList = backgroundSize.slice()
519
533
  if (sizeList.length === 1) sizeList.push('auto')
520
534
 
521
- if (type === 'linear') {
535
+ return sizeList.map((val) => {
536
+ if (typeof val !== 'string') return val
537
+
522
538
  // 处理当使用渐变的时候,background-size出现cover, contain, auto,当作100%处理
523
- for (const i in sizeList) {
524
- const val = sizeList[i]
525
- sizeList[i] = /^cover|contain|auto$/.test(val as string) ? '100%' : val
539
+ if (type === 'linear' && /^cover|contain|auto$/.test(val)) {
540
+ val = '100%'
526
541
  }
527
- }
528
542
 
529
- return sizeList
543
+ // 模板 style 属性传入时, 需要额外转换处理单位 px/rpx/vh
544
+ return global.__formatValue(val) as DimensionValue
545
+ })
530
546
  }
531
547
 
532
548
  function preParseImage (imageStyle?: ExtendedViewStyle) {
@@ -777,7 +793,6 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
777
793
  ref: nodeRef,
778
794
  style: enableStyleAnimation ? [viewStyle, animationStyle] : viewStyle
779
795
  }
780
-
781
796
  ),
782
797
  [
783
798
  'hover-start-time',