@greypan/web-ui 11.2.0 → 12.0.0

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 +72 -71
  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,84 +1,149 @@
1
- import { definePlugin as e } from "@greypan/js-kit";
2
- //#region src/shared/option-portal/combobox-shell.ts
3
- function t(e) {
4
- function t(t = !1) {
5
- e.canOpen() === !1 || e.getIsOpen() || (e.setIsOpen(!0), e.dispatchOpenChange(), e.onOpen?.(t), e.syncScrollLock(!0), e.isPortal() ? requestAnimationFrame(() => {
6
- e.getIsOpen() && e.openOverlay(t);
7
- }) : e.openOverlay(t));
1
+ import { definePlugin } from "@greypan/js-kit";
2
+ // src/shared/option-portal/combobox-shell.ts
3
+ function createComboboxOpenController(hooks) {
4
+ function open(isKeyboardNavigation = false) {
5
+ if (hooks.canOpen() === false || hooks.getIsOpen()) return;
6
+ hooks.setIsOpen(true);
7
+ hooks.dispatchOpenChange();
8
+ hooks.onOpen?.(isKeyboardNavigation);
9
+ hooks.syncScrollLock(true);
10
+ if (hooks.isPortal()) requestAnimationFrame(() => {
11
+ if (hooks.getIsOpen()) hooks.openOverlay(isKeyboardNavigation);
12
+ });
13
+ else hooks.openOverlay(isKeyboardNavigation);
8
14
  }
9
- function n() {
10
- e.getIsOpen() && (e.onBeforeClose?.(), e.setIsOpen(!1), e.dispatchOpenChange(), e.onAfterClose?.(), e.syncScrollLock(!1), e.closeOverlay());
15
+ function close() {
16
+ if (!hooks.getIsOpen()) return;
17
+ hooks.onBeforeClose?.();
18
+ hooks.setIsOpen(false);
19
+ hooks.dispatchOpenChange();
20
+ hooks.onAfterClose?.();
21
+ hooks.syncScrollLock(false);
22
+ hooks.closeOverlay();
11
23
  }
12
24
  return {
13
- open: t,
14
- close: n
25
+ open,
26
+ close
15
27
  };
16
28
  }
17
- var n = () => e((e) => {
18
- let t = null, n = () => e.getCustomTrigger() ?? e.getFallbackTrigger() ?? null, r = (e) => {
19
- let t = e?.value;
20
- return typeof t == "string" ? t : null;
21
- }, i = (e, t) => {
22
- let n = e.target;
23
- return !!t && n instanceof Node && (n === t || t.contains(n));
24
- }, a = (t) => {
25
- let a = n();
26
- if (!i(t, a)) return;
27
- let o = r(a);
28
- o !== null && e.onInput(o);
29
- }, o = (e) => {
30
- i(e, n()) && e.stopPropagation();
31
- }, s = () => e.onClick(), c = (t) => e.onFocusIn(t), l = (t) => e.onFocusOut(t);
29
+ /**
30
+ * combobox trigger 委托层(autocomplete)。
31
+ *
32
+ * 默认 trigger 是 shadow 内的 `web-ui-input`,自定义 trigger 由 `slot[name="trigger"]`
33
+ * 提供(`web-ui-textarea` 等)。两者对组件暴露同一形状:字符串 value、可聚焦、
34
+ * 派发 composed 的 input / click / focusin / focusout。委托层把这些差异收敛成一份接口:
35
+ * 监听统一挂在包装 div 上(事件委托,覆盖 shadow 内与 light DOM 两条路径),
36
+ * 文本读写只认 trigger host 的 value 属性。
37
+ *
38
+ * 焦点用 focusin/focusout 而非 focus/blur:后两者不冒泡,到不了包装 div
39
+ * (实测:shadow 内默认 trigger 与 light DOM 自定义 trigger 都不触发包装 div 的 focus/blur)。
40
+ *
41
+ * trigger 自身派发的 change(web-ui-input/textarea 在原生 change 不 composed 时补发)
42
+ * 必须被拦下:组件的 change 只表示「选中提交」,否则失焦即误报一次 change。
43
+ */
44
+ const defineComboboxTrigger = () => definePlugin((source) => {
45
+ let boundWrapper = null;
46
+ const getTrigger = () => source.getCustomTrigger() ?? source.getFallbackTrigger() ?? null;
47
+ const readValue = (trigger) => {
48
+ const value = trigger?.value;
49
+ return typeof value === "string" ? value : null;
50
+ };
51
+ const isWithinTrigger = (event, trigger) => {
52
+ const target = event.target;
53
+ return !!trigger && target instanceof Node && (target === trigger || trigger.contains(target));
54
+ };
55
+ const onInput = (event) => {
56
+ const trigger = getTrigger();
57
+ if (!isWithinTrigger(event, trigger)) return;
58
+ const value = readValue(trigger);
59
+ if (value !== null) source.onInput(value);
60
+ };
61
+ const onNativeChange = (event) => {
62
+ if (isWithinTrigger(event, getTrigger())) event.stopPropagation();
63
+ };
64
+ const onClick = () => source.onClick();
65
+ const onFocusIn = (event) => source.onFocusIn(event);
66
+ const onFocusOut = (event) => source.onFocusOut(event);
32
67
  return {
33
- getTrigger: n,
34
- getValue: () => r(n()),
35
- setValue(e) {
36
- let t = n(), i = r(t);
37
- t && i !== null && i !== e && (t.value = e);
68
+ getTrigger,
69
+ getValue: () => readValue(getTrigger()),
70
+ setValue(value) {
71
+ const trigger = getTrigger();
72
+ const current = readValue(trigger);
73
+ if (!trigger || current === null || current === value) return;
74
+ trigger.value = value;
38
75
  },
39
- isMultilineEdit(e) {
40
- return e.composedPath()[0] instanceof HTMLTextAreaElement;
76
+ isMultilineEdit(event) {
77
+ return event.composedPath()[0] instanceof HTMLTextAreaElement;
41
78
  },
42
- focusTrigger(e) {
43
- n()?.focus(e);
79
+ focusTrigger(options) {
80
+ getTrigger()?.focus(options);
44
81
  },
45
82
  blurTrigger() {
46
- n()?.blur();
83
+ getTrigger()?.blur();
47
84
  },
48
85
  bind() {
49
- let n = e.getWrapper();
50
- n && n !== t && (t = n, n.addEventListener("input", a), n.addEventListener("change", o), n.addEventListener("click", s), n.addEventListener("focusin", c), n.addEventListener("focusout", l));
86
+ const wrapper = source.getWrapper();
87
+ if (!wrapper || wrapper === boundWrapper) return;
88
+ boundWrapper = wrapper;
89
+ wrapper.addEventListener("input", onInput);
90
+ wrapper.addEventListener("change", onNativeChange);
91
+ wrapper.addEventListener("click", onClick);
92
+ wrapper.addEventListener("focusin", onFocusIn);
93
+ wrapper.addEventListener("focusout", onFocusOut);
51
94
  },
52
95
  dispose() {
53
- let e = t;
54
- t = null, e && (e.removeEventListener("input", a), e.removeEventListener("change", o), e.removeEventListener("click", s), e.removeEventListener("focusin", c), e.removeEventListener("focusout", l));
96
+ const wrapper = boundWrapper;
97
+ boundWrapper = null;
98
+ if (!wrapper) return;
99
+ wrapper.removeEventListener("input", onInput);
100
+ wrapper.removeEventListener("change", onNativeChange);
101
+ wrapper.removeEventListener("click", onClick);
102
+ wrapper.removeEventListener("focusin", onFocusIn);
103
+ wrapper.removeEventListener("focusout", onFocusOut);
55
104
  }
56
105
  };
57
106
  });
58
- function r(e) {
59
- function t(t) {
60
- t.addEventListener("click", e.onClick), t.addEventListener("pointerover", e.onPointerOver), t.addEventListener("pointerdown", e.onPointerDown), t.addEventListener("option-update", e.onUpdate);
107
+ /** option 四事件监听对的绑定/解绑;两组件的 handler 签名一致,仅实现不同。 */
108
+ function createOptionListenerBinding(handlers) {
109
+ function bind(option) {
110
+ option.addEventListener("click", handlers.onClick);
111
+ option.addEventListener("pointerover", handlers.onPointerOver);
112
+ option.addEventListener("pointerdown", handlers.onPointerDown);
113
+ option.addEventListener("option-update", handlers.onUpdate);
61
114
  }
62
- function n(t) {
63
- t.removeEventListener("click", e.onClick), t.removeEventListener("pointerover", e.onPointerOver), t.removeEventListener("pointerdown", e.onPointerDown), t.removeEventListener("option-update", e.onUpdate);
115
+ function unbind(option) {
116
+ option.removeEventListener("click", handlers.onClick);
117
+ option.removeEventListener("pointerover", handlers.onPointerOver);
118
+ option.removeEventListener("pointerdown", handlers.onPointerDown);
119
+ option.removeEventListener("option-update", handlers.onUpdate);
64
120
  }
65
121
  return {
66
- bind: t,
67
- unbind: n
122
+ bind,
123
+ unbind
68
124
  };
69
125
  }
70
- function i(e, t, n, r) {
126
+ /**
127
+ * focusout 关闭复核:焦点是否真的离开了宿主与 panel。
128
+ * rAF 等待 click/pointerdown 相关的焦点迁移完成后再判定。
129
+ */
130
+ function handleComboboxFocusOut(host, getHandle, getIsOpen, close) {
71
131
  requestAnimationFrame(() => {
72
- let i = t();
73
- n() && !e.matches(":focus-within") && !i?.hasFocusWithin() && r();
132
+ const handle = getHandle();
133
+ if (getIsOpen() && !host.matches(":focus-within") && !handle?.hasFocusWithin()) close();
74
134
  });
75
135
  }
76
- function a(e, t, n) {
77
- if (e === 0) return -1;
78
- let r = t + n;
79
- return r < 0 && (r = e - 1), r >= e && (r = 0), r;
136
+ /**
137
+ * 环绕游标:在 enabled 列表内按 delta 移动;从 -1(无激活)向下取首项、向上取末项。
138
+ * 返回在 enabled 中的下一索引;调用方负责换算回全量 options 索引。
139
+ */
140
+ function nextWrappingIndex(enabledCount, currentIdx, delta) {
141
+ if (enabledCount === 0) return -1;
142
+ let nextIdx = currentIdx + delta;
143
+ if (nextIdx < 0) nextIdx = enabledCount - 1;
144
+ if (nextIdx >= enabledCount) nextIdx = 0;
145
+ return nextIdx;
80
146
  }
81
- //#endregion
82
- export { t as createComboboxOpenController, r as createOptionListenerBinding, n as defineComboboxTrigger, i as handleComboboxFocusOut, a as nextWrappingIndex };
147
+ export { createComboboxOpenController, createOptionListenerBinding, defineComboboxTrigger, handleComboboxFocusOut, nextWrappingIndex };
83
148
 
84
149
  //# sourceMappingURL=combobox-shell.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"combobox-shell.js","names":[],"sources":["../../../src/shared/option-portal/combobox-shell.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport type { WebUiOption } from '@/components/option'\nimport type { OpenOverlayHandle } from '@/shared/overlay/open-overlay'\n\n/**\n * combobox 开合与 option 交互的共享骨架(select / autocomplete)。\n *\n * 与 option-portal 的边界约定一致:交互语义的\"差异点\"经回调注入,\n * 这里收口两组件逐行复制的生命周期不变量——\n * - open/close 状态迁移顺序:guard → 状态翻转 → open-change 派发 →\n * 激活钩子 → scroll-lock 配对 → portal 模式的 rAF 延迟 openOverlay\n * - close 路径:before-close 钩子(portal 内容先收敛)→ 激活清理 →\n * scroll-lock 释放 → closeOverlay(关闭后使 portal 引用失效)\n * - option 四事件监听对的绑定/解绑\n * - focusout 的 rAF :focus-within 复核\n * - 键盘导航的环绕游标算法\n */\n\nexport interface ComboboxOpenHooks {\n /** 是否允许打开(disabled / readonly 等由组件判断)。 */\n canOpen(): boolean\n getIsOpen(): boolean\n setIsOpen(open: boolean): void\n dispatchOpenChange(): void\n syncScrollLock(open: boolean): void\n /** 是否 portal 模式(决定 openOverlay 是否延迟到下一帧)。 */\n isPortal(): boolean\n openOverlay(isKeyboardNavigation: boolean): void\n closeOverlay(): void\n /** 打开时的激活项初始化(键盘导航取选中/首项,指针打开保留现状)。 */\n onOpen?(isKeyboardNavigation: boolean): void\n /** 关闭前钩子:autocomplete 需先把 light DOM 新增节点收敛进当前 portal content。 */\n onBeforeClose?(): void\n /** 关闭时清理激活状态(清 _activeIndex 与 active 属性)。 */\n onAfterClose?(): void\n}\n\nexport interface ComboboxOpenController {\n open(isKeyboardNavigation?: boolean): void\n close(): void\n}\n\nexport function createComboboxOpenController(hooks: ComboboxOpenHooks): ComboboxOpenController {\n function open(isKeyboardNavigation = false) {\n if (hooks.canOpen() === false || hooks.getIsOpen()) return\n hooks.setIsOpen(true)\n hooks.dispatchOpenChange()\n hooks.onOpen?.(isKeyboardNavigation)\n hooks.syncScrollLock(true)\n if (hooks.isPortal()) {\n requestAnimationFrame(() => {\n if (hooks.getIsOpen()) hooks.openOverlay(isKeyboardNavigation)\n })\n } else {\n hooks.openOverlay(isKeyboardNavigation)\n }\n }\n\n function close() {\n if (!hooks.getIsOpen()) return\n hooks.onBeforeClose?.()\n hooks.setIsOpen(false)\n hooks.dispatchOpenChange()\n hooks.onAfterClose?.()\n hooks.syncScrollLock(false)\n hooks.closeOverlay()\n }\n\n return { open, close }\n}\n\nexport interface OptionListenerHandlers {\n onClick: (event: Event) => void\n onPointerOver: (event: PointerEvent) => void\n onPointerDown: (event: PointerEvent) => void\n onUpdate: () => void\n}\n\nexport interface ComboboxTriggerSource {\n /** 持 ARIA 与委托监听的 trigger 包装 div(shadow 内)。 */\n getWrapper(): HTMLElement | null\n /** `slot[name=\"trigger\"]` 的首个 assigned 元素;无自定义 trigger 时为 null。 */\n getCustomTrigger(): HTMLElement | null\n /** 默认 trigger(shadow 内的 web-ui-input);未渲染时为 null。 */\n getFallbackTrigger(): HTMLElement | null\n}\n\nexport interface ComboboxTriggerHandlers {\n /** trigger 文本变化;value 取自 trigger host 的字符串 value 属性。 */\n onInput(value: string): void\n /** 点击 trigger 区域(含包装 div 自身留白)。 */\n onClick(): void\n onFocusIn(event: FocusEvent): void\n onFocusOut(event: FocusEvent): void\n}\n\nexport interface ComboboxTriggerApi {\n /** 当前生效的 trigger host:自定义 trigger slot 首个 assigned 元素,否则默认 trigger。 */\n getTrigger(): HTMLElement | null\n /** trigger 当前文本;trigger 不暴露字符串 value 时返回 null。 */\n getValue(): string | null\n /** 回写文本;仅在文本 trigger 且值确实变化时写入,避免无谓重渲染。 */\n setValue(value: string): void\n /** 多行可编辑元素判定:Enter 保留换行语义,不接管为「选中高亮项」。 */\n isMultilineEdit(event: KeyboardEvent): boolean\n /**\n * 程序化聚焦当前 trigger。组件自带 focus 重定向(web-ui-input/textarea)时落到\n * 内部原生控件;自定义 trigger 没有该能力时,原生 focus() 聚焦 host 自身。\n */\n focusTrigger(options?: FocusOptions): void\n /** 失焦当前 trigger,兜底语义同 focusTrigger。 */\n blurTrigger(): void\n /** 绑定包装 div 上的委托监听(幂等:包装 div 不变则跳过)。 */\n bind(): void\n dispose(): void\n}\n\n/**\n * combobox trigger 委托层(autocomplete)。\n *\n * 默认 trigger 是 shadow 内的 `web-ui-input`,自定义 trigger 由 `slot[name=\"trigger\"]`\n * 提供(`web-ui-textarea` 等)。两者对组件暴露同一形状:字符串 value、可聚焦、\n * 派发 composed 的 input / click / focusin / focusout。委托层把这些差异收敛成一份接口:\n * 监听统一挂在包装 div 上(事件委托,覆盖 shadow 内与 light DOM 两条路径),\n * 文本读写只认 trigger host 的 value 属性。\n *\n * 焦点用 focusin/focusout 而非 focus/blur:后两者不冒泡,到不了包装 div\n * (实测:shadow 内默认 trigger 与 light DOM 自定义 trigger 都不触发包装 div 的 focus/blur)。\n *\n * trigger 自身派发的 change(web-ui-input/textarea 在原生 change 不 composed 时补发)\n * 必须被拦下:组件的 change 只表示「选中提交」,否则失焦即误报一次 change。\n */\nexport const defineComboboxTrigger = () =>\n definePlugin<ComboboxTriggerApi, ComboboxTriggerSource & ComboboxTriggerHandlers>(source => {\n let boundWrapper: HTMLElement | null = null\n\n const getTrigger = (): HTMLElement | null => source.getCustomTrigger() ?? source.getFallbackTrigger() ?? null\n\n const readValue = (trigger: HTMLElement | null): string | null => {\n const value = (trigger as (HTMLElement & { value?: unknown }) | null)?.value\n return typeof value === 'string' ? value : null\n }\n\n // composed 事件在包装 div 上看到的是 trigger host(或其在 light DOM 内的后代);\n // 只有来自 trigger 内部的输入才计入,包装 div 上的其它内容不干扰。\n const isWithinTrigger = (event: Event, trigger: HTMLElement | null): boolean => {\n const target = event.target\n return !!trigger && target instanceof Node && (target === trigger || trigger.contains(target))\n }\n\n const onInput = (event: Event) => {\n const trigger = getTrigger()\n if (!isWithinTrigger(event, trigger)) return\n const value = readValue(trigger)\n if (value !== null) source.onInput(value)\n }\n\n const onNativeChange = (event: Event) => {\n if (isWithinTrigger(event, getTrigger())) event.stopPropagation()\n }\n\n const onClick = () => source.onClick()\n const onFocusIn = (event: FocusEvent) => source.onFocusIn(event)\n const onFocusOut = (event: FocusEvent) => source.onFocusOut(event)\n\n return {\n getTrigger,\n getValue: () => readValue(getTrigger()),\n setValue(value: string) {\n const trigger = getTrigger()\n const current = readValue(trigger)\n if (!trigger || current === null || current === value) return\n ;(trigger as HTMLElement & { value: string }).value = value\n },\n isMultilineEdit(event: KeyboardEvent) {\n // composedPath()[0] 是未 retarget 的真实可编辑元素:textarea 保留 Enter 换行\n return event.composedPath()[0] instanceof HTMLTextAreaElement\n },\n focusTrigger(options?: FocusOptions) {\n // web-ui-input/textarea 的公共 focus() 已重定向到内部原生控件;普通元素或\n // 未实现 focus 的自定义 trigger 走原生 HTMLElement.focus(),即聚焦 host 自身\n getTrigger()?.focus(options)\n },\n blurTrigger() {\n getTrigger()?.blur()\n },\n bind() {\n const wrapper = source.getWrapper()\n if (!wrapper || wrapper === boundWrapper) return\n boundWrapper = wrapper\n wrapper.addEventListener('input', onInput)\n wrapper.addEventListener('change', onNativeChange)\n wrapper.addEventListener('click', onClick)\n wrapper.addEventListener('focusin', onFocusIn)\n wrapper.addEventListener('focusout', onFocusOut)\n },\n dispose() {\n const wrapper = boundWrapper\n boundWrapper = null\n if (!wrapper) return\n wrapper.removeEventListener('input', onInput)\n wrapper.removeEventListener('change', onNativeChange)\n wrapper.removeEventListener('click', onClick)\n wrapper.removeEventListener('focusin', onFocusIn)\n wrapper.removeEventListener('focusout', onFocusOut)\n }\n }\n })\n\n/** option 四事件监听对的绑定/解绑;两组件的 handler 签名一致,仅实现不同。 */\nexport function createOptionListenerBinding(handlers: OptionListenerHandlers) {\n function bind(option: WebUiOption) {\n option.addEventListener('click', handlers.onClick)\n option.addEventListener('pointerover', handlers.onPointerOver)\n option.addEventListener('pointerdown', handlers.onPointerDown)\n option.addEventListener('option-update', handlers.onUpdate)\n }\n function unbind(option: WebUiOption) {\n option.removeEventListener('click', handlers.onClick)\n option.removeEventListener('pointerover', handlers.onPointerOver)\n option.removeEventListener('pointerdown', handlers.onPointerDown)\n option.removeEventListener('option-update', handlers.onUpdate)\n }\n return { bind, unbind }\n}\n\n/**\n * focusout 关闭复核:焦点是否真的离开了宿主与 panel。\n * rAF 等待 click/pointerdown 相关的焦点迁移完成后再判定。\n */\nexport function handleComboboxFocusOut(\n host: HTMLElement,\n getHandle: () => OpenOverlayHandle | null | undefined,\n getIsOpen: () => boolean,\n close: () => void\n): void {\n requestAnimationFrame(() => {\n const handle = getHandle()\n if (getIsOpen() && !host.matches(':focus-within') && !handle?.hasFocusWithin()) {\n close()\n }\n })\n}\n\n/**\n * 环绕游标:在 enabled 列表内按 delta 移动;从 -1(无激活)向下取首项、向上取末项。\n * 返回在 enabled 中的下一索引;调用方负责换算回全量 options 索引。\n */\nexport function nextWrappingIndex(enabledCount: number, currentIdx: number, delta: number): number {\n if (enabledCount === 0) return -1\n let nextIdx = currentIdx + delta\n if (nextIdx < 0) nextIdx = enabledCount - 1\n if (nextIdx >= enabledCount) nextIdx = 0\n return nextIdx\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"combobox-shell.js","names":[],"sources":["../../../src/shared/option-portal/combobox-shell.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport type { WebUiOption } from '@/components/option'\nimport type { OpenOverlayHandle } from '@/shared/overlay/open-overlay'\n\n/**\n * combobox 开合与 option 交互的共享骨架(select / autocomplete)。\n *\n * 与 option-portal 的边界约定一致:交互语义的\"差异点\"经回调注入,\n * 这里收口两组件逐行复制的生命周期不变量——\n * - open/close 状态迁移顺序:guard → 状态翻转 → open-change 派发 →\n * 激活钩子 → scroll-lock 配对 → portal 模式的 rAF 延迟 openOverlay\n * - close 路径:before-close 钩子(portal 内容先收敛)→ 激活清理 →\n * scroll-lock 释放 → closeOverlay(关闭后使 portal 引用失效)\n * - option 四事件监听对的绑定/解绑\n * - focusout 的 rAF :focus-within 复核\n * - 键盘导航的环绕游标算法\n */\n\nexport interface ComboboxOpenHooks {\n /** 是否允许打开(disabled / readonly 等由组件判断)。 */\n canOpen(): boolean\n getIsOpen(): boolean\n setIsOpen(open: boolean): void\n dispatchOpenChange(): void\n syncScrollLock(open: boolean): void\n /** 是否 portal 模式(决定 openOverlay 是否延迟到下一帧)。 */\n isPortal(): boolean\n openOverlay(isKeyboardNavigation: boolean): void\n closeOverlay(): void\n /** 打开时的激活项初始化(键盘导航取选中/首项,指针打开保留现状)。 */\n onOpen?(isKeyboardNavigation: boolean): void\n /** 关闭前钩子:autocomplete 需先把 light DOM 新增节点收敛进当前 portal content。 */\n onBeforeClose?(): void\n /** 关闭时清理激活状态(清 _activeIndex 与 active 属性)。 */\n onAfterClose?(): void\n}\n\nexport interface ComboboxOpenController {\n open(isKeyboardNavigation?: boolean): void\n close(): void\n}\n\nexport function createComboboxOpenController(hooks: ComboboxOpenHooks): ComboboxOpenController {\n function open(isKeyboardNavigation = false) {\n if (hooks.canOpen() === false || hooks.getIsOpen()) return\n hooks.setIsOpen(true)\n hooks.dispatchOpenChange()\n hooks.onOpen?.(isKeyboardNavigation)\n hooks.syncScrollLock(true)\n if (hooks.isPortal()) {\n requestAnimationFrame(() => {\n if (hooks.getIsOpen()) hooks.openOverlay(isKeyboardNavigation)\n })\n } else {\n hooks.openOverlay(isKeyboardNavigation)\n }\n }\n\n function close() {\n if (!hooks.getIsOpen()) return\n hooks.onBeforeClose?.()\n hooks.setIsOpen(false)\n hooks.dispatchOpenChange()\n hooks.onAfterClose?.()\n hooks.syncScrollLock(false)\n hooks.closeOverlay()\n }\n\n return { open, close }\n}\n\nexport interface OptionListenerHandlers {\n onClick: (event: Event) => void\n onPointerOver: (event: PointerEvent) => void\n onPointerDown: (event: PointerEvent) => void\n onUpdate: () => void\n}\n\nexport interface ComboboxTriggerSource {\n /** 持 ARIA 与委托监听的 trigger 包装 div(shadow 内)。 */\n getWrapper(): HTMLElement | null\n /** `slot[name=\"trigger\"]` 的首个 assigned 元素;无自定义 trigger 时为 null。 */\n getCustomTrigger(): HTMLElement | null\n /** 默认 trigger(shadow 内的 web-ui-input);未渲染时为 null。 */\n getFallbackTrigger(): HTMLElement | null\n}\n\nexport interface ComboboxTriggerHandlers {\n /** trigger 文本变化;value 取自 trigger host 的字符串 value 属性。 */\n onInput(value: string): void\n /** 点击 trigger 区域(含包装 div 自身留白)。 */\n onClick(): void\n onFocusIn(event: FocusEvent): void\n onFocusOut(event: FocusEvent): void\n}\n\nexport interface ComboboxTriggerApi {\n /** 当前生效的 trigger host:自定义 trigger slot 首个 assigned 元素,否则默认 trigger。 */\n getTrigger(): HTMLElement | null\n /** trigger 当前文本;trigger 不暴露字符串 value 时返回 null。 */\n getValue(): string | null\n /** 回写文本;仅在文本 trigger 且值确实变化时写入,避免无谓重渲染。 */\n setValue(value: string): void\n /** 多行可编辑元素判定:Enter 保留换行语义,不接管为「选中高亮项」。 */\n isMultilineEdit(event: KeyboardEvent): boolean\n /**\n * 程序化聚焦当前 trigger。组件自带 focus 重定向(web-ui-input/textarea)时落到\n * 内部原生控件;自定义 trigger 没有该能力时,原生 focus() 聚焦 host 自身。\n */\n focusTrigger(options?: FocusOptions): void\n /** 失焦当前 trigger,兜底语义同 focusTrigger。 */\n blurTrigger(): void\n /** 绑定包装 div 上的委托监听(幂等:包装 div 不变则跳过)。 */\n bind(): void\n dispose(): void\n}\n\n/**\n * combobox trigger 委托层(autocomplete)。\n *\n * 默认 trigger 是 shadow 内的 `web-ui-input`,自定义 trigger 由 `slot[name=\"trigger\"]`\n * 提供(`web-ui-textarea` 等)。两者对组件暴露同一形状:字符串 value、可聚焦、\n * 派发 composed 的 input / click / focusin / focusout。委托层把这些差异收敛成一份接口:\n * 监听统一挂在包装 div 上(事件委托,覆盖 shadow 内与 light DOM 两条路径),\n * 文本读写只认 trigger host 的 value 属性。\n *\n * 焦点用 focusin/focusout 而非 focus/blur:后两者不冒泡,到不了包装 div\n * (实测:shadow 内默认 trigger 与 light DOM 自定义 trigger 都不触发包装 div 的 focus/blur)。\n *\n * trigger 自身派发的 change(web-ui-input/textarea 在原生 change 不 composed 时补发)\n * 必须被拦下:组件的 change 只表示「选中提交」,否则失焦即误报一次 change。\n */\nexport const defineComboboxTrigger = () =>\n definePlugin<ComboboxTriggerApi, ComboboxTriggerSource & ComboboxTriggerHandlers>(source => {\n let boundWrapper: HTMLElement | null = null\n\n const getTrigger = (): HTMLElement | null => source.getCustomTrigger() ?? source.getFallbackTrigger() ?? null\n\n const readValue = (trigger: HTMLElement | null): string | null => {\n const value = (trigger as (HTMLElement & { value?: unknown }) | null)?.value\n return typeof value === 'string' ? value : null\n }\n\n // composed 事件在包装 div 上看到的是 trigger host(或其在 light DOM 内的后代);\n // 只有来自 trigger 内部的输入才计入,包装 div 上的其它内容不干扰。\n const isWithinTrigger = (event: Event, trigger: HTMLElement | null): boolean => {\n const target = event.target\n return !!trigger && target instanceof Node && (target === trigger || trigger.contains(target))\n }\n\n const onInput = (event: Event) => {\n const trigger = getTrigger()\n if (!isWithinTrigger(event, trigger)) return\n const value = readValue(trigger)\n if (value !== null) source.onInput(value)\n }\n\n const onNativeChange = (event: Event) => {\n if (isWithinTrigger(event, getTrigger())) event.stopPropagation()\n }\n\n const onClick = () => source.onClick()\n const onFocusIn = (event: FocusEvent) => source.onFocusIn(event)\n const onFocusOut = (event: FocusEvent) => source.onFocusOut(event)\n\n return {\n getTrigger,\n getValue: () => readValue(getTrigger()),\n setValue(value: string) {\n const trigger = getTrigger()\n const current = readValue(trigger)\n if (!trigger || current === null || current === value) return\n ;(trigger as HTMLElement & { value: string }).value = value\n },\n isMultilineEdit(event: KeyboardEvent) {\n // composedPath()[0] 是未 retarget 的真实可编辑元素:textarea 保留 Enter 换行\n return event.composedPath()[0] instanceof HTMLTextAreaElement\n },\n focusTrigger(options?: FocusOptions) {\n // web-ui-input/textarea 的公共 focus() 已重定向到内部原生控件;普通元素或\n // 未实现 focus 的自定义 trigger 走原生 HTMLElement.focus(),即聚焦 host 自身\n getTrigger()?.focus(options)\n },\n blurTrigger() {\n getTrigger()?.blur()\n },\n bind() {\n const wrapper = source.getWrapper()\n if (!wrapper || wrapper === boundWrapper) return\n boundWrapper = wrapper\n wrapper.addEventListener('input', onInput)\n wrapper.addEventListener('change', onNativeChange)\n wrapper.addEventListener('click', onClick)\n wrapper.addEventListener('focusin', onFocusIn)\n wrapper.addEventListener('focusout', onFocusOut)\n },\n dispose() {\n const wrapper = boundWrapper\n boundWrapper = null\n if (!wrapper) return\n wrapper.removeEventListener('input', onInput)\n wrapper.removeEventListener('change', onNativeChange)\n wrapper.removeEventListener('click', onClick)\n wrapper.removeEventListener('focusin', onFocusIn)\n wrapper.removeEventListener('focusout', onFocusOut)\n }\n }\n })\n\n/** option 四事件监听对的绑定/解绑;两组件的 handler 签名一致,仅实现不同。 */\nexport function createOptionListenerBinding(handlers: OptionListenerHandlers) {\n function bind(option: WebUiOption) {\n option.addEventListener('click', handlers.onClick)\n option.addEventListener('pointerover', handlers.onPointerOver)\n option.addEventListener('pointerdown', handlers.onPointerDown)\n option.addEventListener('option-update', handlers.onUpdate)\n }\n function unbind(option: WebUiOption) {\n option.removeEventListener('click', handlers.onClick)\n option.removeEventListener('pointerover', handlers.onPointerOver)\n option.removeEventListener('pointerdown', handlers.onPointerDown)\n option.removeEventListener('option-update', handlers.onUpdate)\n }\n return { bind, unbind }\n}\n\n/**\n * focusout 关闭复核:焦点是否真的离开了宿主与 panel。\n * rAF 等待 click/pointerdown 相关的焦点迁移完成后再判定。\n */\nexport function handleComboboxFocusOut(\n host: HTMLElement,\n getHandle: () => OpenOverlayHandle | null | undefined,\n getIsOpen: () => boolean,\n close: () => void\n): void {\n requestAnimationFrame(() => {\n const handle = getHandle()\n if (getIsOpen() && !host.matches(':focus-within') && !handle?.hasFocusWithin()) {\n close()\n }\n })\n}\n\n/**\n * 环绕游标:在 enabled 列表内按 delta 移动;从 -1(无激活)向下取首项、向上取末项。\n * 返回在 enabled 中的下一索引;调用方负责换算回全量 options 索引。\n */\nexport function nextWrappingIndex(enabledCount: number, currentIdx: number, delta: number): number {\n if (enabledCount === 0) return -1\n let nextIdx = currentIdx + delta\n if (nextIdx < 0) nextIdx = enabledCount - 1\n if (nextIdx >= enabledCount) nextIdx = 0\n return nextIdx\n}\n"],"mappings":"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"}
@@ -1,66 +1,87 @@
1
- import { createComboboxOpenController as e, createOptionListenerBinding as t, defineComboboxTrigger as n, handleComboboxFocusOut as r, nextWrappingIndex as i } from "./combobox-shell.js";
2
- import { definePlugin as a } from "@greypan/js-kit";
3
- //#region src/shared/option-portal/index.ts
4
- var o = "web-ui-option", s = () => a((e) => {
5
- let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new WeakMap(), r = 0, i = (t) => {
6
- e.bindOption(t), t.addEventListener("option-unregister", s);
7
- }, a = (t) => {
8
- e.unbindOption(t), t.removeEventListener("option-unregister", s);
9
- }, s = (e) => {
10
- e.target instanceof HTMLElement && e.target.localName === o && t.add(e.target), l.scheduleRefresh();
11
- }, c = () => {
12
- l.scheduleRefresh();
13
- }, l = {
1
+ import { createComboboxOpenController, createOptionListenerBinding, defineComboboxTrigger, handleComboboxFocusOut, nextWrappingIndex } from "./combobox-shell.js";
2
+ import { definePlugin } from "@greypan/js-kit";
3
+ // src/shared/option-portal/index.ts
4
+ const OPTION_TAG = "web-ui-option";
5
+ const defineOptionPortal = () => definePlugin((host) => {
6
+ const pendingUnregistered = /* @__PURE__ */ new Set();
7
+ const optionIds = /* @__PURE__ */ new WeakMap();
8
+ let nextOptionId = 0;
9
+ const bindOption = (option) => {
10
+ host.bindOption(option);
11
+ option.addEventListener("option-unregister", handleOptionUnregister);
12
+ };
13
+ const unbindOption = (option) => {
14
+ host.unbindOption(option);
15
+ option.removeEventListener("option-unregister", handleOptionUnregister);
16
+ };
17
+ const handleOptionUnregister = (event) => {
18
+ if (event.target instanceof HTMLElement && event.target.localName === OPTION_TAG) pendingUnregistered.add(event.target);
19
+ api.scheduleRefresh();
20
+ };
21
+ const handleRegister = () => {
22
+ api.scheduleRefresh();
23
+ };
24
+ const api = {
14
25
  queryOptions() {
15
- let t = e.getPortal()?.panel ?? e.getPortalContent(), n = t ? [...t.querySelectorAll(o)] : [];
16
- return n.length > 0 ? n : [...e.element.querySelectorAll(o)];
26
+ const panel = host.getPortal()?.panel ?? host.getPortalContent();
27
+ const panelOptions = panel ? [...panel.querySelectorAll(OPTION_TAG)] : [];
28
+ return panelOptions.length > 0 ? panelOptions : [...host.element.querySelectorAll(OPTION_TAG)];
17
29
  },
18
- refresh(e, t) {
19
- let n = l.queryOptions();
20
- for (let t of e) n.includes(t) || a(t);
21
- return n.forEach(i), {
22
- options: n,
23
- activeIndex: t && n.includes(t) ? n.indexOf(t) : -1
30
+ refresh(previous, activeOption) {
31
+ const nextOptions = api.queryOptions();
32
+ for (const option of previous) if (!nextOptions.includes(option)) unbindOption(option);
33
+ nextOptions.forEach(bindOption);
34
+ return {
35
+ options: nextOptions,
36
+ activeIndex: activeOption && nextOptions.includes(activeOption) ? nextOptions.indexOf(activeOption) : -1
24
37
  };
25
38
  },
26
- ensureOptionIds(t) {
27
- let i = new Set(t.map((e) => e.id).filter((e) => !!e));
28
- t.forEach((t) => {
29
- if (t.id) return;
30
- let a = n.get(t);
31
- if (!a || i.has(a)) {
39
+ ensureOptionIds(registryOptions) {
40
+ const usedIds = new Set(registryOptions.map((option) => option.id).filter((id) => Boolean(id)));
41
+ registryOptions.forEach((option) => {
42
+ if (option.id) return;
43
+ let id = optionIds.get(option);
44
+ if (!id || usedIds.has(id)) {
32
45
  do
33
- a = `${e.idPrefix}-option-${++r}`;
34
- while (i.has(a));
35
- n.set(t, a);
46
+ id = `${host.idPrefix}-option-${++nextOptionId}`;
47
+ while (usedIds.has(id));
48
+ optionIds.set(option, id);
36
49
  }
37
- t.id = a, i.add(a);
50
+ option.id = id;
51
+ usedIds.add(id);
38
52
  });
39
53
  },
40
54
  syncPortalContent() {
41
- let n = e.getPortal(), r = e.getPortalContent();
42
- if (!n || !r) return;
43
- for (let i of t) !r.contains(i) && !e.element.contains(i) && n.removeContent([i]);
44
- if (t.clear(), !e.isOpen()) return;
45
- let i = e.getMigratableNodes().filter((e) => !(e instanceof Comment));
46
- i.length && n.appendContent(i, r);
55
+ const portal = host.getPortal();
56
+ const portalContent = host.getPortalContent();
57
+ if (!portal || !portalContent) return;
58
+ for (const option of pendingUnregistered) if (!portalContent.contains(option) && !host.element.contains(option)) portal.removeContent([option]);
59
+ pendingUnregistered.clear();
60
+ if (!host.isOpen()) return;
61
+ const nodes = host.getMigratableNodes().filter((node) => !(node instanceof Comment));
62
+ if (nodes.length) portal.appendContent(nodes, portalContent);
47
63
  },
48
64
  scheduleRefresh() {
49
65
  queueMicrotask(() => {
50
- e.element.isConnected && (l.syncPortalContent(), e.requestUpdate(), e.isOpen() && e.hasUpdated() && e.onImmediateSync?.());
66
+ if (!host.element.isConnected) return;
67
+ api.syncPortalContent();
68
+ host.requestUpdate();
69
+ if (host.isOpen() && host.hasUpdated()) host.onImmediateSync?.();
51
70
  });
52
71
  },
53
- handleOptionUnregister: s,
72
+ handleOptionUnregister,
54
73
  bindHost() {
55
- e.element.addEventListener("option-register", c), e.element.addEventListener("option-unregister", s);
74
+ host.element.addEventListener("option-register", handleRegister);
75
+ host.element.addEventListener("option-unregister", handleOptionUnregister);
56
76
  },
57
77
  dispose() {
58
- e.element.removeEventListener("option-register", c), e.element.removeEventListener("option-unregister", s), t.clear();
78
+ host.element.removeEventListener("option-register", handleRegister);
79
+ host.element.removeEventListener("option-unregister", handleOptionUnregister);
80
+ pendingUnregistered.clear();
59
81
  }
60
82
  };
61
- return l;
83
+ return api;
62
84
  });
63
- //#endregion
64
- export { e as createComboboxOpenController, t as createOptionListenerBinding, n as defineComboboxTrigger, s as defineOptionPortal, r as handleComboboxFocusOut, i as nextWrappingIndex };
85
+ export { createComboboxOpenController, createOptionListenerBinding, defineComboboxTrigger, defineOptionPortal, handleComboboxFocusOut, nextWrappingIndex };
65
86
 
66
87
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/shared/option-portal/index.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport type { WebUiOption } from '@/components/option'\nimport type { OverlayPortal } from '@/shared/overlay/portal'\n\n/**\n * select / autocomplete 共用的 portal option 域:宿主侧 option 注册表、\n * portal 内容同步(打开期迁移 + 真删除清理)与微任务调度。\n *\n * 交互语义与 Lit 响应式由各组件保留(同 anchored-panel 的边界约定):\n * 组件通过 host 回调注入差异点(迁移节点来源、打开期即时同步等),\n * 并持有 _options/_activeIndex 的 @state,shared 只经返回值同步数据。\n */\n\nexport interface OptionPortalHost {\n /** 承载宿主级监听的元素(select / autocomplete 宿主自身)。 */\n readonly element: HTMLElement\n /** option id 前缀;宿主应保证跨实例唯一(如含实例序号),供 aria 引用与样式定位。 */\n readonly idPrefix: string\n getPortal(): OverlayPortal | undefined\n getPortalContent(): HTMLElement | undefined\n /** 打开判定:syncPortalContent 仅在打开期执行内容迁移。 */\n isOpen(): boolean\n /**\n * 打开期待迁移的节点来源。两组件粒度不同(select 迁裸 option,\n * autocomplete 迁全部 childNodes),保持各自现状不在此统一。\n */\n getMigratableNodes(): Node[]\n /** 微任务回调中判断宿主是否已完成首次渲染(Lit hasUpdated)。 */\n hasUpdated(): boolean\n /** 微任务末的宿主刷新(requestUpdate)。 */\n requestUpdate(): void\n /**\n * 打开期即时同步钩子。select 在微任务内立即刷新 label 与激活态\n * (portal 打开时 willUpdate 查不到 panel 外的新增项),autocomplete 无此需要。\n */\n onImmediateSync?(): void\n /**\n * 组件侧的逐元素交互监听(click/pointerover/pointerdown/option-update)。\n * shared 负责随 refresh 配对调用,语义由组件定义。\n */\n bindOption(option: WebUiOption): void\n unbindOption(option: WebUiOption): void\n}\n\nexport interface OptionPortalApi {\n /** panel 优先查询,panel 无 option 或关闭时回退 light DOM。 */\n queryOptions(): WebUiOption[]\n /**\n * diff 出旧集合解绑、新集合绑定;按 option 身份保持激活索引。\n * 返回新注册表数组与新的激活索引(-1 表示激活项已失效,如移除/迁移)。\n */\n refresh(\n previous: readonly WebUiOption[],\n activeOption: WebUiOption | undefined\n ): {\n options: WebUiOption[]\n activeIndex: number\n }\n /** 稳定 id 分配(WeakMap 身份 + 冲突循环),跨 remove/reorder 保持不变。 */\n ensureOptionIds(options: readonly WebUiOption[]): void\n /** pending 真删除清理 + 打开期把滞留 light DOM 的节点迁入 panel。 */\n syncPortalContent(): void\n /** register/unregister/contentChange 的统一微任务收敛入口(slot 监听由组件模板持有)。 */\n scheduleRefresh(): void\n /** 宿主级与逐元素 unregister 监听共用的处理器。 */\n handleOptionUnregister(event: Event): void\n /** 宿主级监听配对(connectedCallback 调用,与 dispose 配对)。 */\n bindHost(): void\n /** 断连清理:解绑宿主监听并清空 pending 集合。 */\n dispose(): void\n}\n\nconst OPTION_TAG = 'web-ui-option'\n\nexport const defineOptionPortal = () =>\n definePlugin<OptionPortalApi, OptionPortalHost>(host => {\n const pendingUnregistered = new Set<WebUiOption>()\n // 稳定 id:WeakMap 按 option 身份记忆分配结果,remove/reorder 后 id 不变;\n // aria-activedescendant / 外部样式都依赖 id 的时序稳定性。\n const optionIds = new WeakMap<WebUiOption, string>()\n let nextOptionId = 0\n\n const bindOption = (option: WebUiOption) => {\n host.bindOption(option)\n option.addEventListener('option-unregister', handleOptionUnregister)\n }\n\n const unbindOption = (option: WebUiOption) => {\n host.unbindOption(option)\n option.removeEventListener('option-unregister', handleOptionUnregister)\n }\n\n const handleOptionUnregister = (event: Event) => {\n // Portal 迁移与真实删除都会触发 unregister;先记录候选,\n // 微任务末 syncPortalContent 按最终位置区分二者。\n if (event.target instanceof HTMLElement && event.target.localName === OPTION_TAG) {\n pendingUnregistered.add(event.target as WebUiOption)\n }\n api.scheduleRefresh()\n }\n\n const handleRegister = () => {\n api.scheduleRefresh()\n }\n\n const api: OptionPortalApi = {\n queryOptions() {\n const panel = host.getPortal()?.panel ?? host.getPortalContent()\n const panelOptions = panel ? [...panel.querySelectorAll<WebUiOption>(OPTION_TAG)] : []\n // panel 内容仅在 overlay 打开、moveContent 之后存在;关闭时回退 light DOM,\n // 否则 portal 组件首次加载时注册表为空。\n return panelOptions.length > 0 ? panelOptions : [...host.element.querySelectorAll<WebUiOption>(OPTION_TAG)]\n },\n\n refresh(previous, activeOption) {\n const nextOptions = api.queryOptions()\n\n // register/unregister 是 composed 事件:Portal 迁移时 target 会 retarget 成宿主,\n // 不能作为监听器绑定依据;绑定只发生在按 DOM 查询确认身份的 option 上。\n for (const option of previous) if (!nextOptions.includes(option)) unbindOption(option)\n nextOptions.forEach(bindOption)\n\n // 激活索引按 option 身份保持,避免移除中间项后静默偏移到相邻项\n return {\n options: nextOptions,\n activeIndex: activeOption && nextOptions.includes(activeOption) ? nextOptions.indexOf(activeOption) : -1\n }\n },\n\n ensureOptionIds(registryOptions) {\n const usedIds = new Set(registryOptions.map(option => option.id).filter((id): id is string => Boolean(id)))\n registryOptions.forEach(option => {\n if (option.id) return\n\n let id = optionIds.get(option)\n if (!id || usedIds.has(id)) {\n do {\n id = `${host.idPrefix}-option-${++nextOptionId}`\n } while (usedIds.has(id))\n optionIds.set(option, id)\n }\n option.id = id\n usedIds.add(id)\n })\n },\n\n syncPortalContent() {\n const portal = host.getPortal()\n const portalContent = host.getPortalContent()\n if (!portal || !portalContent) return\n\n // 真删除(既不在 panel 也不在 light DOM)的 option 从 portal 追踪列表摘除,\n // 否则关闭时 restoreContent 会把它复活回 light DOM。\n for (const option of pendingUnregistered) {\n if (!portalContent.contains(option) && !host.element.contains(option)) portal.removeContent([option])\n }\n pendingUnregistered.clear()\n\n if (!host.isOpen()) return\n\n // Portal 打开期间框架条件渲染(v-if)可能在 light DOM 插入新节点;\n // panel 内已有内容时 queryOptions 不会回退 light DOM,必须显式迁入 panel。\n // 注释(框架锚点与 portal 的 marker)不迁移:锚点留守宿主是实时渲染契约。\n const nodes = host.getMigratableNodes().filter(node => !(node instanceof Comment))\n if (nodes.length) portal.appendContent(nodes, portalContent)\n },\n\n scheduleRefresh() {\n queueMicrotask(() => {\n if (!host.element.isConnected) return\n api.syncPortalContent()\n host.requestUpdate()\n // 关闭状态下 willUpdate 查不到 portal panel 内容;打开期的新增/删除\n // 由宿主在微任务内立即同步 label 与激活态。\n if (host.isOpen() && host.hasUpdated()) host.onImmediateSync?.()\n })\n },\n\n handleOptionUnregister,\n\n bindHost() {\n host.element.addEventListener('option-register', handleRegister)\n host.element.addEventListener('option-unregister', handleOptionUnregister)\n },\n\n dispose() {\n host.element.removeEventListener('option-register', handleRegister)\n host.element.removeEventListener('option-unregister', handleOptionUnregister)\n pendingUnregistered.clear()\n }\n }\n\n return api\n })\nexport * from './combobox-shell'\n"],"mappings":";;;AAyEA,IAAM,IAAa,iBAEN,UACX,GAAgD,MAAQ;CACtD,IAAM,oBAAsB,IAAI,IAAiB,GAG3C,oBAAY,IAAI,QAA6B,GAC/C,IAAe,GAEb,KAAc,MAAwB;EAE1C,AADA,EAAK,WAAW,CAAM,GACtB,EAAO,iBAAiB,qBAAqB,CAAsB;CACrE,GAEM,KAAgB,MAAwB;EAE5C,AADA,EAAK,aAAa,CAAM,GACxB,EAAO,oBAAoB,qBAAqB,CAAsB;CACxE,GAEM,KAA0B,MAAiB;EAM/C,AAHI,EAAM,kBAAkB,eAAe,EAAM,OAAO,cAAc,KACpE,EAAoB,IAAI,EAAM,MAAqB,GAErD,EAAI,gBAAgB;CACtB,GAEM,UAAuB;EAC3B,EAAI,gBAAgB;CACtB,GAEM,IAAuB;EAC3B,eAAe;GACb,IAAM,IAAQ,EAAK,UAAU,CAAC,EAAE,SAAS,EAAK,iBAAiB,GACzD,IAAe,IAAQ,CAAC,GAAG,EAAM,iBAA8B,CAAU,CAAC,IAAI,CAAC;GAGrF,OAAO,EAAa,SAAS,IAAI,IAAe,CAAC,GAAG,EAAK,QAAQ,iBAA8B,CAAU,CAAC;EAC5G;EAEA,QAAQ,GAAU,GAAc;GAC9B,IAAM,IAAc,EAAI,aAAa;GAIrC,KAAK,IAAM,KAAU,GAAU,AAAK,EAAY,SAAS,CAAM,KAAG,EAAa,CAAM;GAIrF,OAHA,EAAY,QAAQ,CAAU,GAGvB;IACL,SAAS;IACT,aAAa,KAAgB,EAAY,SAAS,CAAY,IAAI,EAAY,QAAQ,CAAY,IAAI;GACxG;EACF;EAEA,gBAAgB,GAAiB;GAC/B,IAAM,IAAU,IAAI,IAAI,EAAgB,KAAI,MAAU,EAAO,EAAE,CAAC,CAAC,QAAQ,MAAqB,EAAQ,CAAG,CAAC;GAC1G,EAAgB,SAAQ,MAAU;IAChC,IAAI,EAAO,IAAI;IAEf,IAAI,IAAK,EAAU,IAAI,CAAM;IAC7B,IAAI,CAAC,KAAM,EAAQ,IAAI,CAAE,GAAG;KAC1B;MACE,IAAK,GAAG,EAAK,SAAS,UAAU,EAAE;YAC3B,EAAQ,IAAI,CAAE;KACvB,EAAU,IAAI,GAAQ,CAAE;IAC1B;IAEA,AADA,EAAO,KAAK,GACZ,EAAQ,IAAI,CAAE;GAChB,CAAC;EACH;EAEA,oBAAoB;GAClB,IAAM,IAAS,EAAK,UAAU,GACxB,IAAgB,EAAK,iBAAiB;GAC5C,IAAI,CAAC,KAAU,CAAC,GAAe;GAI/B,KAAK,IAAM,KAAU,GACnB,AAAI,CAAC,EAAc,SAAS,CAAM,KAAK,CAAC,EAAK,QAAQ,SAAS,CAAM,KAAG,EAAO,cAAc,CAAC,CAAM,CAAC;GAItG,IAFA,EAAoB,MAAM,GAEtB,CAAC,EAAK,OAAO,GAAG;GAKpB,IAAM,IAAQ,EAAK,mBAAmB,CAAC,CAAC,QAAO,MAAQ,EAAE,aAAgB,QAAQ;GACjF,AAAI,EAAM,UAAQ,EAAO,cAAc,GAAO,CAAa;EAC7D;EAEA,kBAAkB;GAChB,qBAAqB;IACd,EAAK,QAAQ,gBAClB,EAAI,kBAAkB,GACtB,EAAK,cAAc,GAGf,EAAK,OAAO,KAAK,EAAK,WAAW,KAAG,EAAK,kBAAkB;GACjE,CAAC;EACH;EAEA;EAEA,WAAW;GAET,AADA,EAAK,QAAQ,iBAAiB,mBAAmB,CAAc,GAC/D,EAAK,QAAQ,iBAAiB,qBAAqB,CAAsB;EAC3E;EAEA,UAAU;GAGR,AAFA,EAAK,QAAQ,oBAAoB,mBAAmB,CAAc,GAClE,EAAK,QAAQ,oBAAoB,qBAAqB,CAAsB,GAC5E,EAAoB,MAAM;EAC5B;CACF;CAEA,OAAO;AACT,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/shared/option-portal/index.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport type { WebUiOption } from '@/components/option'\nimport type { OverlayPortal } from '@/shared/overlay/portal'\n\n/**\n * select / autocomplete 共用的 portal option 域:宿主侧 option 注册表、\n * portal 内容同步(打开期迁移 + 真删除清理)与微任务调度。\n *\n * 交互语义与 Lit 响应式由各组件保留(同 anchored-panel 的边界约定):\n * 组件通过 host 回调注入差异点(迁移节点来源、打开期即时同步等),\n * 并持有 _options/_activeIndex 的 @state,shared 只经返回值同步数据。\n */\n\nexport interface OptionPortalHost {\n /** 承载宿主级监听的元素(select / autocomplete 宿主自身)。 */\n readonly element: HTMLElement\n /** option id 前缀;宿主应保证跨实例唯一(如含实例序号),供 aria 引用与样式定位。 */\n readonly idPrefix: string\n getPortal(): OverlayPortal | undefined\n getPortalContent(): HTMLElement | undefined\n /** 打开判定:syncPortalContent 仅在打开期执行内容迁移。 */\n isOpen(): boolean\n /**\n * 打开期待迁移的节点来源。两组件粒度不同(select 迁裸 option,\n * autocomplete 迁全部 childNodes),保持各自现状不在此统一。\n */\n getMigratableNodes(): Node[]\n /** 微任务回调中判断宿主是否已完成首次渲染(Lit hasUpdated)。 */\n hasUpdated(): boolean\n /** 微任务末的宿主刷新(requestUpdate)。 */\n requestUpdate(): void\n /**\n * 打开期即时同步钩子。select 在微任务内立即刷新 label 与激活态\n * (portal 打开时 willUpdate 查不到 panel 外的新增项),autocomplete 无此需要。\n */\n onImmediateSync?(): void\n /**\n * 组件侧的逐元素交互监听(click/pointerover/pointerdown/option-update)。\n * shared 负责随 refresh 配对调用,语义由组件定义。\n */\n bindOption(option: WebUiOption): void\n unbindOption(option: WebUiOption): void\n}\n\nexport interface OptionPortalApi {\n /** panel 优先查询,panel 无 option 或关闭时回退 light DOM。 */\n queryOptions(): WebUiOption[]\n /**\n * diff 出旧集合解绑、新集合绑定;按 option 身份保持激活索引。\n * 返回新注册表数组与新的激活索引(-1 表示激活项已失效,如移除/迁移)。\n */\n refresh(\n previous: readonly WebUiOption[],\n activeOption: WebUiOption | undefined\n ): {\n options: WebUiOption[]\n activeIndex: number\n }\n /** 稳定 id 分配(WeakMap 身份 + 冲突循环),跨 remove/reorder 保持不变。 */\n ensureOptionIds(options: readonly WebUiOption[]): void\n /** pending 真删除清理 + 打开期把滞留 light DOM 的节点迁入 panel。 */\n syncPortalContent(): void\n /** register/unregister/contentChange 的统一微任务收敛入口(slot 监听由组件模板持有)。 */\n scheduleRefresh(): void\n /** 宿主级与逐元素 unregister 监听共用的处理器。 */\n handleOptionUnregister(event: Event): void\n /** 宿主级监听配对(connectedCallback 调用,与 dispose 配对)。 */\n bindHost(): void\n /** 断连清理:解绑宿主监听并清空 pending 集合。 */\n dispose(): void\n}\n\nconst OPTION_TAG = 'web-ui-option'\n\nexport const defineOptionPortal = () =>\n definePlugin<OptionPortalApi, OptionPortalHost>(host => {\n const pendingUnregistered = new Set<WebUiOption>()\n // 稳定 id:WeakMap 按 option 身份记忆分配结果,remove/reorder 后 id 不变;\n // aria-activedescendant / 外部样式都依赖 id 的时序稳定性。\n const optionIds = new WeakMap<WebUiOption, string>()\n let nextOptionId = 0\n\n const bindOption = (option: WebUiOption) => {\n host.bindOption(option)\n option.addEventListener('option-unregister', handleOptionUnregister)\n }\n\n const unbindOption = (option: WebUiOption) => {\n host.unbindOption(option)\n option.removeEventListener('option-unregister', handleOptionUnregister)\n }\n\n const handleOptionUnregister = (event: Event) => {\n // Portal 迁移与真实删除都会触发 unregister;先记录候选,\n // 微任务末 syncPortalContent 按最终位置区分二者。\n if (event.target instanceof HTMLElement && event.target.localName === OPTION_TAG) {\n pendingUnregistered.add(event.target as WebUiOption)\n }\n api.scheduleRefresh()\n }\n\n const handleRegister = () => {\n api.scheduleRefresh()\n }\n\n const api: OptionPortalApi = {\n queryOptions() {\n const panel = host.getPortal()?.panel ?? host.getPortalContent()\n const panelOptions = panel ? [...panel.querySelectorAll<WebUiOption>(OPTION_TAG)] : []\n // panel 内容仅在 overlay 打开、moveContent 之后存在;关闭时回退 light DOM,\n // 否则 portal 组件首次加载时注册表为空。\n return panelOptions.length > 0 ? panelOptions : [...host.element.querySelectorAll<WebUiOption>(OPTION_TAG)]\n },\n\n refresh(previous, activeOption) {\n const nextOptions = api.queryOptions()\n\n // register/unregister 是 composed 事件:Portal 迁移时 target 会 retarget 成宿主,\n // 不能作为监听器绑定依据;绑定只发生在按 DOM 查询确认身份的 option 上。\n for (const option of previous) if (!nextOptions.includes(option)) unbindOption(option)\n nextOptions.forEach(bindOption)\n\n // 激活索引按 option 身份保持,避免移除中间项后静默偏移到相邻项\n return {\n options: nextOptions,\n activeIndex: activeOption && nextOptions.includes(activeOption) ? nextOptions.indexOf(activeOption) : -1\n }\n },\n\n ensureOptionIds(registryOptions) {\n const usedIds = new Set(registryOptions.map(option => option.id).filter((id): id is string => Boolean(id)))\n registryOptions.forEach(option => {\n if (option.id) return\n\n let id = optionIds.get(option)\n if (!id || usedIds.has(id)) {\n do {\n id = `${host.idPrefix}-option-${++nextOptionId}`\n } while (usedIds.has(id))\n optionIds.set(option, id)\n }\n option.id = id\n usedIds.add(id)\n })\n },\n\n syncPortalContent() {\n const portal = host.getPortal()\n const portalContent = host.getPortalContent()\n if (!portal || !portalContent) return\n\n // 真删除(既不在 panel 也不在 light DOM)的 option 从 portal 追踪列表摘除,\n // 否则关闭时 restoreContent 会把它复活回 light DOM。\n for (const option of pendingUnregistered) {\n if (!portalContent.contains(option) && !host.element.contains(option)) portal.removeContent([option])\n }\n pendingUnregistered.clear()\n\n if (!host.isOpen()) return\n\n // Portal 打开期间框架条件渲染(v-if)可能在 light DOM 插入新节点;\n // panel 内已有内容时 queryOptions 不会回退 light DOM,必须显式迁入 panel。\n // 注释(框架锚点与 portal 的 marker)不迁移:锚点留守宿主是实时渲染契约。\n const nodes = host.getMigratableNodes().filter(node => !(node instanceof Comment))\n if (nodes.length) portal.appendContent(nodes, portalContent)\n },\n\n scheduleRefresh() {\n queueMicrotask(() => {\n if (!host.element.isConnected) return\n api.syncPortalContent()\n host.requestUpdate()\n // 关闭状态下 willUpdate 查不到 portal panel 内容;打开期的新增/删除\n // 由宿主在微任务内立即同步 label 与激活态。\n if (host.isOpen() && host.hasUpdated()) host.onImmediateSync?.()\n })\n },\n\n handleOptionUnregister,\n\n bindHost() {\n host.element.addEventListener('option-register', handleRegister)\n host.element.addEventListener('option-unregister', handleOptionUnregister)\n },\n\n dispose() {\n host.element.removeEventListener('option-register', handleRegister)\n host.element.removeEventListener('option-unregister', handleOptionUnregister)\n pendingUnregistered.clear()\n }\n }\n\n return api\n })\nexport * from './combobox-shell'\n"],"mappings":"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"}
@@ -1,57 +1,92 @@
1
- import { defineOverlay as e } from "./overlay.js";
2
- import { hideOverlayPresence as t, showOverlayPresence as n } from "./presence.js";
3
- import { definePlugin as r } from "@greypan/js-kit";
4
- //#region src/shared/overlay/anchored-panel.ts
5
- var i = () => r((r) => {
6
- let i, a, o = null, s = () => a?.panel ?? r.getLocalPanel(), c = () => {
7
- o?.release(), o = null;
8
- }, l = () => {
9
- a && (a.restoreContent(), a.remove(), a = void 0, i = void 0);
10
- }, u = () => r.isPortal() ? (a ??= r.createPortal(), a.panel) : r.getLocalPanel(), d = (t, n) => {
11
- if (i) {
12
- i.updateAnchor(t), i.update(r.getPositioning());
1
+ import { defineOverlay } from "./overlay.js";
2
+ import { hideOverlayPresence, showOverlayPresence } from "./presence.js";
3
+ import { definePlugin } from "@greypan/js-kit";
4
+ // src/shared/overlay/anchored-panel.ts
5
+ const defineAnchoredPanel = () => definePlugin((ctx) => {
6
+ let overlay;
7
+ let portal;
8
+ let handle = null;
9
+ const getPanel = () => portal?.panel ?? ctx.getLocalPanel();
10
+ const releaseHandle = () => {
11
+ handle?.release();
12
+ handle = null;
13
+ };
14
+ const disposePortal = () => {
15
+ if (!portal) return;
16
+ portal.restoreContent();
17
+ portal.remove();
18
+ portal = void 0;
19
+ overlay = void 0;
20
+ };
21
+ const getOrCreatePanel = () => {
22
+ if (!ctx.isPortal()) return ctx.getLocalPanel();
23
+ portal ??= ctx.createPortal();
24
+ return portal.panel;
25
+ };
26
+ const ensureOverlay = (anchor, panel) => {
27
+ if (overlay) {
28
+ overlay.updateAnchor(anchor);
29
+ overlay.update(ctx.getPositioning());
13
30
  return;
14
31
  }
15
- i = e().make({
16
- anchor: t,
17
- overlay: n,
18
- ...r.getPositioning()
32
+ overlay = defineOverlay().make({
33
+ anchor,
34
+ overlay: panel,
35
+ ...ctx.getPositioning()
19
36
  });
20
- }, f = (e = !1) => {
21
- let t = r.getAnchor();
22
- if (!t) return;
23
- let a = u();
24
- a && (c(), o = r.openOverlay.claim(a, {
25
- arbitration: r.arbitration,
26
- ancestryFrom: t
27
- }), d(t, a), i?.open(), n(a, { isInstant: e }));
28
- }, p = () => {
29
- i?.dispose(), i = void 0, c(), l();
37
+ };
38
+ const open = (isInstant = false) => {
39
+ const anchor = ctx.getAnchor();
40
+ if (!anchor) return;
41
+ const panel = getOrCreatePanel();
42
+ if (!panel) return;
43
+ releaseHandle();
44
+ handle = ctx.openOverlay.claim(panel, {
45
+ arbitration: ctx.arbitration,
46
+ ancestryFrom: anchor
47
+ });
48
+ ensureOverlay(anchor, panel);
49
+ overlay?.open();
50
+ showOverlayPresence(panel, { isInstant });
51
+ };
52
+ const dispose = () => {
53
+ overlay?.dispose();
54
+ overlay = void 0;
55
+ releaseHandle();
56
+ disposePortal();
30
57
  };
31
58
  return {
32
59
  getPanel() {
33
- return s();
60
+ return getPanel();
34
61
  },
35
62
  getHandle() {
36
- return o;
63
+ return handle;
37
64
  },
38
- open: f,
39
- async close(e) {
40
- o?.deferArbitration(), i?.close();
41
- let n = s();
42
- return n && !await t(n) ? !1 : e() ? (o?.deferArbitration(!1), !1) : (c(), l(), !0);
65
+ open,
66
+ async close(isStillOpen) {
67
+ handle?.deferArbitration();
68
+ overlay?.close();
69
+ const panel = getPanel();
70
+ if (panel && !await hideOverlayPresence(panel)) return false;
71
+ if (isStillOpen()) {
72
+ handle?.deferArbitration(false);
73
+ return false;
74
+ }
75
+ releaseHandle();
76
+ disposePortal();
77
+ return true;
43
78
  },
44
79
  updatePosition() {
45
- i?.update(r.getPositioning());
80
+ overlay?.update(ctx.getPositioning());
46
81
  },
47
- reconfigure(e) {
48
- let t = s()?.dataset.wuiPresence === "entering";
49
- p(), e && f(!t);
82
+ reconfigure(isOpen) {
83
+ const shouldAnimate = getPanel()?.dataset.wuiPresence === "entering";
84
+ dispose();
85
+ if (isOpen) open(!shouldAnimate);
50
86
  },
51
- dispose: p
87
+ dispose
52
88
  };
53
89
  });
54
- //#endregion
55
- export { i as defineAnchoredPanel };
90
+ export { defineAnchoredPanel };
56
91
 
57
92
  //# sourceMappingURL=anchored-panel.js.map