@greypan/web-ui 11.2.0 → 12.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 (667) hide show
  1. package/README.CN.md +79 -68
  2. package/README.md +81 -72
  3. package/dist/_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js +8 -0
  4. package/dist/assets/menu-portal.js +3 -4
  5. package/dist/assets/menu-portal.js.map +1 -1
  6. package/dist/assets/modal-surface.js +3 -4
  7. package/dist/assets/modal-surface.js.map +1 -1
  8. package/dist/assets/overlay-motion.js +3 -4
  9. package/dist/assets/overlay-motion.js.map +1 -1
  10. package/dist/assets/scrollbar.js +5 -0
  11. package/dist/assets/scrollbar.js.map +1 -0
  12. package/dist/assets/selection-control.js +3 -4
  13. package/dist/assets/selection-control.js.map +1 -1
  14. package/dist/assets/toast-containers.js +3 -4
  15. package/dist/assets/toast-containers.js.map +1 -1
  16. package/dist/classes/glass.js +3 -4
  17. package/dist/classes/glass.js.map +1 -1
  18. package/dist/classes/glow.js +3 -4
  19. package/dist/classes/glow.js.map +1 -1
  20. package/dist/components/autocomplete/index.d.ts +485 -483
  21. package/dist/components/autocomplete/index.d.ts.map +1 -0
  22. package/dist/components/autocomplete/index.js +475 -267
  23. package/dist/components/autocomplete/index.js.map +1 -1
  24. package/dist/components/autocomplete/style.js +3 -4
  25. package/dist/components/autocomplete/style.js.map +1 -1
  26. package/dist/components/avatar/index.d.ts +26 -24
  27. package/dist/components/avatar/index.d.ts.map +1 -0
  28. package/dist/components/avatar/index.js +72 -52
  29. package/dist/components/avatar/index.js.map +1 -1
  30. package/dist/components/avatar/style.js +3 -4
  31. package/dist/components/avatar/style.js.map +1 -1
  32. package/dist/components/back-top/index.d.ts +30 -27
  33. package/dist/components/back-top/index.d.ts.map +1 -0
  34. package/dist/components/back-top/index.js +96 -62
  35. package/dist/components/back-top/index.js.map +1 -1
  36. package/dist/components/back-top/style.js +3 -4
  37. package/dist/components/back-top/style.js.map +1 -1
  38. package/dist/components/badge/index.d.ts +32 -26
  39. package/dist/components/badge/index.d.ts.map +1 -0
  40. package/dist/components/badge/index.js +116 -74
  41. package/dist/components/badge/index.js.map +1 -1
  42. package/dist/components/badge/style.js +3 -4
  43. package/dist/components/badge/style.js.map +1 -1
  44. package/dist/components/button/index.d.ts +392 -390
  45. package/dist/components/button/index.d.ts.map +1 -0
  46. package/dist/components/button/index.js +108 -74
  47. package/dist/components/button/index.js.map +1 -1
  48. package/dist/components/button/style.js +3 -4
  49. package/dist/components/button/style.js.map +1 -1
  50. package/dist/components/button-group/index.d.ts +14 -13
  51. package/dist/components/button-group/index.d.ts.map +1 -0
  52. package/dist/components/button-group/index.js +43 -33
  53. package/dist/components/button-group/index.js.map +1 -1
  54. package/dist/components/button-group/style.js +3 -4
  55. package/dist/components/button-group/style.js.map +1 -1
  56. package/dist/components/checkbox/index.d.ts +399 -397
  57. package/dist/components/checkbox/index.d.ts.map +1 -0
  58. package/dist/components/checkbox/index.js +103 -74
  59. package/dist/components/checkbox/index.js.map +1 -1
  60. package/dist/components/checkbox/style.js +3 -4
  61. package/dist/components/checkbox/style.js.map +1 -1
  62. package/dist/components/checkbox-group/index.d.ts +397 -396
  63. package/dist/components/checkbox-group/index.d.ts.map +1 -0
  64. package/dist/components/checkbox-group/index.js +92 -70
  65. package/dist/components/checkbox-group/index.js.map +1 -1
  66. package/dist/components/checkbox-group/style.js +3 -4
  67. package/dist/components/checkbox-group/style.js.map +1 -1
  68. package/dist/components/collapse/index.d.ts +74 -73
  69. package/dist/components/collapse/index.d.ts.map +1 -0
  70. package/dist/components/collapse/index.js +225 -130
  71. package/dist/components/collapse/index.js.map +1 -1
  72. package/dist/components/collapse/style.js +3 -4
  73. package/dist/components/collapse/style.js.map +1 -1
  74. package/dist/components/context-menu/index.d.ts +307 -310
  75. package/dist/components/context-menu/index.d.ts.map +1 -0
  76. package/dist/components/context-menu/index.js +685 -270
  77. package/dist/components/context-menu/index.js.map +1 -1
  78. package/dist/components/context-menu/scrim.js +3 -4
  79. package/dist/components/context-menu/scrim.js.map +1 -1
  80. package/dist/components/context-menu/style.js +3 -4
  81. package/dist/components/context-menu/style.js.map +1 -1
  82. package/dist/components/dialog/index.d.ts +87 -78
  83. package/dist/components/dialog/index.d.ts.map +1 -0
  84. package/dist/components/dialog/index.js +183 -88
  85. package/dist/components/dialog/index.js.map +1 -1
  86. package/dist/components/dialog/style.js +3 -4
  87. package/dist/components/dialog/style.js.map +1 -1
  88. package/dist/components/drawer/index.d.ts +159 -150
  89. package/dist/components/drawer/index.d.ts.map +1 -0
  90. package/dist/components/drawer/index.js +503 -242
  91. package/dist/components/drawer/index.js.map +1 -1
  92. package/dist/components/drawer/style.js +3 -4
  93. package/dist/components/drawer/style.js.map +1 -1
  94. package/dist/components/dropdown/index.d.ts +125 -124
  95. package/dist/components/dropdown/index.d.ts.map +1 -0
  96. package/dist/components/dropdown/index.js +556 -328
  97. package/dist/components/dropdown/index.js.map +1 -1
  98. package/dist/components/dropdown/style.js +3 -4
  99. package/dist/components/dropdown/style.js.map +1 -1
  100. package/dist/components/dropdown-divider/index.d.ts +7 -6
  101. package/dist/components/dropdown-divider/index.d.ts.map +1 -0
  102. package/dist/components/dropdown-divider/index.js +10 -11
  103. package/dist/components/dropdown-divider/index.js.map +1 -1
  104. package/dist/components/dropdown-divider/style.js +3 -4
  105. package/dist/components/dropdown-divider/style.js.map +1 -1
  106. package/dist/components/dropdown-header/index.d.ts +7 -6
  107. package/dist/components/dropdown-header/index.d.ts.map +1 -0
  108. package/dist/components/dropdown-header/index.js +10 -11
  109. package/dist/components/dropdown-header/index.js.map +1 -1
  110. package/dist/components/dropdown-header/style.js +3 -4
  111. package/dist/components/dropdown-header/style.js.map +1 -1
  112. package/dist/components/dropdown-item/index.d.ts +13 -11
  113. package/dist/components/dropdown-item/index.d.ts.map +1 -0
  114. package/dist/components/dropdown-item/index.js +32 -25
  115. package/dist/components/dropdown-item/index.js.map +1 -1
  116. package/dist/components/dropdown-item/style.js +3 -4
  117. package/dist/components/dropdown-item/style.js.map +1 -1
  118. package/dist/components/editable-text/index.d.ts +506 -505
  119. package/dist/components/editable-text/index.d.ts.map +1 -0
  120. package/dist/components/editable-text/index.js +281 -127
  121. package/dist/components/editable-text/index.js.map +1 -1
  122. package/dist/components/editable-text/style.js +3 -4
  123. package/dist/components/editable-text/style.js.map +1 -1
  124. package/dist/components/empty/index.d.ts +17 -15
  125. package/dist/components/empty/index.d.ts.map +1 -0
  126. package/dist/components/empty/index.js +66 -37
  127. package/dist/components/empty/index.js.map +1 -1
  128. package/dist/components/empty/style.js +3 -4
  129. package/dist/components/empty/style.js.map +1 -1
  130. package/dist/components/icon/index.d.ts +12 -11
  131. package/dist/components/icon/index.d.ts.map +1 -0
  132. package/dist/components/icon/index.js +34 -27
  133. package/dist/components/icon/index.js.map +1 -1
  134. package/dist/components/icon/style.js +3 -4
  135. package/dist/components/icon/style.js.map +1 -1
  136. package/dist/components/image-preview/index.d.ts +58 -44
  137. package/dist/components/image-preview/index.d.ts.map +1 -0
  138. package/dist/components/image-preview/index.js +536 -265
  139. package/dist/components/image-preview/index.js.map +1 -1
  140. package/dist/components/image-preview/style.js +3 -4
  141. package/dist/components/image-preview/style.js.map +1 -1
  142. package/dist/components/index.d.ts +46 -43
  143. package/dist/components/index.d.ts.map +1 -0
  144. package/dist/components/index.js +41 -41
  145. package/dist/components/input/index.d.ts +418 -413
  146. package/dist/components/input/index.d.ts.map +1 -0
  147. package/dist/components/input/index.js +148 -84
  148. package/dist/components/input/index.js.map +1 -1
  149. package/dist/components/input/style.js +3 -4
  150. package/dist/components/input/style.js.map +1 -1
  151. package/dist/components/input-number/index.d.ts +453 -447
  152. package/dist/components/input-number/index.d.ts.map +1 -0
  153. package/dist/components/input-number/index.js +484 -292
  154. package/dist/components/input-number/index.js.map +1 -1
  155. package/dist/components/input-number/style.js +3 -4
  156. package/dist/components/input-number/style.js.map +1 -1
  157. package/dist/components/layout/index.d.ts +110 -87
  158. package/dist/components/layout/index.d.ts.map +1 -0
  159. package/dist/components/layout/index.js +238 -144
  160. package/dist/components/layout/index.js.map +1 -1
  161. package/dist/components/layout/style.js +3 -4
  162. package/dist/components/layout/style.js.map +1 -1
  163. package/dist/components/middle-ellipsis/index.d.ts +93 -92
  164. package/dist/components/middle-ellipsis/index.d.ts.map +1 -0
  165. package/dist/components/middle-ellipsis/index.js +261 -107
  166. package/dist/components/middle-ellipsis/index.js.map +1 -1
  167. package/dist/components/middle-ellipsis/style.js +3 -4
  168. package/dist/components/middle-ellipsis/style.js.map +1 -1
  169. package/dist/components/middle-ellipsis/truncate.js +60 -30
  170. package/dist/components/middle-ellipsis/truncate.js.map +1 -1
  171. package/dist/components/option/index.d.ts +20 -18
  172. package/dist/components/option/index.d.ts.map +1 -0
  173. package/dist/components/option/index.js +53 -40
  174. package/dist/components/option/index.js.map +1 -1
  175. package/dist/components/option/style.js +3 -4
  176. package/dist/components/option/style.js.map +1 -1
  177. package/dist/components/popover/index.d.ts +69 -68
  178. package/dist/components/popover/index.d.ts.map +1 -0
  179. package/dist/components/popover/index.js +221 -104
  180. package/dist/components/popover/index.js.map +1 -1
  181. package/dist/components/popover/style.js +3 -4
  182. package/dist/components/popover/style.js.map +1 -1
  183. package/dist/components/radio/index.d.ts +396 -395
  184. package/dist/components/radio/index.d.ts.map +1 -0
  185. package/dist/components/radio/index.js +91 -62
  186. package/dist/components/radio/index.js.map +1 -1
  187. package/dist/components/radio/interaction.js +10 -11
  188. package/dist/components/radio/interaction.js.map +1 -1
  189. package/dist/components/radio/style.js +3 -4
  190. package/dist/components/radio/style.js.map +1 -1
  191. package/dist/components/radio-group/index.d.ts +417 -416
  192. package/dist/components/radio-group/index.d.ts.map +1 -0
  193. package/dist/components/radio-group/index.js +307 -207
  194. package/dist/components/radio-group/index.js.map +1 -1
  195. package/dist/components/radio-group/style.js +3 -4
  196. package/dist/components/radio-group/style.js.map +1 -1
  197. package/dist/components/segmented/index.d.ts +408 -402
  198. package/dist/components/segmented/index.d.ts.map +1 -0
  199. package/dist/components/segmented/index.js +267 -158
  200. package/dist/components/segmented/index.js.map +1 -1
  201. package/dist/components/segmented/style.js +3 -4
  202. package/dist/components/segmented/style.js.map +1 -1
  203. package/dist/components/segmented-trigger/index.d.ts +18 -17
  204. package/dist/components/segmented-trigger/index.d.ts.map +1 -0
  205. package/dist/components/segmented-trigger/index.js +45 -36
  206. package/dist/components/segmented-trigger/index.js.map +1 -1
  207. package/dist/components/segmented-trigger/style.js +3 -4
  208. package/dist/components/segmented-trigger/style.js.map +1 -1
  209. package/dist/components/select/index.d.ts +450 -448
  210. package/dist/components/select/index.d.ts.map +1 -0
  211. package/dist/components/select/index.js +342 -188
  212. package/dist/components/select/index.js.map +1 -1
  213. package/dist/components/select/style.js +3 -4
  214. package/dist/components/select/style.js.map +1 -1
  215. package/dist/components/slider/index.d.ts +428 -427
  216. package/dist/components/slider/index.d.ts.map +1 -0
  217. package/dist/components/slider/index.js +308 -216
  218. package/dist/components/slider/index.js.map +1 -1
  219. package/dist/components/slider/style.js +3 -4
  220. package/dist/components/slider/style.js.map +1 -1
  221. package/dist/components/spinner/index.d.ts +39 -38
  222. package/dist/components/spinner/index.d.ts.map +1 -0
  223. package/dist/components/spinner/index.js +118 -65
  224. package/dist/components/spinner/index.js.map +1 -1
  225. package/dist/components/spinner/style.js +3 -4
  226. package/dist/components/spinner/style.js.map +1 -1
  227. package/dist/components/svg-draw-lines/index.d.ts +40 -39
  228. package/dist/components/svg-draw-lines/index.d.ts.map +1 -0
  229. package/dist/components/svg-draw-lines/index.js +189 -106
  230. package/dist/components/svg-draw-lines/index.js.map +1 -1
  231. package/dist/components/svg-draw-lines/style.js +3 -4
  232. package/dist/components/svg-draw-lines/style.js.map +1 -1
  233. package/dist/components/switch/index.d.ts +411 -409
  234. package/dist/components/switch/index.d.ts.map +1 -0
  235. package/dist/components/switch/index.js +193 -106
  236. package/dist/components/switch/index.js.map +1 -1
  237. package/dist/components/switch/style.js +3 -4
  238. package/dist/components/switch/style.js.map +1 -1
  239. package/dist/components/textarea/index.d.ts +430 -425
  240. package/dist/components/textarea/index.d.ts.map +1 -0
  241. package/dist/components/textarea/index.js +187 -100
  242. package/dist/components/textarea/index.js.map +1 -1
  243. package/dist/components/textarea/style.js +3 -4
  244. package/dist/components/textarea/style.js.map +1 -1
  245. package/dist/components/theme/index.d.ts +45 -44
  246. package/dist/components/theme/index.d.ts.map +1 -0
  247. package/dist/components/theme/index.js +268 -161
  248. package/dist/components/theme/index.js.map +1 -1
  249. package/dist/components/theme/style.js +3 -4
  250. package/dist/components/theme/style.js.map +1 -1
  251. package/dist/components/toast/index.d.ts +4 -3
  252. package/dist/components/toast/index.js +3 -3
  253. package/dist/components/toast/manager.d.ts +9 -8
  254. package/dist/components/toast/manager.d.ts.map +1 -0
  255. package/dist/components/toast/manager.js +215 -119
  256. package/dist/components/toast/manager.js.map +1 -1
  257. package/dist/components/toast/style.js +3 -4
  258. package/dist/components/toast/style.js.map +1 -1
  259. package/dist/components/toast/toast.d.ts +75 -71
  260. package/dist/components/toast/toast.d.ts.map +1 -0
  261. package/dist/components/toast/toast.js +203 -96
  262. package/dist/components/toast/toast.js.map +1 -1
  263. package/dist/components/toast/types.d.ts +10 -9
  264. package/dist/components/toast/types.d.ts.map +1 -0
  265. package/dist/components/tooltip/index.d.ts +72 -62
  266. package/dist/components/tooltip/index.d.ts.map +1 -0
  267. package/dist/components/tooltip/index.js +251 -93
  268. package/dist/components/tooltip/index.js.map +1 -1
  269. package/dist/components/tooltip/style.js +3 -4
  270. package/dist/components/tooltip/style.js.map +1 -1
  271. package/dist/icons/generated/akar-icons-check.d.ts +5 -4
  272. package/dist/icons/generated/akar-icons-check.d.ts.map +1 -0
  273. package/dist/icons/generated/akar-icons-check.js +3 -4
  274. package/dist/icons/generated/akar-icons-check.js.map +1 -1
  275. package/dist/icons/generated/akar-icons-circle-check.d.ts +5 -4
  276. package/dist/icons/generated/akar-icons-circle-check.d.ts.map +1 -0
  277. package/dist/icons/generated/akar-icons-circle-check.js +3 -4
  278. package/dist/icons/generated/akar-icons-circle-check.js.map +1 -1
  279. package/dist/icons/generated/andrsrxn-inbox.d.ts +5 -4
  280. package/dist/icons/generated/andrsrxn-inbox.d.ts.map +1 -0
  281. package/dist/icons/generated/andrsrxn-inbox.js +3 -4
  282. package/dist/icons/generated/andrsrxn-inbox.js.map +1 -1
  283. package/dist/icons/generated/bi-check-lg.d.ts +5 -4
  284. package/dist/icons/generated/bi-check-lg.d.ts.map +1 -0
  285. package/dist/icons/generated/bi-check-lg.js +3 -4
  286. package/dist/icons/generated/bi-check-lg.js.map +1 -1
  287. package/dist/icons/generated/bi-check.d.ts +5 -4
  288. package/dist/icons/generated/bi-check.d.ts.map +1 -0
  289. package/dist/icons/generated/bi-check.js +3 -4
  290. package/dist/icons/generated/bi-check.js.map +1 -1
  291. package/dist/icons/generated/fluent-tag-search-24-regular.d.ts +5 -4
  292. package/dist/icons/generated/fluent-tag-search-24-regular.d.ts.map +1 -0
  293. package/dist/icons/generated/fluent-tag-search-24-regular.js +3 -4
  294. package/dist/icons/generated/fluent-tag-search-24-regular.js.map +1 -1
  295. package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.d.ts +5 -4
  296. package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.d.ts.map +1 -0
  297. package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.js +3 -4
  298. package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.js.map +1 -1
  299. package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.d.ts +5 -4
  300. package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.d.ts.map +1 -0
  301. package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.js +3 -4
  302. package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.js.map +1 -1
  303. package/dist/icons/generated/heroicons-check-16-solid.d.ts +5 -4
  304. package/dist/icons/generated/heroicons-check-16-solid.d.ts.map +1 -0
  305. package/dist/icons/generated/heroicons-check-16-solid.js +3 -4
  306. package/dist/icons/generated/heroicons-check-16-solid.js.map +1 -1
  307. package/dist/icons/generated/heroicons-x-mark-16-solid.d.ts +5 -4
  308. package/dist/icons/generated/heroicons-x-mark-16-solid.d.ts.map +1 -0
  309. package/dist/icons/generated/heroicons-x-mark-16-solid.js +3 -4
  310. package/dist/icons/generated/heroicons-x-mark-16-solid.js.map +1 -1
  311. package/dist/icons/generated/jam-close-circle-f.d.ts +7 -6
  312. package/dist/icons/generated/jam-close-circle-f.d.ts.map +1 -0
  313. package/dist/icons/generated/jam-close-circle-f.js +3 -4
  314. package/dist/icons/generated/jam-close-circle-f.js.map +1 -1
  315. package/dist/icons/generated/lucide-arrow-down-to-line.d.ts +5 -4
  316. package/dist/icons/generated/lucide-arrow-down-to-line.d.ts.map +1 -0
  317. package/dist/icons/generated/lucide-arrow-down-to-line.js +3 -4
  318. package/dist/icons/generated/lucide-arrow-down-to-line.js.map +1 -1
  319. package/dist/icons/generated/lucide-arrow-up-to-line.d.ts +5 -4
  320. package/dist/icons/generated/lucide-arrow-up-to-line.d.ts.map +1 -0
  321. package/dist/icons/generated/lucide-arrow-up-to-line.js +3 -4
  322. package/dist/icons/generated/lucide-arrow-up-to-line.js.map +1 -1
  323. package/dist/icons/generated/lucide-bell.d.ts +5 -4
  324. package/dist/icons/generated/lucide-bell.d.ts.map +1 -0
  325. package/dist/icons/generated/lucide-bell.js +3 -4
  326. package/dist/icons/generated/lucide-bell.js.map +1 -1
  327. package/dist/icons/generated/lucide-check.d.ts +5 -4
  328. package/dist/icons/generated/lucide-check.d.ts.map +1 -0
  329. package/dist/icons/generated/lucide-check.js +3 -4
  330. package/dist/icons/generated/lucide-check.js.map +1 -1
  331. package/dist/icons/generated/lucide-chevron-down.d.ts +5 -4
  332. package/dist/icons/generated/lucide-chevron-down.d.ts.map +1 -0
  333. package/dist/icons/generated/lucide-chevron-down.js +3 -4
  334. package/dist/icons/generated/lucide-chevron-down.js.map +1 -1
  335. package/dist/icons/generated/lucide-chevron-left.d.ts +5 -4
  336. package/dist/icons/generated/lucide-chevron-left.d.ts.map +1 -0
  337. package/dist/icons/generated/lucide-chevron-left.js +3 -4
  338. package/dist/icons/generated/lucide-chevron-left.js.map +1 -1
  339. package/dist/icons/generated/lucide-chevron-right.d.ts +5 -4
  340. package/dist/icons/generated/lucide-chevron-right.d.ts.map +1 -0
  341. package/dist/icons/generated/lucide-chevron-right.js +3 -4
  342. package/dist/icons/generated/lucide-chevron-right.js.map +1 -1
  343. package/dist/icons/generated/lucide-chevron-up.d.ts +5 -4
  344. package/dist/icons/generated/lucide-chevron-up.d.ts.map +1 -0
  345. package/dist/icons/generated/lucide-chevron-up.js +3 -4
  346. package/dist/icons/generated/lucide-chevron-up.js.map +1 -1
  347. package/dist/icons/generated/lucide-circle-alert.d.ts +5 -4
  348. package/dist/icons/generated/lucide-circle-alert.d.ts.map +1 -0
  349. package/dist/icons/generated/lucide-circle-alert.js +3 -4
  350. package/dist/icons/generated/lucide-circle-alert.js.map +1 -1
  351. package/dist/icons/generated/lucide-clapperboard.d.ts +5 -4
  352. package/dist/icons/generated/lucide-clapperboard.d.ts.map +1 -0
  353. package/dist/icons/generated/lucide-clapperboard.js +3 -4
  354. package/dist/icons/generated/lucide-clapperboard.js.map +1 -1
  355. package/dist/icons/generated/lucide-clipboard-paste.d.ts +5 -4
  356. package/dist/icons/generated/lucide-clipboard-paste.d.ts.map +1 -0
  357. package/dist/icons/generated/lucide-clipboard-paste.js +3 -4
  358. package/dist/icons/generated/lucide-clipboard-paste.js.map +1 -1
  359. package/dist/icons/generated/lucide-code.d.ts +5 -4
  360. package/dist/icons/generated/lucide-code.d.ts.map +1 -0
  361. package/dist/icons/generated/lucide-code.js +3 -4
  362. package/dist/icons/generated/lucide-code.js.map +1 -1
  363. package/dist/icons/generated/lucide-copy.d.ts +5 -4
  364. package/dist/icons/generated/lucide-copy.d.ts.map +1 -0
  365. package/dist/icons/generated/lucide-copy.js +3 -4
  366. package/dist/icons/generated/lucide-copy.js.map +1 -1
  367. package/dist/icons/generated/lucide-download.d.ts +5 -4
  368. package/dist/icons/generated/lucide-download.d.ts.map +1 -0
  369. package/dist/icons/generated/lucide-download.js +3 -4
  370. package/dist/icons/generated/lucide-download.js.map +1 -1
  371. package/dist/icons/generated/lucide-ellipsis-vertical.d.ts +5 -4
  372. package/dist/icons/generated/lucide-ellipsis-vertical.d.ts.map +1 -0
  373. package/dist/icons/generated/lucide-ellipsis-vertical.js +3 -4
  374. package/dist/icons/generated/lucide-ellipsis-vertical.js.map +1 -1
  375. package/dist/icons/generated/lucide-external-link.d.ts +5 -4
  376. package/dist/icons/generated/lucide-external-link.d.ts.map +1 -0
  377. package/dist/icons/generated/lucide-external-link.js +3 -4
  378. package/dist/icons/generated/lucide-external-link.js.map +1 -1
  379. package/dist/icons/generated/lucide-eye.d.ts +5 -4
  380. package/dist/icons/generated/lucide-eye.d.ts.map +1 -0
  381. package/dist/icons/generated/lucide-eye.js +3 -4
  382. package/dist/icons/generated/lucide-eye.js.map +1 -1
  383. package/dist/icons/generated/lucide-file-text.d.ts +5 -4
  384. package/dist/icons/generated/lucide-file-text.d.ts.map +1 -0
  385. package/dist/icons/generated/lucide-file-text.js +3 -4
  386. package/dist/icons/generated/lucide-file-text.js.map +1 -1
  387. package/dist/icons/generated/lucide-file.d.ts +5 -4
  388. package/dist/icons/generated/lucide-file.d.ts.map +1 -0
  389. package/dist/icons/generated/lucide-file.js +3 -4
  390. package/dist/icons/generated/lucide-file.js.map +1 -1
  391. package/dist/icons/generated/lucide-film.d.ts +5 -4
  392. package/dist/icons/generated/lucide-film.d.ts.map +1 -0
  393. package/dist/icons/generated/lucide-film.js +3 -4
  394. package/dist/icons/generated/lucide-film.js.map +1 -1
  395. package/dist/icons/generated/lucide-folder-open.d.ts +5 -4
  396. package/dist/icons/generated/lucide-folder-open.d.ts.map +1 -0
  397. package/dist/icons/generated/lucide-folder-open.js +3 -4
  398. package/dist/icons/generated/lucide-folder-open.js.map +1 -1
  399. package/dist/icons/generated/lucide-folder.d.ts +5 -4
  400. package/dist/icons/generated/lucide-folder.d.ts.map +1 -0
  401. package/dist/icons/generated/lucide-folder.js +3 -4
  402. package/dist/icons/generated/lucide-folder.js.map +1 -1
  403. package/dist/icons/generated/lucide-globe.d.ts +5 -4
  404. package/dist/icons/generated/lucide-globe.d.ts.map +1 -0
  405. package/dist/icons/generated/lucide-globe.js +3 -4
  406. package/dist/icons/generated/lucide-globe.js.map +1 -1
  407. package/dist/icons/generated/lucide-headphones.d.ts +5 -4
  408. package/dist/icons/generated/lucide-headphones.d.ts.map +1 -0
  409. package/dist/icons/generated/lucide-headphones.js +3 -4
  410. package/dist/icons/generated/lucide-headphones.js.map +1 -1
  411. package/dist/icons/generated/lucide-heart.d.ts +5 -4
  412. package/dist/icons/generated/lucide-heart.d.ts.map +1 -0
  413. package/dist/icons/generated/lucide-heart.js +3 -4
  414. package/dist/icons/generated/lucide-heart.js.map +1 -1
  415. package/dist/icons/generated/lucide-image.d.ts +5 -4
  416. package/dist/icons/generated/lucide-image.d.ts.map +1 -0
  417. package/dist/icons/generated/lucide-image.js +3 -4
  418. package/dist/icons/generated/lucide-image.js.map +1 -1
  419. package/dist/icons/generated/lucide-inbox.d.ts +5 -4
  420. package/dist/icons/generated/lucide-inbox.d.ts.map +1 -0
  421. package/dist/icons/generated/lucide-inbox.js +3 -4
  422. package/dist/icons/generated/lucide-inbox.js.map +1 -1
  423. package/dist/icons/generated/lucide-info.d.ts +5 -4
  424. package/dist/icons/generated/lucide-info.d.ts.map +1 -0
  425. package/dist/icons/generated/lucide-info.js +3 -4
  426. package/dist/icons/generated/lucide-info.js.map +1 -1
  427. package/dist/icons/generated/lucide-layout-grid.d.ts +5 -4
  428. package/dist/icons/generated/lucide-layout-grid.d.ts.map +1 -0
  429. package/dist/icons/generated/lucide-layout-grid.js +3 -4
  430. package/dist/icons/generated/lucide-layout-grid.js.map +1 -1
  431. package/dist/icons/generated/lucide-link.d.ts +5 -4
  432. package/dist/icons/generated/lucide-link.d.ts.map +1 -0
  433. package/dist/icons/generated/lucide-link.js +3 -4
  434. package/dist/icons/generated/lucide-link.js.map +1 -1
  435. package/dist/icons/generated/lucide-list-filter.d.ts +5 -4
  436. package/dist/icons/generated/lucide-list-filter.d.ts.map +1 -0
  437. package/dist/icons/generated/lucide-list-filter.js +3 -4
  438. package/dist/icons/generated/lucide-list-filter.js.map +1 -1
  439. package/dist/icons/generated/lucide-list-restart.d.ts +5 -4
  440. package/dist/icons/generated/lucide-list-restart.d.ts.map +1 -0
  441. package/dist/icons/generated/lucide-list-restart.js +3 -4
  442. package/dist/icons/generated/lucide-list-restart.js.map +1 -1
  443. package/dist/icons/generated/lucide-loader-circle.d.ts +5 -4
  444. package/dist/icons/generated/lucide-loader-circle.d.ts.map +1 -0
  445. package/dist/icons/generated/lucide-loader-circle.js +3 -4
  446. package/dist/icons/generated/lucide-loader-circle.js.map +1 -1
  447. package/dist/icons/generated/lucide-mail.d.ts +5 -4
  448. package/dist/icons/generated/lucide-mail.d.ts.map +1 -0
  449. package/dist/icons/generated/lucide-mail.js +3 -4
  450. package/dist/icons/generated/lucide-mail.js.map +1 -1
  451. package/dist/icons/generated/lucide-minus.d.ts +5 -4
  452. package/dist/icons/generated/lucide-minus.d.ts.map +1 -0
  453. package/dist/icons/generated/lucide-minus.js +3 -4
  454. package/dist/icons/generated/lucide-minus.js.map +1 -1
  455. package/dist/icons/generated/lucide-music.d.ts +5 -4
  456. package/dist/icons/generated/lucide-music.d.ts.map +1 -0
  457. package/dist/icons/generated/lucide-music.js +3 -4
  458. package/dist/icons/generated/lucide-music.js.map +1 -1
  459. package/dist/icons/generated/lucide-package.d.ts +5 -4
  460. package/dist/icons/generated/lucide-package.d.ts.map +1 -0
  461. package/dist/icons/generated/lucide-package.js +3 -4
  462. package/dist/icons/generated/lucide-package.js.map +1 -1
  463. package/dist/icons/generated/lucide-pen-line.d.ts +5 -4
  464. package/dist/icons/generated/lucide-pen-line.d.ts.map +1 -0
  465. package/dist/icons/generated/lucide-pen-line.js +3 -4
  466. package/dist/icons/generated/lucide-pen-line.js.map +1 -1
  467. package/dist/icons/generated/lucide-pencil.d.ts +5 -4
  468. package/dist/icons/generated/lucide-pencil.d.ts.map +1 -0
  469. package/dist/icons/generated/lucide-pencil.js +3 -4
  470. package/dist/icons/generated/lucide-pencil.js.map +1 -1
  471. package/dist/icons/generated/lucide-play.d.ts +5 -4
  472. package/dist/icons/generated/lucide-play.d.ts.map +1 -0
  473. package/dist/icons/generated/lucide-play.js +3 -4
  474. package/dist/icons/generated/lucide-play.js.map +1 -1
  475. package/dist/icons/generated/lucide-plus.d.ts +5 -4
  476. package/dist/icons/generated/lucide-plus.d.ts.map +1 -0
  477. package/dist/icons/generated/lucide-plus.js +3 -4
  478. package/dist/icons/generated/lucide-plus.js.map +1 -1
  479. package/dist/icons/generated/lucide-printer.d.ts +5 -4
  480. package/dist/icons/generated/lucide-printer.d.ts.map +1 -0
  481. package/dist/icons/generated/lucide-printer.js +3 -4
  482. package/dist/icons/generated/lucide-printer.js.map +1 -1
  483. package/dist/icons/generated/lucide-redo-2.d.ts +5 -4
  484. package/dist/icons/generated/lucide-redo-2.d.ts.map +1 -0
  485. package/dist/icons/generated/lucide-redo-2.js +3 -4
  486. package/dist/icons/generated/lucide-redo-2.js.map +1 -1
  487. package/dist/icons/generated/lucide-refresh-cw.d.ts +5 -4
  488. package/dist/icons/generated/lucide-refresh-cw.d.ts.map +1 -0
  489. package/dist/icons/generated/lucide-refresh-cw.js +3 -4
  490. package/dist/icons/generated/lucide-refresh-cw.js.map +1 -1
  491. package/dist/icons/generated/lucide-scissors.d.ts +5 -4
  492. package/dist/icons/generated/lucide-scissors.d.ts.map +1 -0
  493. package/dist/icons/generated/lucide-scissors.js +3 -4
  494. package/dist/icons/generated/lucide-scissors.js.map +1 -1
  495. package/dist/icons/generated/lucide-search.d.ts +5 -4
  496. package/dist/icons/generated/lucide-search.d.ts.map +1 -0
  497. package/dist/icons/generated/lucide-search.js +3 -4
  498. package/dist/icons/generated/lucide-search.js.map +1 -1
  499. package/dist/icons/generated/lucide-settings.d.ts +5 -4
  500. package/dist/icons/generated/lucide-settings.d.ts.map +1 -0
  501. package/dist/icons/generated/lucide-settings.js +3 -4
  502. package/dist/icons/generated/lucide-settings.js.map +1 -1
  503. package/dist/icons/generated/lucide-sliders-horizontal.d.ts +5 -4
  504. package/dist/icons/generated/lucide-sliders-horizontal.d.ts.map +1 -0
  505. package/dist/icons/generated/lucide-sliders-horizontal.js +3 -4
  506. package/dist/icons/generated/lucide-sliders-horizontal.js.map +1 -1
  507. package/dist/icons/generated/lucide-star.d.ts +5 -4
  508. package/dist/icons/generated/lucide-star.d.ts.map +1 -0
  509. package/dist/icons/generated/lucide-star.js +3 -4
  510. package/dist/icons/generated/lucide-star.js.map +1 -1
  511. package/dist/icons/generated/lucide-tag.d.ts +5 -4
  512. package/dist/icons/generated/lucide-tag.d.ts.map +1 -0
  513. package/dist/icons/generated/lucide-tag.js +3 -4
  514. package/dist/icons/generated/lucide-tag.js.map +1 -1
  515. package/dist/icons/generated/lucide-tags.d.ts +5 -4
  516. package/dist/icons/generated/lucide-tags.d.ts.map +1 -0
  517. package/dist/icons/generated/lucide-tags.js +3 -4
  518. package/dist/icons/generated/lucide-tags.js.map +1 -1
  519. package/dist/icons/generated/lucide-trash-2.d.ts +5 -4
  520. package/dist/icons/generated/lucide-trash-2.d.ts.map +1 -0
  521. package/dist/icons/generated/lucide-trash-2.js +3 -4
  522. package/dist/icons/generated/lucide-trash-2.js.map +1 -1
  523. package/dist/icons/generated/lucide-triangle-alert.d.ts +5 -4
  524. package/dist/icons/generated/lucide-triangle-alert.d.ts.map +1 -0
  525. package/dist/icons/generated/lucide-triangle-alert.js +3 -4
  526. package/dist/icons/generated/lucide-triangle-alert.js.map +1 -1
  527. package/dist/icons/generated/lucide-undo-2.d.ts +5 -4
  528. package/dist/icons/generated/lucide-undo-2.d.ts.map +1 -0
  529. package/dist/icons/generated/lucide-undo-2.js +3 -4
  530. package/dist/icons/generated/lucide-undo-2.js.map +1 -1
  531. package/dist/icons/generated/lucide-upload.d.ts +5 -4
  532. package/dist/icons/generated/lucide-upload.d.ts.map +1 -0
  533. package/dist/icons/generated/lucide-upload.js +3 -4
  534. package/dist/icons/generated/lucide-upload.js.map +1 -1
  535. package/dist/icons/generated/lucide-user.d.ts +5 -4
  536. package/dist/icons/generated/lucide-user.d.ts.map +1 -0
  537. package/dist/icons/generated/lucide-user.js +3 -4
  538. package/dist/icons/generated/lucide-user.js.map +1 -1
  539. package/dist/icons/generated/lucide-wrench.d.ts +5 -4
  540. package/dist/icons/generated/lucide-wrench.d.ts.map +1 -0
  541. package/dist/icons/generated/lucide-wrench.js +3 -4
  542. package/dist/icons/generated/lucide-wrench.js.map +1 -1
  543. package/dist/icons/generated/lucide-x.d.ts +5 -4
  544. package/dist/icons/generated/lucide-x.d.ts.map +1 -0
  545. package/dist/icons/generated/lucide-x.js +3 -4
  546. package/dist/icons/generated/lucide-x.js.map +1 -1
  547. package/dist/icons/generated/mdi-tag-search-outline.d.ts +5 -4
  548. package/dist/icons/generated/mdi-tag-search-outline.d.ts.map +1 -0
  549. package/dist/icons/generated/mdi-tag-search-outline.js +3 -4
  550. package/dist/icons/generated/mdi-tag-search-outline.js.map +1 -1
  551. package/dist/icons/generated/ooui-close.d.ts +5 -4
  552. package/dist/icons/generated/ooui-close.d.ts.map +1 -0
  553. package/dist/icons/generated/ooui-close.js +3 -4
  554. package/dist/icons/generated/ooui-close.js.map +1 -1
  555. package/dist/icons/generated/radix-icons-panel-left-minimized.d.ts +5 -4
  556. package/dist/icons/generated/radix-icons-panel-left-minimized.d.ts.map +1 -0
  557. package/dist/icons/generated/radix-icons-panel-left-minimized.js +3 -4
  558. package/dist/icons/generated/radix-icons-panel-left-minimized.js.map +1 -1
  559. package/dist/icons/generated/radix-icons-reset.d.ts +5 -4
  560. package/dist/icons/generated/radix-icons-reset.d.ts.map +1 -0
  561. package/dist/icons/generated/radix-icons-reset.js +3 -4
  562. package/dist/icons/generated/radix-icons-reset.js.map +1 -1
  563. package/dist/icons/generated/tabler-sort-ascending-letters.d.ts +5 -4
  564. package/dist/icons/generated/tabler-sort-ascending-letters.d.ts.map +1 -0
  565. package/dist/icons/generated/tabler-sort-ascending-letters.js +3 -4
  566. package/dist/icons/generated/tabler-sort-ascending-letters.js.map +1 -1
  567. package/dist/icons/index.d.ts +75 -74
  568. package/dist/icons/index.js +75 -75
  569. package/dist/shared/element-height/index.js +51 -25
  570. package/dist/shared/element-height/index.js.map +1 -1
  571. package/dist/shared/element-width/index.js +39 -24
  572. package/dist/shared/element-width/index.js.map +1 -1
  573. package/dist/shared/events/user-change.js +14 -8
  574. package/dist/shared/events/user-change.js.map +1 -1
  575. package/dist/shared/focus/pointer-focus.js +56 -30
  576. package/dist/shared/focus/pointer-focus.js.map +1 -1
  577. package/dist/shared/focus/tabbable.js +96 -0
  578. package/dist/shared/focus/tabbable.js.map +1 -0
  579. package/dist/shared/form-association/field-id.js +13 -6
  580. package/dist/shared/form-association/field-id.js.map +1 -1
  581. package/dist/shared/form-association/index.js +75 -42
  582. package/dist/shared/form-association/index.js.map +1 -1
  583. package/dist/shared/gesture/drag-gesture.js +239 -99
  584. package/dist/shared/gesture/drag-gesture.js.map +1 -1
  585. package/dist/shared/gesture/physics.js +49 -16
  586. package/dist/shared/gesture/physics.js.map +1 -1
  587. package/dist/shared/gesture/pinch-gesture.js +111 -60
  588. package/dist/shared/gesture/pinch-gesture.js.map +1 -1
  589. package/dist/shared/group-management/index.js +181 -84
  590. package/dist/shared/group-management/index.js.map +1 -1
  591. package/dist/shared/label-emptiness/index.js +45 -26
  592. package/dist/shared/label-emptiness/index.js.map +1 -1
  593. package/dist/shared/locale/builtin-labels.js +38 -0
  594. package/dist/shared/locale/builtin-labels.js.map +1 -0
  595. package/dist/shared/menu-behavior/index.js +113 -60
  596. package/dist/shared/menu-behavior/index.js.map +1 -1
  597. package/dist/shared/menu-portal/menu-portal.js +47 -26
  598. package/dist/shared/menu-portal/menu-portal.js.map +1 -1
  599. package/dist/shared/menu-portal/menu-tree.js +132 -75
  600. package/dist/shared/menu-portal/menu-tree.js.map +1 -1
  601. package/dist/shared/normalize/index.js +16 -7
  602. package/dist/shared/normalize/index.js.map +1 -1
  603. package/dist/shared/open-state/index.js +7 -8
  604. package/dist/shared/open-state/index.js.map +1 -1
  605. package/dist/shared/option-portal/combobox-shell.js +121 -56
  606. package/dist/shared/option-portal/combobox-shell.js.map +1 -1
  607. package/dist/shared/option-portal/index.js +65 -44
  608. package/dist/shared/option-portal/index.js.map +1 -1
  609. package/dist/shared/overlay/anchored-panel.js +75 -40
  610. package/dist/shared/overlay/anchored-panel.js.map +1 -1
  611. package/dist/shared/overlay/native-dialog-presence.js +116 -52
  612. package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
  613. package/dist/shared/overlay/nested-drawer-layers.js +76 -46
  614. package/dist/shared/overlay/nested-drawer-layers.js.map +1 -1
  615. package/dist/shared/overlay/open-overlay.js +240 -136
  616. package/dist/shared/overlay/open-overlay.js.map +1 -1
  617. package/dist/shared/overlay/overlay-root.js +33 -24
  618. package/dist/shared/overlay/overlay-root.js.map +1 -1
  619. package/dist/shared/overlay/overlay.js +109 -66
  620. package/dist/shared/overlay/overlay.js.map +1 -1
  621. package/dist/shared/overlay/placement-props.js +9 -4
  622. package/dist/shared/overlay/placement-props.js.map +1 -1
  623. package/dist/shared/overlay/portal.d.ts +2 -0
  624. package/dist/shared/overlay/portal.d.ts.map +1 -0
  625. package/dist/shared/overlay/portal.js +202 -117
  626. package/dist/shared/overlay/portal.js.map +1 -1
  627. package/dist/shared/overlay/positioning-generation.js +9 -10
  628. package/dist/shared/overlay/positioning-generation.js.map +1 -1
  629. package/dist/shared/overlay/presence.js +43 -21
  630. package/dist/shared/overlay/presence.js.map +1 -1
  631. package/dist/shared/overlay/theme-overlay-scope.js +22 -19
  632. package/dist/shared/overlay/theme-overlay-scope.js.map +1 -1
  633. package/dist/shared/scroll-lock/scroll-lock.js +49 -15
  634. package/dist/shared/scroll-lock/scroll-lock.js.map +1 -1
  635. package/dist/shared/theme/duration.js +13 -6
  636. package/dist/shared/theme/duration.js.map +1 -1
  637. package/dist/shared/theme/reduced-motion.js +14 -9
  638. package/dist/shared/theme/reduced-motion.js.map +1 -1
  639. package/dist/shared/theme/root-sync.js +85 -32
  640. package/dist/shared/theme/root-sync.js.map +1 -1
  641. package/dist/shared/visible-area/index.js +81 -37
  642. package/dist/shared/visible-area/index.js.map +1 -1
  643. package/dist/types/iconify.d.ts +1 -1
  644. package/dist/types/iconify.js +0 -0
  645. package/dist/types/react.d.ts +8 -10
  646. package/dist/types/react.d.ts.map +1 -0
  647. package/dist/types/react.js +0 -0
  648. package/dist/types/utils.d.ts +8 -13
  649. package/dist/types/utils.d.ts.map +1 -0
  650. package/dist/types/utils.js +0 -0
  651. package/dist/types/vue.d.ts +9 -13
  652. package/dist/types/vue.d.ts.map +1 -0
  653. package/dist/types/vue.js +0 -0
  654. package/dist/vite/index.d.ts +1 -0
  655. package/dist/vite/index.d.ts.map +1 -0
  656. package/dist/vite/index.js +30 -4
  657. package/dist/vite/index.js.map +1 -1
  658. package/package.json +10 -23
  659. package/dist/_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js +0 -9
  660. package/dist/components/middle-ellipsis/truncate.d.ts +0 -62
  661. package/dist/components/radio/interaction.d.ts +0 -4
  662. package/dist/scrollbars/index.d.ts +0 -33
  663. package/dist/scrollbars/index.js +0 -18
  664. package/dist/scrollbars/index.js.map +0 -1
  665. package/dist/scrollbars/internal.js +0 -6
  666. package/dist/scrollbars/internal.js.map +0 -1
  667. package/dist/scrollbars/style.css +0 -10
@@ -1,158 +1,298 @@
1
- function e(e, t) {
2
- let n = typeof PointerEvent < "u" && e instanceof PointerEvent, r = n ? e.currentTarget || e.target : e, { axis: i = "both", threshold: a = 0, calibrateOnFirstMove: o = !1, onStart: s, onMove: c, onEnd: l, onTap: u, onCancel: d } = t, f = null, p = 0, m = 0, h = 0, g = a <= 0, _ = !1, v = [], y = null, b = null;
3
- function x(e) {
4
- e.cancelable && e.preventDefault();
5
- }
6
- function S(e) {
7
- let t = /* @__PURE__ */ new Set(), n = typeof e.composedPath == "function" ? e.composedPath() : [];
8
- for (let e of n) {
9
- let n = e.nodeType;
10
- (n === Node.ELEMENT_NODE || n === Node.DOCUMENT_FRAGMENT_NODE) && (e.addEventListener("touchmove", x, {
11
- capture: !0,
12
- passive: !1
13
- }), t.add(e));
14
- }
15
- b = t;
1
+ // src/shared/gesture/drag-gesture.ts
2
+ /**
3
+ * 跨平台/跨浏览器 Pointer 拖拽手势生命周期管理器
4
+ *
5
+ * 封装:
6
+ * 1. setPointerCapture 安全捕获与 window 兜底监听(防 pointer 丢失/离开视口悬挂)
7
+ * 2. 多点触控副指针与未聚焦指针过滤
8
+ * 3. 意图死区(threshold)与滑动轴向判定
9
+ * 4. 可选的零点校准(calibrateOnFirstMove:首个有效 move 重置零点与判定时钟)
10
+ * 5. 100ms 滑动窗口平滑速度估算(Velocity px/s)
11
+ * 6. Window / Handle 跨层事件去重(防重复采样)
12
+ */
13
+ const VELOCITY_WINDOW_MS = 100;
14
+ /**
15
+ * 为指定元素挂载统一的 Pointer 拖拽手势,或在已有的 pointerdown 事件中启动手势
16
+ */
17
+ function attachDragGesture(targetOrEvent, options) {
18
+ const isEvent = typeof PointerEvent !== "undefined" && targetOrEvent instanceof PointerEvent;
19
+ const target = isEvent ? targetOrEvent.currentTarget || targetOrEvent.target : targetOrEvent;
20
+ const { axis = "both", threshold = 0, calibrateOnFirstMove = false, onStart, onMove, onEnd, onTap, onCancel } = options;
21
+ let activePointerId = null;
22
+ let startX = 0;
23
+ let startY = 0;
24
+ let startTimeStamp = 0;
25
+ let isThresholdPassed = threshold <= 0;
26
+ let isCalibrated = false;
27
+ let samples = [];
28
+ let handledMoveEvent = null;
29
+ let touchGuardTargets = null;
30
+ /**
31
+ * iOS Safari 滚动接管兜底:
32
+ * WebKit 对 shadow DOM 内 touch-action 的交集计算存在怪癖,触摸落在深层子元素
33
+ * (如 slider thumb、segmented-trigger 的 shadow 内容)时,声明在手势元素上的
34
+ * touch-action: none 可能不生效,iOS 会把触摸判为滚动意图并在越过阈值前触发
35
+ * pointercancel,拖拽因此中断。非被动 touchmove + preventDefault 是 WebKit 也
36
+ * 尊重的最后手段:页面显式处理触摸移动后,滚动识别器不会获胜,也就不会接管。
37
+ */
38
+ function handleTouchMove(e) {
39
+ if (e.cancelable) e.preventDefault();
16
40
  }
17
- function C() {
18
- if (b) {
19
- for (let e of b) e.removeEventListener("touchmove", x, !0);
20
- b = null;
41
+ /**
42
+ * 沿 pointerdown 的 composedPath 在每个 Element/ShadowRoot 挂非被动 touchmove
43
+ * 监听。TouchEvent 不像 PointerEvent 那样可组合:非 composed 的 touchmove 只在
44
+ * 落点所在的 shadow tree 内传播(连 host 都不经过),所以单一手势元素上的监听
45
+ * 对 segmented-trigger 这类深层 shadow 内容完全失效。composedPath 覆盖落点的
46
+ * 全部 shadow tree 链,无论 touchmove 在哪一层传播,路径上必有我们挂载的节点
47
+ * 能收到事件并 preventDefault。document/window 不在挂载范围:touchmove 到不了
48
+ * 它们,挂上也只是死代码。
49
+ */
50
+ function attachTouchGuards(e) {
51
+ const targets = /* @__PURE__ */ new Set();
52
+ const path = typeof e.composedPath === "function" ? e.composedPath() : [];
53
+ for (const node of path) {
54
+ const type = node.nodeType;
55
+ if (type === Node.ELEMENT_NODE || type === Node.DOCUMENT_FRAGMENT_NODE) {
56
+ node.addEventListener("touchmove", handleTouchMove, {
57
+ capture: true,
58
+ passive: false
59
+ });
60
+ targets.add(node);
61
+ }
21
62
  }
63
+ touchGuardTargets = targets;
22
64
  }
23
- function w() {
24
- if (v.length < 2) return {
65
+ function detachTouchGuards() {
66
+ if (!touchGuardTargets) return;
67
+ for (const node of touchGuardTargets) node.removeEventListener("touchmove", handleTouchMove, true);
68
+ touchGuardTargets = null;
69
+ }
70
+ function estimateVelocity() {
71
+ if (samples.length < 2) return {
25
72
  vx: 0,
26
73
  vy: 0,
27
74
  v: 0
28
75
  };
29
- let e = v[0], t = v[v.length - 1], n = t.t - e.t;
30
- if (n < 2) return {
76
+ const first = samples[0];
77
+ const last = samples[samples.length - 1];
78
+ const dt = last.t - first.t;
79
+ if (dt < 2) return {
31
80
  vx: 0,
32
81
  vy: 0,
33
82
  v: 0
34
83
  };
35
- let r = (t.x - e.x) / n * 1e3, a = (t.y - e.y) / n * 1e3, o = 0;
36
- return o = i === "x" ? r : i === "y" ? a : Math.hypot(r, a), {
37
- vx: r,
38
- vy: a,
39
- v: o
84
+ const vx = (last.x - first.x) / dt * 1e3;
85
+ const vy = (last.y - first.y) / dt * 1e3;
86
+ let v = 0;
87
+ if (axis === "x") v = vx;
88
+ else if (axis === "y") v = vy;
89
+ else v = Math.hypot(vx, vy);
90
+ return {
91
+ vx,
92
+ vy,
93
+ v
40
94
  };
41
95
  }
42
- function T() {
43
- window.removeEventListener("pointermove", j, !0), window.removeEventListener("pointerup", M, !0), window.removeEventListener("pointercancel", N, !0), window.removeEventListener("lostpointercapture", P, !0);
96
+ function detachWindowListeners() {
97
+ window.removeEventListener("pointermove", handlePointerMove, true);
98
+ window.removeEventListener("pointerup", handlePointerUp, true);
99
+ window.removeEventListener("pointercancel", handlePointerCancel, true);
100
+ window.removeEventListener("lostpointercapture", handleLostPointerCapture, true);
44
101
  }
45
- function E() {
46
- window.addEventListener("pointermove", j, !0), window.addEventListener("pointerup", M, !0), window.addEventListener("pointercancel", N, !0), window.addEventListener("lostpointercapture", P, !0);
102
+ function attachWindowListeners() {
103
+ window.addEventListener("pointermove", handlePointerMove, true);
104
+ window.addEventListener("pointerup", handlePointerUp, true);
105
+ window.addEventListener("pointercancel", handlePointerCancel, true);
106
+ window.addEventListener("lostpointercapture", handleLostPointerCapture, true);
47
107
  }
48
- function D() {
49
- r && (r.removeEventListener("pointermove", j), r.removeEventListener("pointerup", M), r.removeEventListener("pointercancel", N), r.removeEventListener("lostpointercapture", P));
108
+ function detachTargetListeners() {
109
+ if (!target) return;
110
+ target.removeEventListener("pointermove", handlePointerMove);
111
+ target.removeEventListener("pointerup", handlePointerUp);
112
+ target.removeEventListener("pointercancel", handlePointerCancel);
113
+ target.removeEventListener("lostpointercapture", handleLostPointerCapture);
50
114
  }
51
- function O() {
52
- r && (r.addEventListener("pointermove", j), r.addEventListener("pointerup", M), r.addEventListener("pointercancel", N), r.addEventListener("lostpointercapture", P));
115
+ function attachTargetListeners() {
116
+ if (!target) return;
117
+ target.addEventListener("pointermove", handlePointerMove);
118
+ target.addEventListener("pointerup", handlePointerUp);
119
+ target.addEventListener("pointercancel", handlePointerCancel);
120
+ target.addEventListener("lostpointercapture", handleLostPointerCapture);
53
121
  }
54
- function k() {
55
- if (f !== null && r && typeof r.hasPointerCapture == "function") try {
56
- r.hasPointerCapture(f) && r.releasePointerCapture(f);
122
+ function resetState() {
123
+ if (activePointerId !== null && target && typeof target.hasPointerCapture === "function") try {
124
+ if (target.hasPointerCapture(activePointerId)) target.releasePointerCapture(activePointerId);
57
125
  } catch {}
58
- f = null, g = a <= 0, _ = !1, v = [], y = null, T(), D(), C();
126
+ activePointerId = null;
127
+ isThresholdPassed = threshold <= 0;
128
+ isCalibrated = false;
129
+ samples = [];
130
+ handledMoveEvent = null;
131
+ detachWindowListeners();
132
+ detachTargetListeners();
133
+ detachTouchGuards();
59
134
  }
60
- function A(e) {
61
- if (f !== null || e.pointerType === "touch" && e.isPrimary === !1) return;
62
- let t = {
135
+ function handlePointerDown(e) {
136
+ if (activePointerId !== null) return;
137
+ if (e.pointerType === "touch" && e.isPrimary === false) return;
138
+ const startInfo = {
63
139
  pointerId: e.pointerId,
64
140
  clientX: e.clientX,
65
141
  clientY: e.clientY,
66
142
  timeStamp: e.timeStamp
67
143
  };
68
- if (s?.(t, e) !== !1 && (f = e.pointerId, p = e.clientX, m = e.clientY, h = e.timeStamp, g = a <= 0, _ = !1, v = [{
144
+ if (onStart?.(startInfo, e) === false) return;
145
+ activePointerId = e.pointerId;
146
+ startX = e.clientX;
147
+ startY = e.clientY;
148
+ startTimeStamp = e.timeStamp;
149
+ isThresholdPassed = threshold <= 0;
150
+ isCalibrated = false;
151
+ samples = [{
69
152
  t: e.timeStamp,
70
153
  x: e.clientX,
71
154
  y: e.clientY
72
- }], y = null, E(), O(), S(e), g)) try {
73
- r?.setPointerCapture?.(e.pointerId);
155
+ }];
156
+ handledMoveEvent = null;
157
+ attachWindowListeners();
158
+ attachTargetListeners();
159
+ attachTouchGuards(e);
160
+ if (isThresholdPassed) try {
161
+ target?.setPointerCapture?.(e.pointerId);
74
162
  } catch {}
75
163
  }
76
- function j(e) {
77
- if (f !== e.pointerId || y === e) return;
78
- if (y = e, !g) {
79
- let t = e.clientX - p, n = e.clientY - m, o = i === "x" ? Math.abs(t) : i === "y" ? Math.abs(n) : Math.hypot(t, n);
80
- if (i === "x" && Math.abs(n) >= a && Math.abs(n) > Math.abs(t)) {
81
- F();
164
+ function handlePointerMove(e) {
165
+ if (activePointerId !== e.pointerId) return;
166
+ if (handledMoveEvent === e) return;
167
+ handledMoveEvent = e;
168
+ if (!isThresholdPassed) {
169
+ const rawDeltaX = e.clientX - startX;
170
+ const rawDeltaY = e.clientY - startY;
171
+ const distance = axis === "x" ? Math.abs(rawDeltaX) : axis === "y" ? Math.abs(rawDeltaY) : Math.hypot(rawDeltaX, rawDeltaY);
172
+ if (axis === "x" && Math.abs(rawDeltaY) >= threshold && Math.abs(rawDeltaY) > Math.abs(rawDeltaX)) {
173
+ cancel();
82
174
  return;
83
175
  }
84
- if (i === "y" && Math.abs(t) >= a && Math.abs(t) > Math.abs(n)) {
85
- F();
176
+ if (axis === "y" && Math.abs(rawDeltaX) >= threshold && Math.abs(rawDeltaX) > Math.abs(rawDeltaY)) {
177
+ cancel();
86
178
  return;
87
179
  }
88
- if (o < a) return;
89
- g = !0, h = e.timeStamp;
180
+ if (distance < threshold) return;
181
+ isThresholdPassed = true;
182
+ startTimeStamp = e.timeStamp;
90
183
  try {
91
- r?.setPointerCapture?.(e.pointerId);
184
+ target?.setPointerCapture?.(e.pointerId);
92
185
  } catch {}
93
186
  }
94
- o && !_ && (_ = !0, p = e.clientX, m = e.clientY, h = e.timeStamp);
95
- let t = e.clientX - p, n = e.clientY - m;
96
- e.cancelable && e.preventDefault();
97
- let s = e.timeStamp;
98
- for (v.push({
99
- t: s,
187
+ if (calibrateOnFirstMove && !isCalibrated) {
188
+ isCalibrated = true;
189
+ startX = e.clientX;
190
+ startY = e.clientY;
191
+ startTimeStamp = e.timeStamp;
192
+ }
193
+ const deltaX = e.clientX - startX;
194
+ const deltaY = e.clientY - startY;
195
+ if (e.cancelable) e.preventDefault();
196
+ const now = e.timeStamp;
197
+ samples.push({
198
+ t: now,
100
199
  x: e.clientX,
101
200
  y: e.clientY
102
- }); v.length > 2 && s - v[0].t > 100;) v.shift();
103
- let { vx: l, vy: u, v: d } = w(), b = {
201
+ });
202
+ while (samples.length > 2 && now - samples[0].t > VELOCITY_WINDOW_MS) samples.shift();
203
+ const { vx, vy, v } = estimateVelocity();
204
+ const moveInfo = {
104
205
  pointerId: e.pointerId,
105
206
  clientX: e.clientX,
106
207
  clientY: e.clientY,
107
- deltaX: t,
108
- deltaY: n,
109
- velocityX: l,
110
- velocityY: u,
111
- velocity: d,
112
- timeStamp: s
208
+ deltaX,
209
+ deltaY,
210
+ velocityX: vx,
211
+ velocityY: vy,
212
+ velocity: v,
213
+ timeStamp: now
113
214
  };
114
- c?.(b, e);
215
+ onMove?.(moveInfo, e);
115
216
  }
116
- function M(e) {
117
- if (f !== e.pointerId) return;
118
- let t = e.timeStamp;
119
- for (v.push({
120
- t,
217
+ function handlePointerUp(e) {
218
+ if (activePointerId !== e.pointerId) return;
219
+ const now = e.timeStamp;
220
+ samples.push({
221
+ t: now,
121
222
  x: e.clientX,
122
223
  y: e.clientY
123
- }); v.length > 2 && t - v[0].t > 100;) v.shift();
124
- let n = e.clientX - p, r = e.clientY - m, { vx: i, vy: a, v: o } = w(), s = {
224
+ });
225
+ while (samples.length > 2 && now - samples[0].t > VELOCITY_WINDOW_MS) samples.shift();
226
+ const deltaX = e.clientX - startX;
227
+ const deltaY = e.clientY - startY;
228
+ const { vx, vy, v } = estimateVelocity();
229
+ const endInfo = {
125
230
  pointerId: e.pointerId,
126
231
  clientX: e.clientX,
127
232
  clientY: e.clientY,
128
- deltaX: n,
129
- deltaY: r,
130
- velocityX: i,
131
- velocityY: a,
132
- velocity: o,
233
+ deltaX,
234
+ deltaY,
235
+ velocityX: vx,
236
+ velocityY: vy,
237
+ velocity: v,
133
238
  timeStamp: e.timeStamp,
134
- duration: Math.max(0, e.timeStamp - h)
135
- }, c = g;
136
- k(), c ? l?.(s, e) : (u?.(s, e), d?.(e));
239
+ duration: Math.max(0, e.timeStamp - startTimeStamp)
240
+ };
241
+ const hadPassedThreshold = isThresholdPassed;
242
+ resetState();
243
+ if (hadPassedThreshold) onEnd?.(endInfo, e);
244
+ else {
245
+ onTap?.(endInfo, e);
246
+ onCancel?.(e);
247
+ }
137
248
  }
138
- function N(e) {
139
- f === e.pointerId && (k(), d?.(e));
249
+ function handlePointerCancel(e) {
250
+ if (activePointerId !== e.pointerId) return;
251
+ resetState();
252
+ onCancel?.(e);
140
253
  }
141
- function P(e) {
142
- f === e.pointerId && e.target === r && (k(), d?.(e));
254
+ /**
255
+ * lostpointercapture 不能当作 pointercancel:touch 指针在 pointerdown 时会被浏览器
256
+ * 隐式捕获到命中元素(如 slider thumb、segmented-trigger 内容),组件随后
257
+ * setPointerCapture(target) 把捕获转手到手势元素,命中元素先收到 lostpointercapture——
258
+ * 这是正常转手而非取消,若直接走 cancel 会把刚启动的拖拽杀死(值只走一步即冻结)。
259
+ * 只有手势元素自身意外丢失捕获(如元素被移出文档)才应取消。
260
+ *
261
+ * resetState 内 releasePointerCapture 产生的 lostpointercapture 会在 activePointerId
262
+ * 置空之后异步到达,被 pointerId 守卫挡住,不会误伤。
263
+ */
264
+ function handleLostPointerCapture(e) {
265
+ if (activePointerId !== e.pointerId) return;
266
+ if (e.target !== target) return;
267
+ resetState();
268
+ onCancel?.(e);
143
269
  }
144
- function F() {
145
- f !== null && (k(), d?.());
270
+ function cancel() {
271
+ if (activePointerId === null) return;
272
+ resetState();
273
+ onCancel?.();
146
274
  }
147
- return n ? A(e) : r && (r.addEventListener("pointerdown", A), r.addEventListener("pointermove", j), r.addEventListener("pointerup", M), r.addEventListener("pointercancel", N)), {
148
- isDragging: () => f !== null,
149
- cancel: F,
275
+ if (isEvent) handlePointerDown(targetOrEvent);
276
+ else if (target) {
277
+ target.addEventListener("pointerdown", handlePointerDown);
278
+ target.addEventListener("pointermove", handlePointerMove);
279
+ target.addEventListener("pointerup", handlePointerUp);
280
+ target.addEventListener("pointercancel", handlePointerCancel);
281
+ }
282
+ return {
283
+ isDragging: () => activePointerId !== null,
284
+ cancel,
150
285
  destroy: () => {
151
- F(), !n && r && (r.removeEventListener("pointerdown", A), r.removeEventListener("pointermove", j), r.removeEventListener("pointerup", M), r.removeEventListener("pointercancel", N));
286
+ cancel();
287
+ if (!isEvent && target) {
288
+ target.removeEventListener("pointerdown", handlePointerDown);
289
+ target.removeEventListener("pointermove", handlePointerMove);
290
+ target.removeEventListener("pointerup", handlePointerUp);
291
+ target.removeEventListener("pointercancel", handlePointerCancel);
292
+ }
152
293
  }
153
294
  };
154
295
  }
155
- //#endregion
156
- export { e as attachDragGesture };
296
+ export { attachDragGesture };
157
297
 
158
298
  //# sourceMappingURL=drag-gesture.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"drag-gesture.js","names":[],"sources":["../../../src/shared/gesture/drag-gesture.ts"],"sourcesContent":["/**\n * 跨平台/跨浏览器 Pointer 拖拽手势生命周期管理器\n *\n * 封装:\n * 1. setPointerCapture 安全捕获与 window 兜底监听(防 pointer 丢失/离开视口悬挂)\n * 2. 多点触控副指针与未聚焦指针过滤\n * 3. 意图死区(threshold)与滑动轴向判定\n * 4. 可选的零点校准(calibrateOnFirstMove:首个有效 move 重置零点与判定时钟)\n * 5. 100ms 滑动窗口平滑速度估算(Velocity px/s)\n * 6. Window / Handle 跨层事件去重(防重复采样)\n */\n\nconst VELOCITY_WINDOW_MS = 100\n\nexport interface DragSample {\n t: number\n x: number\n y: number\n}\n\nexport interface DragStartInfo {\n pointerId: number\n clientX: number\n clientY: number\n timeStamp: number\n}\n\nexport interface DragMoveInfo {\n pointerId: number\n clientX: number\n clientY: number\n deltaX: number\n deltaY: number\n velocityX: number\n velocityY: number\n velocity: number // 沿配置主轴(若为 both 则为欧氏速度)\n timeStamp: number\n}\n\nexport interface DragEndInfo {\n pointerId: number\n clientX: number\n clientY: number\n deltaX: number\n deltaY: number\n velocityX: number\n velocityY: number\n velocity: number\n timeStamp: number\n /**\n * 手势从**被识别**(越过意图死区;无死区时为 pointerdown)到本次释放的总时长(ms)。\n * `velocity*` 是滑动窗口内的瞬时速度,只描述最后一小段轨迹;需要「整段手势的平均速度」\n * (如判定甩动意图)时用它做分母。\n */\n duration: number\n}\n\nexport interface DragGestureOptions {\n /** 允许拖拽的轴向,默认 'both' */\n axis?: 'x' | 'y' | 'both'\n /** 拖拽启动的意图死区阈值(像素)。默认 0(即时跟手) */\n threshold?: number\n /**\n * 首个有效 pointermove 时把拖拽零点与判定时钟一起重置到该点,默认 false。\n * 吸收「按下 → 首个 move」之间的空隙(触摸输入的首个 move 常已相对按下点偏移),\n * 否则这段位移会在首个 move 一次性兑现而让元素跳。开启后 `DragMoveInfo/DragEndInfo`\n * 的 `delta*` 与 `duration` 都以该点为零点与起点,代价是这段位移被丢弃。\n * 有意图死区时校准落在**越过死区的那次 move**(此时 `startTimeStamp` 的既有重置与之同值)。\n */\n calibrateOnFirstMove?: boolean\n /** 手势启动回调。返回 false 可取消本次拖拽 */\n onStart?: (info: DragStartInfo, event: PointerEvent) => boolean | void\n /** 拖拽移动回调 */\n onMove?: (info: DragMoveInfo, event: PointerEvent) => void\n /** 正常松手回调 */\n onEnd?: (info: DragEndInfo, event: PointerEvent) => void\n /** 未通过意图阈值的 pointerup 回调,供点击定位类控件提交一次 tap */\n onTap?: (info: DragEndInfo, event: PointerEvent) => void\n /** 手势取消/被打断回调(如 pointercancel、外部强行 cancel) */\n onCancel?: (event?: PointerEvent) => void\n}\n\nexport interface DragGestureHandle {\n /** 当前是否有正在进行的拖拽手势 */\n isDragging: () => boolean\n /** 外部强制取消当前拖拽(恢复初态并触发 onCancel) */\n cancel: () => void\n /** 彻底销毁手势监听器与解绑 DOM */\n destroy: () => void\n}\n\n/**\n * 为指定元素挂载统一的 Pointer 拖拽手势,或在已有的 pointerdown 事件中启动手势\n */\nexport function attachDragGesture(\n targetOrEvent: HTMLElement | PointerEvent,\n options: DragGestureOptions\n): DragGestureHandle {\n const isEvent = typeof PointerEvent !== 'undefined' && targetOrEvent instanceof PointerEvent\n const target: HTMLElement | null = isEvent\n ? (targetOrEvent.currentTarget as HTMLElement | null) || (targetOrEvent.target as HTMLElement | null)\n : (targetOrEvent as HTMLElement)\n\n const {\n axis = 'both',\n threshold = 0,\n calibrateOnFirstMove = false,\n onStart,\n onMove,\n onEnd,\n onTap,\n onCancel\n } = options\n\n let activePointerId: number | null = null\n let startX = 0\n let startY = 0\n let startTimeStamp = 0\n let isThresholdPassed = threshold <= 0\n let isCalibrated = false\n let samples: DragSample[] = []\n let handledMoveEvent: PointerEvent | null = null\n let touchGuardTargets: Set<EventTarget> | null = null\n\n /**\n * iOS Safari 滚动接管兜底:\n * WebKit 对 shadow DOM 内 touch-action 的交集计算存在怪癖,触摸落在深层子元素\n * (如 slider thumb、segmented-trigger 的 shadow 内容)时,声明在手势元素上的\n * touch-action: none 可能不生效,iOS 会把触摸判为滚动意图并在越过阈值前触发\n * pointercancel,拖拽因此中断。非被动 touchmove + preventDefault 是 WebKit 也\n * 尊重的最后手段:页面显式处理触摸移动后,滚动识别器不会获胜,也就不会接管。\n */\n function handleTouchMove(e: Event) {\n if (e.cancelable) e.preventDefault()\n }\n\n /**\n * 沿 pointerdown 的 composedPath 在每个 Element/ShadowRoot 挂非被动 touchmove\n * 监听。TouchEvent 不像 PointerEvent 那样可组合:非 composed 的 touchmove 只在\n * 落点所在的 shadow tree 内传播(连 host 都不经过),所以单一手势元素上的监听\n * 对 segmented-trigger 这类深层 shadow 内容完全失效。composedPath 覆盖落点的\n * 全部 shadow tree 链,无论 touchmove 在哪一层传播,路径上必有我们挂载的节点\n * 能收到事件并 preventDefault。document/window 不在挂载范围:touchmove 到不了\n * 它们,挂上也只是死代码。\n */\n function attachTouchGuards(e: PointerEvent) {\n const targets = new Set<EventTarget>()\n const path = typeof e.composedPath === 'function' ? e.composedPath() : []\n for (const node of path) {\n const type = (node as Node).nodeType\n if (type === Node.ELEMENT_NODE || type === Node.DOCUMENT_FRAGMENT_NODE) {\n node.addEventListener('touchmove', handleTouchMove, { capture: true, passive: false })\n targets.add(node)\n }\n }\n touchGuardTargets = targets\n }\n\n function detachTouchGuards() {\n if (!touchGuardTargets) return\n for (const node of touchGuardTargets) {\n node.removeEventListener('touchmove', handleTouchMove, true)\n }\n touchGuardTargets = null\n }\n\n function estimateVelocity(): { vx: number; vy: number; v: number } {\n if (samples.length < 2) return { vx: 0, vy: 0, v: 0 }\n const first = samples[0]\n const last = samples[samples.length - 1]\n const dt = last.t - first.t\n // 采样跨度不足 2ms(同帧/同毫秒的合成或极端快速事件)时不可信,置 0;\n // 2-8ms 的超短轻扫仍按真实跨度上报速度,避免「快速轻扫」被误判为无速度\n // 而回弹(旧守卫 <8ms 会把真实超短轻扫的速度清零)。\n if (dt < 2) return { vx: 0, vy: 0, v: 0 }\n const vx = ((last.x - first.x) / dt) * 1000\n const vy = ((last.y - first.y) / dt) * 1000\n let v = 0\n if (axis === 'x') v = vx\n else if (axis === 'y') v = vy\n else v = Math.hypot(vx, vy)\n return { vx, vy, v }\n }\n\n function detachWindowListeners() {\n window.removeEventListener('pointermove', handlePointerMove, true)\n window.removeEventListener('pointerup', handlePointerUp, true)\n window.removeEventListener('pointercancel', handlePointerCancel, true)\n window.removeEventListener('lostpointercapture', handleLostPointerCapture, true)\n }\n\n function attachWindowListeners() {\n window.addEventListener('pointermove', handlePointerMove, true)\n window.addEventListener('pointerup', handlePointerUp, true)\n window.addEventListener('pointercancel', handlePointerCancel, true)\n window.addEventListener('lostpointercapture', handleLostPointerCapture, true)\n }\n\n function detachTargetListeners() {\n if (!target) return\n target.removeEventListener('pointermove', handlePointerMove)\n target.removeEventListener('pointerup', handlePointerUp)\n target.removeEventListener('pointercancel', handlePointerCancel)\n target.removeEventListener('lostpointercapture', handleLostPointerCapture)\n }\n\n function attachTargetListeners() {\n if (!target) return\n target.addEventListener('pointermove', handlePointerMove)\n target.addEventListener('pointerup', handlePointerUp)\n target.addEventListener('pointercancel', handlePointerCancel)\n target.addEventListener('lostpointercapture', handleLostPointerCapture)\n }\n\n function resetState() {\n if (activePointerId !== null && target && typeof target.hasPointerCapture === 'function') {\n try {\n if (target.hasPointerCapture(activePointerId)) {\n target.releasePointerCapture(activePointerId)\n }\n } catch {\n // ignore\n }\n }\n activePointerId = null\n isThresholdPassed = threshold <= 0\n isCalibrated = false\n samples = []\n handledMoveEvent = null\n detachWindowListeners()\n detachTargetListeners()\n detachTouchGuards()\n }\n\n function handlePointerDown(e: PointerEvent) {\n if (activePointerId !== null) return\n // 真实触控环境下的多点触控副指针不启动手势(合成事件或鼠标环境缺省时不拦截)\n if (e.pointerType === 'touch' && e.isPrimary === false) return\n\n const startInfo: DragStartInfo = {\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n timeStamp: e.timeStamp\n }\n\n if (onStart?.(startInfo, e) === false) return\n\n activePointerId = e.pointerId\n startX = e.clientX\n startY = e.clientY\n startTimeStamp = e.timeStamp\n isThresholdPassed = threshold <= 0\n isCalibrated = false\n samples = [{ t: e.timeStamp, x: e.clientX, y: e.clientY }]\n handledMoveEvent = null\n\n attachWindowListeners()\n attachTargetListeners()\n attachTouchGuards(e)\n\n // 仅在无意图死区时立即捕获指针;若存在死区,延迟至确认拖拽后捕获,避免干扰子元素原生点击\n if (isThresholdPassed) {\n try {\n target?.setPointerCapture?.(e.pointerId)\n } catch {\n // 忽略合成指针或不可捕获上下文(如测试环境)\n }\n }\n }\n\n function handlePointerMove(e: PointerEvent) {\n if (activePointerId !== e.pointerId) return\n if (handledMoveEvent === e) return\n handledMoveEvent = e\n\n if (!isThresholdPassed) {\n const rawDeltaX = e.clientX - startX\n const rawDeltaY = e.clientY - startY\n const distance =\n axis === 'x' ? Math.abs(rawDeltaX) : axis === 'y' ? Math.abs(rawDeltaY) : Math.hypot(rawDeltaX, rawDeltaY)\n\n // 交叉轴位移达到阈值且占主导时,立即让给滚动意图;不能等主轴也越过阈值,\n // 否则这类手势会一直处于 tap 候选态,并在松手时被点击定位控件提交。\n if (axis === 'x' && Math.abs(rawDeltaY) >= threshold && Math.abs(rawDeltaY) > Math.abs(rawDeltaX)) {\n cancel()\n return\n }\n if (axis === 'y' && Math.abs(rawDeltaX) >= threshold && Math.abs(rawDeltaX) > Math.abs(rawDeltaY)) {\n cancel()\n return\n }\n if (distance < threshold) return\n\n isThresholdPassed = true\n // 手势从「被识别」这一刻起算:有意图死区时,pointerdown 之后到越过死区之前的\n // 悬停不属于拖拽轨迹,计进 duration 会稀释整段手势的平均速度。\n startTimeStamp = e.timeStamp\n try {\n target?.setPointerCapture?.(e.pointerId)\n } catch {\n // 忽略合成指针\n }\n }\n\n // 首个有效 move 的基准校准:零点与时钟一起重置到当前位置。位移与时长都必须在这之后\n // 重新求(校准改写了零点),否则首个 move 会拿到校准前的旧位移。\n if (calibrateOnFirstMove && !isCalibrated) {\n isCalibrated = true\n startX = e.clientX\n startY = e.clientY\n startTimeStamp = e.timeStamp\n }\n\n const deltaX = e.clientX - startX\n const deltaY = e.clientY - startY\n\n // 确认拖拽后阻止默认滚动/文字选中\n if (e.cancelable) e.preventDefault()\n\n const now = e.timeStamp\n samples.push({ t: now, x: e.clientX, y: e.clientY })\n while (samples.length > 2 && now - samples[0].t > VELOCITY_WINDOW_MS) {\n samples.shift()\n }\n\n const { vx, vy, v } = estimateVelocity()\n\n const moveInfo: DragMoveInfo = {\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n deltaX,\n deltaY,\n velocityX: vx,\n velocityY: vy,\n velocity: v,\n timeStamp: now\n }\n\n onMove?.(moveInfo, e)\n }\n\n function handlePointerUp(e: PointerEvent) {\n if (activePointerId !== e.pointerId) return\n\n const now = e.timeStamp\n samples.push({ t: now, x: e.clientX, y: e.clientY })\n while (samples.length > 2 && now - samples[0].t > VELOCITY_WINDOW_MS) {\n samples.shift()\n }\n\n const deltaX = e.clientX - startX\n const deltaY = e.clientY - startY\n const { vx, vy, v } = estimateVelocity()\n\n const endInfo: DragEndInfo = {\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n deltaX,\n deltaY,\n velocityX: vx,\n velocityY: vy,\n velocity: v,\n timeStamp: e.timeStamp,\n // 时间戳同源(都是事件 timeStamp),合成事件序列可能倒退或为 0,钳到非负。\n duration: Math.max(0, e.timeStamp - startTimeStamp)\n }\n\n const hadPassedThreshold = isThresholdPassed\n resetState()\n\n if (hadPassedThreshold) {\n onEnd?.(endInfo, e)\n } else {\n onTap?.(endInfo, e)\n onCancel?.(e)\n }\n }\n\n function handlePointerCancel(e: PointerEvent) {\n if (activePointerId !== e.pointerId) return\n resetState()\n onCancel?.(e)\n }\n\n /**\n * lostpointercapture 不能当作 pointercancel:touch 指针在 pointerdown 时会被浏览器\n * 隐式捕获到命中元素(如 slider thumb、segmented-trigger 内容),组件随后\n * setPointerCapture(target) 把捕获转手到手势元素,命中元素先收到 lostpointercapture——\n * 这是正常转手而非取消,若直接走 cancel 会把刚启动的拖拽杀死(值只走一步即冻结)。\n * 只有手势元素自身意外丢失捕获(如元素被移出文档)才应取消。\n *\n * resetState 内 releasePointerCapture 产生的 lostpointercapture 会在 activePointerId\n * 置空之后异步到达,被 pointerId 守卫挡住,不会误伤。\n */\n function handleLostPointerCapture(e: PointerEvent) {\n if (activePointerId !== e.pointerId) return\n if (e.target !== target) return\n resetState()\n onCancel?.(e)\n }\n\n function cancel() {\n if (activePointerId === null) return\n resetState()\n onCancel?.()\n }\n\n if (isEvent) {\n handlePointerDown(targetOrEvent)\n } else if (target) {\n target.addEventListener('pointerdown', handlePointerDown)\n target.addEventListener('pointermove', handlePointerMove)\n target.addEventListener('pointerup', handlePointerUp)\n target.addEventListener('pointercancel', handlePointerCancel)\n }\n\n return {\n isDragging: () => activePointerId !== null,\n cancel,\n destroy: () => {\n cancel()\n if (!isEvent && target) {\n target.removeEventListener('pointerdown', handlePointerDown)\n target.removeEventListener('pointermove', handlePointerMove)\n target.removeEventListener('pointerup', handlePointerUp)\n target.removeEventListener('pointercancel', handlePointerCancel)\n }\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"drag-gesture.js","names":[],"sources":["../../../src/shared/gesture/drag-gesture.ts"],"sourcesContent":["/**\n * 跨平台/跨浏览器 Pointer 拖拽手势生命周期管理器\n *\n * 封装:\n * 1. setPointerCapture 安全捕获与 window 兜底监听(防 pointer 丢失/离开视口悬挂)\n * 2. 多点触控副指针与未聚焦指针过滤\n * 3. 意图死区(threshold)与滑动轴向判定\n * 4. 可选的零点校准(calibrateOnFirstMove:首个有效 move 重置零点与判定时钟)\n * 5. 100ms 滑动窗口平滑速度估算(Velocity px/s)\n * 6. Window / Handle 跨层事件去重(防重复采样)\n */\n\nconst VELOCITY_WINDOW_MS = 100\n\nexport interface DragSample {\n t: number\n x: number\n y: number\n}\n\nexport interface DragStartInfo {\n pointerId: number\n clientX: number\n clientY: number\n timeStamp: number\n}\n\nexport interface DragMoveInfo {\n pointerId: number\n clientX: number\n clientY: number\n deltaX: number\n deltaY: number\n velocityX: number\n velocityY: number\n velocity: number // 沿配置主轴(若为 both 则为欧氏速度)\n timeStamp: number\n}\n\nexport interface DragEndInfo {\n pointerId: number\n clientX: number\n clientY: number\n deltaX: number\n deltaY: number\n velocityX: number\n velocityY: number\n velocity: number\n timeStamp: number\n /**\n * 手势从**被识别**(越过意图死区;无死区时为 pointerdown)到本次释放的总时长(ms)。\n * `velocity*` 是滑动窗口内的瞬时速度,只描述最后一小段轨迹;需要「整段手势的平均速度」\n * (如判定甩动意图)时用它做分母。\n */\n duration: number\n}\n\nexport interface DragGestureOptions {\n /** 允许拖拽的轴向,默认 'both' */\n axis?: 'x' | 'y' | 'both'\n /** 拖拽启动的意图死区阈值(像素)。默认 0(即时跟手) */\n threshold?: number\n /**\n * 首个有效 pointermove 时把拖拽零点与判定时钟一起重置到该点,默认 false。\n * 吸收「按下 → 首个 move」之间的空隙(触摸输入的首个 move 常已相对按下点偏移),\n * 否则这段位移会在首个 move 一次性兑现而让元素跳。开启后 `DragMoveInfo/DragEndInfo`\n * 的 `delta*` 与 `duration` 都以该点为零点与起点,代价是这段位移被丢弃。\n * 有意图死区时校准落在**越过死区的那次 move**(此时 `startTimeStamp` 的既有重置与之同值)。\n */\n calibrateOnFirstMove?: boolean\n /** 手势启动回调。返回 false 可取消本次拖拽 */\n onStart?: (info: DragStartInfo, event: PointerEvent) => boolean | void\n /** 拖拽移动回调 */\n onMove?: (info: DragMoveInfo, event: PointerEvent) => void\n /** 正常松手回调 */\n onEnd?: (info: DragEndInfo, event: PointerEvent) => void\n /** 未通过意图阈值的 pointerup 回调,供点击定位类控件提交一次 tap */\n onTap?: (info: DragEndInfo, event: PointerEvent) => void\n /** 手势取消/被打断回调(如 pointercancel、外部强行 cancel) */\n onCancel?: (event?: PointerEvent) => void\n}\n\nexport interface DragGestureHandle {\n /** 当前是否有正在进行的拖拽手势 */\n isDragging: () => boolean\n /** 外部强制取消当前拖拽(恢复初态并触发 onCancel) */\n cancel: () => void\n /** 彻底销毁手势监听器与解绑 DOM */\n destroy: () => void\n}\n\n/**\n * 为指定元素挂载统一的 Pointer 拖拽手势,或在已有的 pointerdown 事件中启动手势\n */\nexport function attachDragGesture(\n targetOrEvent: HTMLElement | PointerEvent,\n options: DragGestureOptions\n): DragGestureHandle {\n const isEvent = typeof PointerEvent !== 'undefined' && targetOrEvent instanceof PointerEvent\n const target: HTMLElement | null = isEvent\n ? (targetOrEvent.currentTarget as HTMLElement | null) || (targetOrEvent.target as HTMLElement | null)\n : (targetOrEvent as HTMLElement)\n\n const {\n axis = 'both',\n threshold = 0,\n calibrateOnFirstMove = false,\n onStart,\n onMove,\n onEnd,\n onTap,\n onCancel\n } = options\n\n let activePointerId: number | null = null\n let startX = 0\n let startY = 0\n let startTimeStamp = 0\n let isThresholdPassed = threshold <= 0\n let isCalibrated = false\n let samples: DragSample[] = []\n let handledMoveEvent: PointerEvent | null = null\n let touchGuardTargets: Set<EventTarget> | null = null\n\n /**\n * iOS Safari 滚动接管兜底:\n * WebKit 对 shadow DOM 内 touch-action 的交集计算存在怪癖,触摸落在深层子元素\n * (如 slider thumb、segmented-trigger 的 shadow 内容)时,声明在手势元素上的\n * touch-action: none 可能不生效,iOS 会把触摸判为滚动意图并在越过阈值前触发\n * pointercancel,拖拽因此中断。非被动 touchmove + preventDefault 是 WebKit 也\n * 尊重的最后手段:页面显式处理触摸移动后,滚动识别器不会获胜,也就不会接管。\n */\n function handleTouchMove(e: Event) {\n if (e.cancelable) e.preventDefault()\n }\n\n /**\n * 沿 pointerdown 的 composedPath 在每个 Element/ShadowRoot 挂非被动 touchmove\n * 监听。TouchEvent 不像 PointerEvent 那样可组合:非 composed 的 touchmove 只在\n * 落点所在的 shadow tree 内传播(连 host 都不经过),所以单一手势元素上的监听\n * 对 segmented-trigger 这类深层 shadow 内容完全失效。composedPath 覆盖落点的\n * 全部 shadow tree 链,无论 touchmove 在哪一层传播,路径上必有我们挂载的节点\n * 能收到事件并 preventDefault。document/window 不在挂载范围:touchmove 到不了\n * 它们,挂上也只是死代码。\n */\n function attachTouchGuards(e: PointerEvent) {\n const targets = new Set<EventTarget>()\n const path = typeof e.composedPath === 'function' ? e.composedPath() : []\n for (const node of path) {\n const type = (node as Node).nodeType\n if (type === Node.ELEMENT_NODE || type === Node.DOCUMENT_FRAGMENT_NODE) {\n node.addEventListener('touchmove', handleTouchMove, { capture: true, passive: false })\n targets.add(node)\n }\n }\n touchGuardTargets = targets\n }\n\n function detachTouchGuards() {\n if (!touchGuardTargets) return\n for (const node of touchGuardTargets) {\n node.removeEventListener('touchmove', handleTouchMove, true)\n }\n touchGuardTargets = null\n }\n\n function estimateVelocity(): { vx: number; vy: number; v: number } {\n if (samples.length < 2) return { vx: 0, vy: 0, v: 0 }\n const first = samples[0]\n const last = samples[samples.length - 1]\n const dt = last.t - first.t\n // 采样跨度不足 2ms(同帧/同毫秒的合成或极端快速事件)时不可信,置 0;\n // 2-8ms 的超短轻扫仍按真实跨度上报速度,避免「快速轻扫」被误判为无速度\n // 而回弹(旧守卫 <8ms 会把真实超短轻扫的速度清零)。\n if (dt < 2) return { vx: 0, vy: 0, v: 0 }\n const vx = ((last.x - first.x) / dt) * 1000\n const vy = ((last.y - first.y) / dt) * 1000\n let v = 0\n if (axis === 'x') v = vx\n else if (axis === 'y') v = vy\n else v = Math.hypot(vx, vy)\n return { vx, vy, v }\n }\n\n function detachWindowListeners() {\n window.removeEventListener('pointermove', handlePointerMove, true)\n window.removeEventListener('pointerup', handlePointerUp, true)\n window.removeEventListener('pointercancel', handlePointerCancel, true)\n window.removeEventListener('lostpointercapture', handleLostPointerCapture, true)\n }\n\n function attachWindowListeners() {\n window.addEventListener('pointermove', handlePointerMove, true)\n window.addEventListener('pointerup', handlePointerUp, true)\n window.addEventListener('pointercancel', handlePointerCancel, true)\n window.addEventListener('lostpointercapture', handleLostPointerCapture, true)\n }\n\n function detachTargetListeners() {\n if (!target) return\n target.removeEventListener('pointermove', handlePointerMove)\n target.removeEventListener('pointerup', handlePointerUp)\n target.removeEventListener('pointercancel', handlePointerCancel)\n target.removeEventListener('lostpointercapture', handleLostPointerCapture)\n }\n\n function attachTargetListeners() {\n if (!target) return\n target.addEventListener('pointermove', handlePointerMove)\n target.addEventListener('pointerup', handlePointerUp)\n target.addEventListener('pointercancel', handlePointerCancel)\n target.addEventListener('lostpointercapture', handleLostPointerCapture)\n }\n\n function resetState() {\n if (activePointerId !== null && target && typeof target.hasPointerCapture === 'function') {\n try {\n if (target.hasPointerCapture(activePointerId)) {\n target.releasePointerCapture(activePointerId)\n }\n } catch {\n // ignore\n }\n }\n activePointerId = null\n isThresholdPassed = threshold <= 0\n isCalibrated = false\n samples = []\n handledMoveEvent = null\n detachWindowListeners()\n detachTargetListeners()\n detachTouchGuards()\n }\n\n function handlePointerDown(e: PointerEvent) {\n if (activePointerId !== null) return\n // 真实触控环境下的多点触控副指针不启动手势(合成事件或鼠标环境缺省时不拦截)\n if (e.pointerType === 'touch' && e.isPrimary === false) return\n\n const startInfo: DragStartInfo = {\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n timeStamp: e.timeStamp\n }\n\n if (onStart?.(startInfo, e) === false) return\n\n activePointerId = e.pointerId\n startX = e.clientX\n startY = e.clientY\n startTimeStamp = e.timeStamp\n isThresholdPassed = threshold <= 0\n isCalibrated = false\n samples = [{ t: e.timeStamp, x: e.clientX, y: e.clientY }]\n handledMoveEvent = null\n\n attachWindowListeners()\n attachTargetListeners()\n attachTouchGuards(e)\n\n // 仅在无意图死区时立即捕获指针;若存在死区,延迟至确认拖拽后捕获,避免干扰子元素原生点击\n if (isThresholdPassed) {\n try {\n target?.setPointerCapture?.(e.pointerId)\n } catch {\n // 忽略合成指针或不可捕获上下文(如测试环境)\n }\n }\n }\n\n function handlePointerMove(e: PointerEvent) {\n if (activePointerId !== e.pointerId) return\n if (handledMoveEvent === e) return\n handledMoveEvent = e\n\n if (!isThresholdPassed) {\n const rawDeltaX = e.clientX - startX\n const rawDeltaY = e.clientY - startY\n const distance =\n axis === 'x' ? Math.abs(rawDeltaX) : axis === 'y' ? Math.abs(rawDeltaY) : Math.hypot(rawDeltaX, rawDeltaY)\n\n // 交叉轴位移达到阈值且占主导时,立即让给滚动意图;不能等主轴也越过阈值,\n // 否则这类手势会一直处于 tap 候选态,并在松手时被点击定位控件提交。\n if (axis === 'x' && Math.abs(rawDeltaY) >= threshold && Math.abs(rawDeltaY) > Math.abs(rawDeltaX)) {\n cancel()\n return\n }\n if (axis === 'y' && Math.abs(rawDeltaX) >= threshold && Math.abs(rawDeltaX) > Math.abs(rawDeltaY)) {\n cancel()\n return\n }\n if (distance < threshold) return\n\n isThresholdPassed = true\n // 手势从「被识别」这一刻起算:有意图死区时,pointerdown 之后到越过死区之前的\n // 悬停不属于拖拽轨迹,计进 duration 会稀释整段手势的平均速度。\n startTimeStamp = e.timeStamp\n try {\n target?.setPointerCapture?.(e.pointerId)\n } catch {\n // 忽略合成指针\n }\n }\n\n // 首个有效 move 的基准校准:零点与时钟一起重置到当前位置。位移与时长都必须在这之后\n // 重新求(校准改写了零点),否则首个 move 会拿到校准前的旧位移。\n if (calibrateOnFirstMove && !isCalibrated) {\n isCalibrated = true\n startX = e.clientX\n startY = e.clientY\n startTimeStamp = e.timeStamp\n }\n\n const deltaX = e.clientX - startX\n const deltaY = e.clientY - startY\n\n // 确认拖拽后阻止默认滚动/文字选中\n if (e.cancelable) e.preventDefault()\n\n const now = e.timeStamp\n samples.push({ t: now, x: e.clientX, y: e.clientY })\n while (samples.length > 2 && now - samples[0].t > VELOCITY_WINDOW_MS) {\n samples.shift()\n }\n\n const { vx, vy, v } = estimateVelocity()\n\n const moveInfo: DragMoveInfo = {\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n deltaX,\n deltaY,\n velocityX: vx,\n velocityY: vy,\n velocity: v,\n timeStamp: now\n }\n\n onMove?.(moveInfo, e)\n }\n\n function handlePointerUp(e: PointerEvent) {\n if (activePointerId !== e.pointerId) return\n\n const now = e.timeStamp\n samples.push({ t: now, x: e.clientX, y: e.clientY })\n while (samples.length > 2 && now - samples[0].t > VELOCITY_WINDOW_MS) {\n samples.shift()\n }\n\n const deltaX = e.clientX - startX\n const deltaY = e.clientY - startY\n const { vx, vy, v } = estimateVelocity()\n\n const endInfo: DragEndInfo = {\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n deltaX,\n deltaY,\n velocityX: vx,\n velocityY: vy,\n velocity: v,\n timeStamp: e.timeStamp,\n // 时间戳同源(都是事件 timeStamp),合成事件序列可能倒退或为 0,钳到非负。\n duration: Math.max(0, e.timeStamp - startTimeStamp)\n }\n\n const hadPassedThreshold = isThresholdPassed\n resetState()\n\n if (hadPassedThreshold) {\n onEnd?.(endInfo, e)\n } else {\n onTap?.(endInfo, e)\n onCancel?.(e)\n }\n }\n\n function handlePointerCancel(e: PointerEvent) {\n if (activePointerId !== e.pointerId) return\n resetState()\n onCancel?.(e)\n }\n\n /**\n * lostpointercapture 不能当作 pointercancel:touch 指针在 pointerdown 时会被浏览器\n * 隐式捕获到命中元素(如 slider thumb、segmented-trigger 内容),组件随后\n * setPointerCapture(target) 把捕获转手到手势元素,命中元素先收到 lostpointercapture——\n * 这是正常转手而非取消,若直接走 cancel 会把刚启动的拖拽杀死(值只走一步即冻结)。\n * 只有手势元素自身意外丢失捕获(如元素被移出文档)才应取消。\n *\n * resetState 内 releasePointerCapture 产生的 lostpointercapture 会在 activePointerId\n * 置空之后异步到达,被 pointerId 守卫挡住,不会误伤。\n */\n function handleLostPointerCapture(e: PointerEvent) {\n if (activePointerId !== e.pointerId) return\n if (e.target !== target) return\n resetState()\n onCancel?.(e)\n }\n\n function cancel() {\n if (activePointerId === null) return\n resetState()\n onCancel?.()\n }\n\n if (isEvent) {\n handlePointerDown(targetOrEvent)\n } else if (target) {\n target.addEventListener('pointerdown', handlePointerDown)\n target.addEventListener('pointermove', handlePointerMove)\n target.addEventListener('pointerup', handlePointerUp)\n target.addEventListener('pointercancel', handlePointerCancel)\n }\n\n return {\n isDragging: () => activePointerId !== null,\n cancel,\n destroy: () => {\n cancel()\n if (!isEvent && target) {\n target.removeEventListener('pointerdown', handlePointerDown)\n target.removeEventListener('pointermove', handlePointerMove)\n target.removeEventListener('pointerup', handlePointerUp)\n target.removeEventListener('pointercancel', handlePointerCancel)\n }\n }\n }\n}\n"],"mappings":"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"}
@@ -1,23 +1,56 @@
1
- //#region src/shared/gesture/physics.ts
2
- function e(e, t, n) {
3
- return Math.min(n, Math.max(t, e));
1
+ // src/shared/gesture/physics.ts
2
+ /**
3
+ * 物理运动与数学辅助函数(阻尼、钳制与归一化)
4
+ */
5
+ /**
6
+ * 钳制数值在 [min, max] 范围内
7
+ */
8
+ function clamp(value, min, max) {
9
+ return Math.min(max, Math.max(min, value));
4
10
  }
5
- function t(e, t) {
6
- if (t.length === 0) return -1;
7
- let n = Infinity, r = 0;
8
- for (let i = 0; i < t.length; i++) {
9
- let a = Math.abs(e - t[i]);
10
- a < n && (n = a, r = i);
11
+ /**
12
+ * 寻找与目标值距离最近的采样点索引。
13
+ * @param value 目标数值
14
+ * @param points 采样点数组
15
+ * @returns 最近采样点的下标(空数组返回 -1)
16
+ */
17
+ function snapToNearest(value, points) {
18
+ if (points.length === 0) return -1;
19
+ let minDistance = Infinity;
20
+ let nearestIndex = 0;
21
+ for (let i = 0; i < points.length; i++) {
22
+ const dist = Math.abs(value - points[i]);
23
+ if (dist < minDistance) {
24
+ minDistance = dist;
25
+ nearestIndex = i;
26
+ }
11
27
  }
12
- return r;
28
+ return nearestIndex;
13
29
  }
14
- function n(t, n, r) {
15
- return r <= n ? 0 : (e(t, n, r) - n) / (r - n);
30
+ /**
31
+ * 将数值钳制并归一化到 [0, 1] 区间(0 对应 min,1 对应 max)。
32
+ * @param value 输入值
33
+ * @param min 最小值
34
+ * @param max 最大值
35
+ */
36
+ function normalizeProgress(value, min, max) {
37
+ if (max <= min) return 0;
38
+ return (clamp(value, min, max) - min) / (max - min);
16
39
  }
17
- function r(e) {
18
- return e >= 0 ? e : Math.sign(e) * Math.abs(e) ** .5;
40
+ /**
41
+ * 「不允许方向」的过冲阻尼。
42
+ *
43
+ * 允许方向原样 1:1 通过(由调用方保证传入的符号空间正确);反向按平方根压缩,压缩比
44
+ * 随位移增大而下降、天然自限幅(400px 过冲只剩 20px),因此不需要额外的位移上限。
45
+ *
46
+ * 它阻尼的是**本次手势自零点起的增量**,调用方再把它叠加到抓取瞬间的基准位移上
47
+ * (`base + damp(delta)`);直接阻尼总位移会把基准位移也一起压缩。
48
+ * @param delta 自手势零点起、沿拖拽主轴的增量;正值 = 允许方向
49
+ */
50
+ function dampOverscroll(delta) {
51
+ if (delta >= 0) return delta;
52
+ return Math.sign(delta) * Math.abs(delta) ** .5;
19
53
  }
20
- //#endregion
21
- export { e as clamp, r as dampOverscroll, n as normalizeProgress, t as snapToNearest };
54
+ export { clamp, dampOverscroll, normalizeProgress, snapToNearest };
22
55
 
23
56
  //# sourceMappingURL=physics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"physics.js","names":[],"sources":["../../../src/shared/gesture/physics.ts"],"sourcesContent":["/**\n * 物理运动与数学辅助函数(阻尼、钳制与归一化)\n */\n\n/**\n * 钳制数值在 [min, max] 范围内\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\n/**\n * 寻找与目标值距离最近的采样点索引。\n * @param value 目标数值\n * @param points 采样点数组\n * @returns 最近采样点的下标(空数组返回 -1)\n */\nexport function snapToNearest(value: number, points: number[]): number {\n if (points.length === 0) return -1\n let minDistance = Infinity\n let nearestIndex = 0\n for (let i = 0; i < points.length; i++) {\n const dist = Math.abs(value - points[i])\n if (dist < minDistance) {\n minDistance = dist\n nearestIndex = i\n }\n }\n return nearestIndex\n}\n\n/**\n * 将数值钳制并归一化到 [0, 1] 区间(0 对应 min,1 对应 max)。\n * @param value 输入值\n * @param min 最小值\n * @param max 最大值\n */\nexport function normalizeProgress(value: number, min: number, max: number): number {\n if (max <= min) return 0\n const clamped = clamp(value, min, max)\n return (clamped - min) / (max - min)\n}\n\n/**\n * 「不允许方向」的过冲阻尼。\n *\n * 允许方向原样 1:1 通过(由调用方保证传入的符号空间正确);反向按平方根压缩,压缩比\n * 随位移增大而下降、天然自限幅(400px 过冲只剩 20px),因此不需要额外的位移上限。\n *\n * 它阻尼的是**本次手势自零点起的增量**,调用方再把它叠加到抓取瞬间的基准位移上\n * (`base + damp(delta)`);直接阻尼总位移会把基准位移也一起压缩。\n * @param delta 自手势零点起、沿拖拽主轴的增量;正值 = 允许方向\n */\nexport function dampOverscroll(delta: number): number {\n if (delta >= 0) return delta\n return Math.sign(delta) * Math.abs(delta) ** 0.5\n}\n"],"mappings":";AAOA,SAAgB,EAAM,GAAe,GAAa,GAAqB;CACrE,OAAO,KAAK,IAAI,GAAK,KAAK,IAAI,GAAK,CAAK,CAAC;AAC3C;AAQA,SAAgB,EAAc,GAAe,GAA0B;CACrE,IAAI,EAAO,WAAW,GAAG,OAAO;CAChC,IAAI,IAAc,UACd,IAAe;CACnB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAO,QAAQ,KAAK;EACtC,IAAM,IAAO,KAAK,IAAI,IAAQ,EAAO,EAAE;EACvC,AAAI,IAAO,MACT,IAAc,GACd,IAAe;CAEnB;CACA,OAAO;AACT;AAQA,SAAgB,EAAkB,GAAe,GAAa,GAAqB;CAGjF,OAFI,KAAO,IAAY,KACP,EAAM,GAAO,GAAK,CAC1B,IAAU,MAAQ,IAAM;AAClC;AAYA,SAAgB,EAAe,GAAuB;CAEpD,OADI,KAAS,IAAU,IAChB,KAAK,KAAK,CAAK,IAAI,KAAK,IAAI,CAAK,KAAK;AAC/C"}
1
+ {"version":3,"file":"physics.js","names":[],"sources":["../../../src/shared/gesture/physics.ts"],"sourcesContent":["/**\n * 物理运动与数学辅助函数(阻尼、钳制与归一化)\n */\n\n/**\n * 钳制数值在 [min, max] 范围内\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\n/**\n * 寻找与目标值距离最近的采样点索引。\n * @param value 目标数值\n * @param points 采样点数组\n * @returns 最近采样点的下标(空数组返回 -1)\n */\nexport function snapToNearest(value: number, points: number[]): number {\n if (points.length === 0) return -1\n let minDistance = Infinity\n let nearestIndex = 0\n for (let i = 0; i < points.length; i++) {\n const dist = Math.abs(value - points[i])\n if (dist < minDistance) {\n minDistance = dist\n nearestIndex = i\n }\n }\n return nearestIndex\n}\n\n/**\n * 将数值钳制并归一化到 [0, 1] 区间(0 对应 min,1 对应 max)。\n * @param value 输入值\n * @param min 最小值\n * @param max 最大值\n */\nexport function normalizeProgress(value: number, min: number, max: number): number {\n if (max <= min) return 0\n const clamped = clamp(value, min, max)\n return (clamped - min) / (max - min)\n}\n\n/**\n * 「不允许方向」的过冲阻尼。\n *\n * 允许方向原样 1:1 通过(由调用方保证传入的符号空间正确);反向按平方根压缩,压缩比\n * 随位移增大而下降、天然自限幅(400px 过冲只剩 20px),因此不需要额外的位移上限。\n *\n * 它阻尼的是**本次手势自零点起的增量**,调用方再把它叠加到抓取瞬间的基准位移上\n * (`base + damp(delta)`);直接阻尼总位移会把基准位移也一起压缩。\n * @param delta 自手势零点起、沿拖拽主轴的增量;正值 = 允许方向\n */\nexport function dampOverscroll(delta: number): number {\n if (delta >= 0) return delta\n return Math.sign(delta) * Math.abs(delta) ** 0.5\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,MAAM,OAAe,KAAa,KAAqB;CACrE,OAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAC3C;;;;;;;AAQA,SAAgB,cAAc,OAAe,QAA0B;CACrE,IAAI,OAAO,WAAW,GAAG,OAAO;CAChC,IAAI,cAAc;CAClB,IAAI,eAAe;CACnB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,MAAM,OAAO,KAAK,IAAI,QAAQ,OAAO,EAAE;EACvC,IAAI,OAAO,aAAa;GACtB,cAAc;GACd,eAAe;EACjB;CACF;CACA,OAAO;AACT;;;;;;;AAQA,SAAgB,kBAAkB,OAAe,KAAa,KAAqB;CACjF,IAAI,OAAO,KAAK,OAAO;CAEvB,QADgB,MAAM,OAAO,KAAK,GACpB,IAAI,QAAQ,MAAM;AAClC;;;;;;;;;;;AAYA,SAAgB,eAAe,OAAuB;CACpD,IAAI,SAAS,GAAG,OAAO;CACvB,OAAO,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK;AAC/C"}