@qw-ui/core 0.3.0-next.40 → 0.3.0-next.42

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 (402) hide show
  1. package/README.md +21 -37
  2. package/dist/action-sheet/action-sheet.d.ts +110 -0
  3. package/dist/action-sheet/index.d.ts +2 -0
  4. package/dist/action-sheet/index.js +2 -0
  5. package/dist/action-sheet-Cvcr1S_m.js +183 -0
  6. package/dist/action-sheet-Cvcr1S_m.js.map +1 -0
  7. package/dist/area-picker/area-picker.d.ts +113 -0
  8. package/dist/area-picker/index.d.ts +1 -0
  9. package/dist/area-picker/index.js +348 -0
  10. package/dist/area-picker/index.js.map +1 -0
  11. package/dist/aria-description-CimD2M_C.js +13 -0
  12. package/dist/aria-description-CimD2M_C.js.map +1 -0
  13. package/dist/aria-description.d.ts +2 -0
  14. package/dist/avatar/avatar-load.d.ts +76 -0
  15. package/dist/avatar/avatar.d.ts +22 -5
  16. package/dist/avatar/index.d.ts +1 -0
  17. package/dist/avatar/index.js +57 -18
  18. package/dist/avatar/index.js.map +1 -1
  19. package/dist/avatar-load-w9dq05oV.js +139 -0
  20. package/dist/avatar-load-w9dq05oV.js.map +1 -0
  21. package/dist/back-top/back-top.d.ts +77 -0
  22. package/dist/back-top/index.d.ts +1 -0
  23. package/dist/back-top/index.js +189 -0
  24. package/dist/back-top/index.js.map +1 -0
  25. package/dist/badge/badge.d.ts +9 -0
  26. package/dist/badge/index.js +14 -1
  27. package/dist/badge/index.js.map +1 -1
  28. package/dist/button/button.d.ts +13 -0
  29. package/dist/button/index.js +3 -5
  30. package/dist/button/index.js.map +1 -1
  31. package/dist/calendar/calendar.d.ts +100 -0
  32. package/dist/calendar/index.d.ts +1 -0
  33. package/dist/calendar/index.js +2 -0
  34. package/dist/calendar-CmpK3stz.js +363 -0
  35. package/dist/calendar-CmpK3stz.js.map +1 -0
  36. package/dist/card/card.d.ts +68 -0
  37. package/dist/card/index.d.ts +2 -0
  38. package/dist/card/index.js +2 -0
  39. package/dist/card-DRtWa6Cr.js +107 -0
  40. package/dist/card-DRtWa6Cr.js.map +1 -0
  41. package/dist/cascader/cascader.d.ts +115 -0
  42. package/dist/cascader/index.d.ts +1 -0
  43. package/dist/cascader/index.js +2 -0
  44. package/dist/cascader-D-xMjs7P.js +333 -0
  45. package/dist/cascader-D-xMjs7P.js.map +1 -0
  46. package/dist/cell/cell.d.ts +41 -0
  47. package/dist/cell/index.d.ts +1 -0
  48. package/dist/cell/index.js +43 -0
  49. package/dist/cell/index.js.map +1 -0
  50. package/dist/check-list/check-list.d.ts +78 -0
  51. package/dist/check-list/index.d.ts +2 -0
  52. package/dist/check-list/index.js +2 -0
  53. package/dist/check-list-BvZHQt5w.js +60 -0
  54. package/dist/check-list-BvZHQt5w.js.map +1 -0
  55. package/dist/checkbox/checkbox.d.ts +59 -0
  56. package/dist/checkbox/index.d.ts +2 -0
  57. package/dist/checkbox/index.js +2 -0
  58. package/dist/checkbox-BlndJrz5.js +127 -0
  59. package/dist/checkbox-BlndJrz5.js.map +1 -0
  60. package/dist/checkbox-group/checkbox-group.d.ts +86 -0
  61. package/dist/checkbox-group/index.d.ts +3 -0
  62. package/dist/checkbox-group/index.js +2 -0
  63. package/dist/checkbox-group-gGfsTv-e.js +223 -0
  64. package/dist/checkbox-group-gGfsTv-e.js.map +1 -0
  65. package/dist/choice-group-C4c9m0qe.js +373 -0
  66. package/dist/choice-group-C4c9m0qe.js.map +1 -0
  67. package/dist/circle/circle.d.ts +97 -0
  68. package/dist/circle/index.d.ts +1 -0
  69. package/dist/circle/index.js +119 -0
  70. package/dist/circle/index.js.map +1 -0
  71. package/dist/collapse/collapse.d.ts +98 -0
  72. package/dist/collapse/index.d.ts +2 -0
  73. package/dist/collapse/index.js +2 -0
  74. package/dist/collapse-B969h7-H.js +226 -0
  75. package/dist/collapse-B969h7-H.js.map +1 -0
  76. package/dist/countdown/countdown.d.ts +114 -0
  77. package/dist/countdown/index.d.ts +1 -0
  78. package/dist/countdown/index.js +309 -0
  79. package/dist/countdown/index.js.map +1 -0
  80. package/dist/date-picker/date-picker.d.ts +168 -0
  81. package/dist/date-picker/index.d.ts +1 -0
  82. package/dist/date-picker/index.js +401 -0
  83. package/dist/date-picker/index.js.map +1 -0
  84. package/dist/descriptions/descriptions.d.ts +69 -0
  85. package/dist/descriptions/index.d.ts +1 -0
  86. package/dist/descriptions/index.js +86 -0
  87. package/dist/descriptions/index.js.map +1 -0
  88. package/dist/dialog/dialog.d.ts +32 -3
  89. package/dist/dialog/index.js +58 -3
  90. package/dist/dialog/index.js.map +1 -1
  91. package/dist/divider/divider.d.ts +18 -2
  92. package/dist/divider/index.js +20 -2
  93. package/dist/divider/index.js.map +1 -1
  94. package/dist/dropdown/dropdown.d.ts +172 -0
  95. package/dist/dropdown/index.d.ts +2 -0
  96. package/dist/dropdown/index.js +467 -0
  97. package/dist/dropdown/index.js.map +1 -0
  98. package/dist/ellipsis/ellipsis-layout.d.ts +34 -0
  99. package/dist/ellipsis/ellipsis.d.ts +88 -0
  100. package/dist/ellipsis/index.d.ts +2 -0
  101. package/dist/ellipsis/index.js +320 -0
  102. package/dist/ellipsis/index.js.map +1 -0
  103. package/dist/empty/empty-illustration.d.ts +3 -0
  104. package/dist/empty/empty.d.ts +43 -1
  105. package/dist/empty/index.js +2 -21
  106. package/dist/empty-CAgyvhUI.js +166 -0
  107. package/dist/empty-CAgyvhUI.js.map +1 -0
  108. package/dist/field/field.d.ts +95 -0
  109. package/dist/field/index.d.ts +2 -0
  110. package/dist/field/index.js +2 -0
  111. package/dist/field-DMHGIMZF.js +241 -0
  112. package/dist/field-DMHGIMZF.js.map +1 -0
  113. package/dist/floating-bubble/floating-bubble.d.ts +116 -0
  114. package/dist/floating-bubble/index.d.ts +1 -0
  115. package/dist/floating-bubble/index.js +333 -0
  116. package/dist/floating-bubble/index.js.map +1 -0
  117. package/dist/floating-panel/floating-panel.d.ts +80 -0
  118. package/dist/floating-panel/index.d.ts +2 -0
  119. package/dist/floating-panel/index.js +2 -0
  120. package/dist/floating-panel-Cbm5njBJ.js +363 -0
  121. package/dist/floating-panel-Cbm5njBJ.js.map +1 -0
  122. package/dist/footer/footer.d.ts +94 -0
  123. package/dist/footer/index.d.ts +1 -0
  124. package/dist/footer/index.js +154 -0
  125. package/dist/footer/index.js.map +1 -0
  126. package/dist/form/connect.d.ts +6 -0
  127. package/dist/form/form.d.ts +100 -0
  128. package/dist/form/ids.d.ts +14 -0
  129. package/dist/form/index.d.ts +13 -0
  130. package/dist/form/index.js +3 -0
  131. package/dist/form/methods.d.ts +5 -0
  132. package/dist/form/model.d.ts +24 -0
  133. package/dist/form/native.d.ts +25 -0
  134. package/dist/form/rules.d.ts +40 -0
  135. package/dist/form/ssr.d.ts +7 -0
  136. package/dist/form/types.d.ts +150 -0
  137. package/dist/form-BAGkIEMY.js +1354 -0
  138. package/dist/form-BAGkIEMY.js.map +1 -0
  139. package/dist/format-BDUY0C_c.js +89 -0
  140. package/dist/format-BDUY0C_c.js.map +1 -0
  141. package/dist/gesture-_SRHIvBm.js +30 -0
  142. package/dist/gesture-_SRHIvBm.js.map +1 -0
  143. package/dist/grid/grid-item.d.ts +22 -0
  144. package/dist/grid/grid.d.ts +42 -0
  145. package/dist/grid/index.d.ts +2 -0
  146. package/dist/grid/index.js +73 -0
  147. package/dist/grid/index.js.map +1 -0
  148. package/dist/icon/icon.d.ts +37 -1
  149. package/dist/icon/identity.d.ts +3 -0
  150. package/dist/icon/index.js +2 -20
  151. package/dist/icon-Cgdbnk1u.js +77 -0
  152. package/dist/icon-Cgdbnk1u.js.map +1 -0
  153. package/dist/image/image-load.d.ts +24 -0
  154. package/dist/image/image.d.ts +45 -8
  155. package/dist/image/index.d.ts +1 -0
  156. package/dist/image/index.js +116 -14
  157. package/dist/image/index.js.map +1 -1
  158. package/dist/image-preview/image-preview.d.ts +124 -0
  159. package/dist/image-preview/index.d.ts +1 -0
  160. package/dist/image-preview/index.js +450 -0
  161. package/dist/image-preview/index.js.map +1 -0
  162. package/dist/index-bar/index-bar.d.ts +121 -0
  163. package/dist/index-bar/index.d.ts +1 -0
  164. package/dist/index-bar/index.js +386 -0
  165. package/dist/index-bar/index.js.map +1 -0
  166. package/dist/index.d.ts +107 -14
  167. package/dist/index.js +148 -14
  168. package/dist/index.js.map +1 -0
  169. package/dist/infinite-scroll/index.d.ts +1 -0
  170. package/dist/infinite-scroll/index.js +248 -0
  171. package/dist/infinite-scroll/index.js.map +1 -0
  172. package/dist/infinite-scroll/infinite-scroll.d.ts +95 -0
  173. package/dist/input/index.js +181 -22
  174. package/dist/input/index.js.map +1 -1
  175. package/dist/input/input.d.ts +44 -1
  176. package/dist/layer-IpFrl5--.js +414 -0
  177. package/dist/layer-IpFrl5--.js.map +1 -0
  178. package/dist/layout-BRSqi4AQ.js +43 -0
  179. package/dist/layout-BRSqi4AQ.js.map +1 -0
  180. package/dist/layout.d.ts +13 -0
  181. package/dist/list/index.d.ts +2 -0
  182. package/dist/list/index.js +2 -0
  183. package/dist/list/list.d.ts +30 -0
  184. package/dist/list-6-iz-Irh.js +28 -0
  185. package/dist/list-6-iz-Irh.js.map +1 -0
  186. package/dist/loading/index.js +45 -2
  187. package/dist/loading/index.js.map +1 -1
  188. package/dist/loading/loading.d.ts +45 -2
  189. package/dist/modal-dialog-machine-CF9_z3Dm.js +487 -0
  190. package/dist/modal-dialog-machine-CF9_z3Dm.js.map +1 -0
  191. package/dist/modal-dialog-machine.d.ts +21 -0
  192. package/dist/modal-dismissable-lifetime.d.ts +21 -0
  193. package/dist/modal-registry.d.ts +24 -0
  194. package/dist/modal-render-hydration.d.ts +35 -0
  195. package/dist/modal-render-runtime.d.ts +19 -0
  196. package/dist/modal-render-scope.d.ts +63 -0
  197. package/dist/nav-bar/index.d.ts +1 -0
  198. package/dist/nav-bar/index.js +115 -0
  199. package/dist/nav-bar/index.js.map +1 -0
  200. package/dist/nav-bar/nav-bar.d.ts +76 -0
  201. package/dist/notice-bar/index.d.ts +2 -0
  202. package/dist/notice-bar/index.js +2 -0
  203. package/dist/notice-bar/notice-bar.d.ts +103 -0
  204. package/dist/notice-bar-DMpwLvRb.js +231 -0
  205. package/dist/notice-bar-DMpwLvRb.js.map +1 -0
  206. package/dist/notify/index.d.ts +1 -0
  207. package/dist/notify/index.js +251 -0
  208. package/dist/notify/index.js.map +1 -0
  209. package/dist/notify/notify.d.ts +123 -0
  210. package/dist/number-keyboard/index.d.ts +1 -0
  211. package/dist/number-keyboard/index.js +333 -0
  212. package/dist/number-keyboard/index.js.map +1 -0
  213. package/dist/number-keyboard/number-keyboard.d.ts +141 -0
  214. package/dist/page-indicator/index.d.ts +1 -0
  215. package/dist/page-indicator/index.js +138 -0
  216. package/dist/page-indicator/index.js.map +1 -0
  217. package/dist/page-indicator/page-indicator.d.ts +93 -0
  218. package/dist/pagination/index.d.ts +1 -0
  219. package/dist/pagination/index.js +198 -0
  220. package/dist/pagination/index.js.map +1 -0
  221. package/dist/pagination/pagination.d.ts +125 -0
  222. package/dist/password-input/index.d.ts +1 -0
  223. package/dist/password-input/index.js +317 -0
  224. package/dist/password-input/index.js.map +1 -0
  225. package/dist/password-input/password-input.d.ts +144 -0
  226. package/dist/picker/index.d.ts +8 -0
  227. package/dist/picker/index.js +2 -0
  228. package/dist/picker/picker-machine.d.ts +80 -0
  229. package/dist/picker/picker.d.ts +121 -0
  230. package/dist/picker/platform.d.ts +84 -0
  231. package/dist/picker/selection-connect.d.ts +90 -0
  232. package/dist/picker/selection-model.d.ts +211 -0
  233. package/dist/picker-BykFntQN.js +1675 -0
  234. package/dist/picker-BykFntQN.js.map +1 -0
  235. package/dist/popover/index.d.ts +3 -0
  236. package/dist/popover/index.js +253 -0
  237. package/dist/popover/index.js.map +1 -0
  238. package/dist/popover/layer.d.ts +44 -0
  239. package/dist/popover/popover.d.ts +104 -0
  240. package/dist/popover/positioning.d.ts +132 -0
  241. package/dist/popup/index.d.ts +2 -0
  242. package/dist/popup/index.js +2 -0
  243. package/dist/popup/popup.d.ts +60 -0
  244. package/dist/popup-z5d8IYCt.js +576 -0
  245. package/dist/popup-z5d8IYCt.js.map +1 -0
  246. package/dist/portal-BHCNTWhg.js +78 -0
  247. package/dist/portal-BHCNTWhg.js.map +1 -0
  248. package/dist/portal.d.ts +61 -0
  249. package/dist/price/format.d.ts +19 -0
  250. package/dist/price/index.d.ts +1 -0
  251. package/dist/price/index.js +154 -0
  252. package/dist/price/index.js.map +1 -0
  253. package/dist/price/price.d.ts +88 -0
  254. package/dist/progress/index.d.ts +1 -0
  255. package/dist/progress/index.js +2 -0
  256. package/dist/progress/progress.d.ts +32 -0
  257. package/dist/progress-f3iYEfdA.js +37 -0
  258. package/dist/progress-f3iYEfdA.js.map +1 -0
  259. package/dist/pull-refresh/index.d.ts +1 -0
  260. package/dist/pull-refresh/index.js +414 -0
  261. package/dist/pull-refresh/index.js.map +1 -0
  262. package/dist/pull-refresh/pull-refresh.d.ts +118 -0
  263. package/dist/radio-group/index.d.ts +3 -0
  264. package/dist/radio-group/index.js +2 -0
  265. package/dist/radio-group/radio-group.d.ts +78 -0
  266. package/dist/radio-group-BOIMuqnS.js +230 -0
  267. package/dist/radio-group-BOIMuqnS.js.map +1 -0
  268. package/dist/rate/index.d.ts +1 -0
  269. package/dist/rate/index.js +2 -0
  270. package/dist/rate/rate-form.d.ts +28 -0
  271. package/dist/rate/rate.d.ts +144 -0
  272. package/dist/rate-5XsU2QkY.js +631 -0
  273. package/dist/rate-5XsU2QkY.js.map +1 -0
  274. package/dist/reorder/index.d.ts +1 -0
  275. package/dist/reorder/index.js +720 -0
  276. package/dist/reorder/index.js.map +1 -0
  277. package/dist/reorder/reorder.d.ts +190 -0
  278. package/dist/result/index.d.ts +1 -0
  279. package/dist/result/index.js +123 -0
  280. package/dist/result/index.js.map +1 -0
  281. package/dist/result/result.d.ts +88 -0
  282. package/dist/safe-area/index.d.ts +1 -0
  283. package/dist/safe-area/index.js +42 -0
  284. package/dist/safe-area/index.js.map +1 -0
  285. package/dist/safe-area/safe-area.d.ts +28 -0
  286. package/dist/search-bar/index.js +3 -1
  287. package/dist/search-bar/index.js.map +1 -1
  288. package/dist/search-bar/search-bar.d.ts +4 -0
  289. package/dist/segmented/index.d.ts +2 -0
  290. package/dist/segmented/index.js +2 -0
  291. package/dist/segmented/segmented.d.ts +127 -0
  292. package/dist/segmented-BaU38_L4.js +367 -0
  293. package/dist/segmented-BaU38_L4.js.map +1 -0
  294. package/dist/selection-form-BOM_odUk.js +88 -0
  295. package/dist/selection-form-BOM_odUk.js.map +1 -0
  296. package/dist/selection-form.d.ts +27 -0
  297. package/dist/selection-ivXqO1eu.js +55 -0
  298. package/dist/selection-ivXqO1eu.js.map +1 -0
  299. package/dist/selection.d.ts +29 -0
  300. package/dist/selector/choice-group.d.ts +114 -0
  301. package/dist/selector/index.d.ts +2 -0
  302. package/dist/selector/index.js +2 -0
  303. package/dist/selector/selector.d.ts +90 -0
  304. package/dist/selector-BU2MMJ4N.js +93 -0
  305. package/dist/selector-BU2MMJ4N.js.map +1 -0
  306. package/dist/share-sheet/index.d.ts +1 -0
  307. package/dist/share-sheet/index.js +138 -0
  308. package/dist/share-sheet/index.js.map +1 -0
  309. package/dist/share-sheet/share-sheet.d.ts +139 -0
  310. package/dist/skeleton/index.js +51 -2
  311. package/dist/skeleton/index.js.map +1 -1
  312. package/dist/skeleton/skeleton.d.ts +34 -3
  313. package/dist/slider/index.d.ts +1 -0
  314. package/dist/slider/index.js +482 -0
  315. package/dist/slider/index.js.map +1 -0
  316. package/dist/slider/slider.d.ts +174 -0
  317. package/dist/space/index.d.ts +1 -0
  318. package/dist/space/index.js +52 -0
  319. package/dist/space/index.js.map +1 -0
  320. package/dist/space/space.d.ts +46 -0
  321. package/dist/statistic/index.d.ts +1 -0
  322. package/dist/statistic/index.js +152 -0
  323. package/dist/statistic/index.js.map +1 -0
  324. package/dist/statistic/statistic.d.ts +101 -0
  325. package/dist/stepper/index.js +62 -3
  326. package/dist/stepper/index.js.map +1 -1
  327. package/dist/stepper/stepper.d.ts +44 -4
  328. package/dist/steps/index.d.ts +1 -0
  329. package/dist/steps/index.js +72 -0
  330. package/dist/steps/index.js.map +1 -0
  331. package/dist/steps/steps.d.ts +67 -0
  332. package/dist/sticky/index.d.ts +1 -0
  333. package/dist/sticky/index.js +145 -0
  334. package/dist/sticky/index.js.map +1 -0
  335. package/dist/sticky/sticky.d.ts +70 -0
  336. package/dist/swipe-action/index.d.ts +1 -0
  337. package/dist/swipe-action/index.js +417 -0
  338. package/dist/swipe-action/index.js.map +1 -0
  339. package/dist/swipe-action/swipe-action.d.ts +148 -0
  340. package/dist/swiper/gesture.d.ts +32 -0
  341. package/dist/swiper/index.d.ts +1 -0
  342. package/dist/swiper/index.js +2 -0
  343. package/dist/swiper/swiper.d.ts +177 -0
  344. package/dist/swiper-BKivDkHp.js +550 -0
  345. package/dist/swiper-BKivDkHp.js.map +1 -0
  346. package/dist/switch/index.js +135 -10
  347. package/dist/switch/index.js.map +1 -1
  348. package/dist/switch/switch.d.ts +93 -6
  349. package/dist/tabbar/index.js +46 -1
  350. package/dist/tabbar/index.js.map +1 -1
  351. package/dist/tabbar/tabbar.d.ts +50 -0
  352. package/dist/tabs/index.js +22 -1
  353. package/dist/tabs/index.js.map +1 -1
  354. package/dist/tabs/tabs.d.ts +12 -8
  355. package/dist/tag/index.js +123 -2
  356. package/dist/tag/index.js.map +1 -1
  357. package/dist/tag/tag.d.ts +67 -1
  358. package/dist/textarea/index.d.ts +2 -0
  359. package/dist/textarea/index.js +2 -242
  360. package/dist/textarea/platform.d.ts +22 -0
  361. package/dist/textarea/textarea.d.ts +165 -46
  362. package/dist/textarea-qbnruDUG.js +775 -0
  363. package/dist/textarea-qbnruDUG.js.map +1 -0
  364. package/dist/time-picker/index.d.ts +1 -0
  365. package/dist/time-picker/index.js +228 -0
  366. package/dist/time-picker/index.js.map +1 -0
  367. package/dist/time-picker/time-picker.d.ts +83 -0
  368. package/dist/timeline/index.d.ts +1 -0
  369. package/dist/timeline/index.js +131 -0
  370. package/dist/timeline/index.js.map +1 -0
  371. package/dist/timeline/timeline.d.ts +79 -0
  372. package/dist/toast/index.js +47 -4
  373. package/dist/toast/index.js.map +1 -1
  374. package/dist/toast/toast.d.ts +26 -3
  375. package/dist/top-bar/index.js +16 -2
  376. package/dist/top-bar/index.js.map +1 -1
  377. package/dist/top-bar/top-bar.d.ts +13 -2
  378. package/dist/tree-select/index.d.ts +1 -0
  379. package/dist/tree-select/index.js +512 -0
  380. package/dist/tree-select/index.js.map +1 -0
  381. package/dist/tree-select/tree-select.d.ts +215 -0
  382. package/dist/typography/index.d.ts +1 -0
  383. package/dist/typography/index.js +82 -0
  384. package/dist/typography/index.js.map +1 -0
  385. package/dist/typography/typography.d.ts +54 -0
  386. package/dist/upload/index.d.ts +1 -0
  387. package/dist/upload/index.js +458 -0
  388. package/dist/upload/index.js.map +1 -0
  389. package/dist/upload/upload.d.ts +172 -0
  390. package/dist/virtual-list/index.d.ts +1 -0
  391. package/dist/virtual-list/index.js +445 -0
  392. package/dist/virtual-list/index.js.map +1 -0
  393. package/dist/virtual-list/virtual-list.d.ts +160 -0
  394. package/dist/visual-manifest.d.ts +6 -0
  395. package/dist/watermark/index.d.ts +1 -0
  396. package/dist/watermark/index.js +260 -0
  397. package/dist/watermark/index.js.map +1 -0
  398. package/dist/watermark/watermark.d.ts +106 -0
  399. package/package.json +399 -50
  400. package/dist/empty/index.js.map +0 -1
  401. package/dist/icon/index.js.map +0 -1
  402. package/dist/textarea/index.js.map +0 -1
@@ -0,0 +1,320 @@
1
+ import { createMachine } from "@zag-js/core";
2
+ import { dataAttr, visuallyHiddenStyle } from "@zag-js/dom-query";
3
+ //#region src/ellipsis/ellipsis-layout.ts
4
+ /** Inherited typography that determines line breaking. */
5
+ const COPIED_STYLES = [
6
+ "font-family",
7
+ "font-size",
8
+ "font-weight",
9
+ "font-style",
10
+ "font-variant",
11
+ "font-stretch",
12
+ "font-feature-settings",
13
+ "letter-spacing",
14
+ "word-spacing",
15
+ "line-height",
16
+ "text-transform",
17
+ "text-indent",
18
+ "word-break",
19
+ "overflow-wrap",
20
+ "line-break",
21
+ "hyphens",
22
+ "tab-size",
23
+ "direction",
24
+ "unicode-bidi",
25
+ "writing-mode"
26
+ ];
27
+ const ELLIPSIS_PROBE_ATTRIBUTE = "data-qw-ellipsis-probe";
28
+ /** Code-point safe truncation candidates; `kept` counts content code points that remain visible. */
29
+ function buildEllipsisCandidate(chars, kept, direction, symbol) {
30
+ const count = Math.max(0, Math.min(chars.length, Math.floor(kept)));
31
+ if (direction === "start") return symbol + chars.slice(chars.length - count).join("");
32
+ if (direction === "middle") {
33
+ const head = Math.ceil(count / 2), tail = count - head;
34
+ return chars.slice(0, head).join("") + symbol + (tail ? chars.slice(chars.length - tail).join("") : "");
35
+ }
36
+ return chars.slice(0, count).join("") + symbol;
37
+ }
38
+ /**
39
+ * Pure search: longest candidate that `fits`. `fits` must be monotonic (fewer kept characters never fit worse).
40
+ * Returns null when the full content fits.
41
+ */
42
+ function findEllipsisText(content, direction, symbol, fits) {
43
+ if (fits(content)) return null;
44
+ const chars = Array.from(content);
45
+ let low = 0, high = chars.length - 1, best = 0;
46
+ while (low <= high) {
47
+ const mid = low + high >> 1;
48
+ if (fits(buildEllipsisCandidate(chars, mid, direction, symbol))) {
49
+ best = mid;
50
+ low = mid + 1;
51
+ } else high = mid - 1;
52
+ }
53
+ return buildEllipsisCandidate(chars, best, direction, symbol);
54
+ }
55
+ function px(value) {
56
+ const parsed = Number.parseFloat(value);
57
+ return Number.isFinite(parsed) ? parsed : 0;
58
+ }
59
+ /** Measures with a detached-from-layout probe in the same document; returns null when not laid out (zero width). */
60
+ function measureEllipsisLayout(root, input) {
61
+ const doc = root.ownerDocument, view = doc.defaultView;
62
+ if (!view || !doc.body || !root.isConnected) return null;
63
+ const style = view.getComputedStyle(root);
64
+ const width = root.getBoundingClientRect().width - px(style.paddingLeft) - px(style.paddingRight) - px(style.borderLeftWidth) - px(style.borderRightWidth);
65
+ if (!(width > 0)) return null;
66
+ const probe = doc.createElement("div");
67
+ probe.setAttribute(ELLIPSIS_PROBE_ATTRIBUTE, "");
68
+ probe.setAttribute("aria-hidden", "true");
69
+ for (const name of COPIED_STYLES) probe.style.setProperty(name, style.getPropertyValue(name));
70
+ for (const [name, value] of [
71
+ ["position", "absolute"],
72
+ ["visibility", "hidden"],
73
+ ["pointer-events", "none"],
74
+ ["inset-block-start", "0"],
75
+ ["inset-inline-start", "0"],
76
+ ["display", "block"],
77
+ ["box-sizing", "content-box"],
78
+ ["padding", "0"],
79
+ ["border", "0"],
80
+ ["margin", "0"],
81
+ ["inline-size", `${width}px`],
82
+ ["block-size", "auto"],
83
+ ["max-block-size", "none"],
84
+ ["overflow", "visible"],
85
+ ["white-space", style.whiteSpace === "nowrap" || style.whiteSpace === "pre" ? "pre-wrap" : style.whiteSpace || "normal"],
86
+ ["-webkit-line-clamp", "none"]
87
+ ]) probe.style.setProperty(name, value);
88
+ probe.style.setProperty("width", `${width}px`);
89
+ doc.body.append(probe);
90
+ try {
91
+ probe.replaceChildren();
92
+ for (let line = 0; line < input.rows; line++) {
93
+ if (line) probe.append(doc.createElement("br"));
94
+ probe.append(doc.createTextNode("\xA0"));
95
+ }
96
+ const limit = probe.getBoundingClientRect().height + .5;
97
+ const suffix = input.actionText ? `\u00a0${input.actionText}\u00a0` : "";
98
+ const height = (text) => {
99
+ probe.textContent = text;
100
+ return probe.getBoundingClientRect().height;
101
+ };
102
+ if (height(input.content) <= limit) return {
103
+ overflow: false,
104
+ text: input.content,
105
+ width
106
+ };
107
+ const text = findEllipsisText(input.content, input.direction, input.symbol, (candidate) => height(candidate + suffix) <= limit);
108
+ return {
109
+ overflow: text !== null,
110
+ text: text ?? input.content,
111
+ width
112
+ };
113
+ } finally {
114
+ probe.remove();
115
+ }
116
+ }
117
+ /** Calls `onChange` when the observed inline size changes (and once on start). Returns stop. */
118
+ function observeEllipsisLayout(root, onChange) {
119
+ const view = root.ownerDocument.defaultView;
120
+ let disposed = false, last = NaN;
121
+ const notify = () => {
122
+ if (!disposed) onChange();
123
+ };
124
+ let observer;
125
+ if (view && typeof view.ResizeObserver === "function") {
126
+ observer = new view.ResizeObserver((entries) => {
127
+ const width = entries[entries.length - 1]?.contentRect?.width;
128
+ if (typeof width === "number" && width === last) return;
129
+ if (typeof width === "number") last = width;
130
+ notify();
131
+ });
132
+ observer.observe(root);
133
+ } else queueMicrotask(notify);
134
+ const fonts = root.ownerDocument.fonts;
135
+ if (fonts?.ready) fonts.ready.then(notify, () => {});
136
+ return () => {
137
+ disposed = true;
138
+ observer?.disconnect();
139
+ };
140
+ }
141
+ //#endregion
142
+ //#region src/ellipsis/ellipsis.ts
143
+ const ELLIPSIS_DIRECTIONS = [
144
+ "end",
145
+ "start",
146
+ "middle"
147
+ ];
148
+ const ELLIPSIS_PARTS = [
149
+ "root",
150
+ "content",
151
+ "text",
152
+ "full-text",
153
+ "toggle"
154
+ ];
155
+ function normalizeEllipsisRows(rows) {
156
+ return typeof rows === "number" && Number.isFinite(rows) && rows >= 1 ? Math.min(1e3, Math.floor(rows)) : 1;
157
+ }
158
+ function createEllipsisProps(props) {
159
+ if (props.id !== void 0 && (typeof props.id !== "string" || !props.id.trim())) throw new TypeError("Ellipsis requires a nonempty instance id when provided");
160
+ return {
161
+ ...props,
162
+ content: typeof props.content === "string" ? props.content : String(props.content ?? ""),
163
+ rows: normalizeEllipsisRows(props.rows),
164
+ direction: ELLIPSIS_DIRECTIONS.includes(props.direction) ? props.direction : "end",
165
+ expandText: typeof props.expandText === "string" ? props.expandText : "展开",
166
+ collapseText: typeof props.collapseText === "string" ? props.collapseText : "收起",
167
+ symbol: typeof props.symbol === "string" ? props.symbol : "…",
168
+ defaultExpanded: props.defaultExpanded === true,
169
+ expanded: typeof props.expanded === "boolean" ? props.expanded : void 0
170
+ };
171
+ }
172
+ function hex(id) {
173
+ return id.split("").map((char) => char.charCodeAt(0).toString(16).padStart(4, "0")).join("");
174
+ }
175
+ const rootId = (scope) => {
176
+ if (!scope.id?.trim()) throw new TypeError("Ellipsis requires a nonempty stable id");
177
+ return `qw-ellipsis-${hex(scope.id)}`;
178
+ };
179
+ const contentId = (scope) => `${rootId(scope)}-content`;
180
+ /** Measurement identity: a result for other text/options is never shown. */
181
+ const measureKey = (params) => JSON.stringify([
182
+ params.prop("content"),
183
+ params.prop("rows"),
184
+ params.prop("direction"),
185
+ params.prop("symbol"),
186
+ params.prop("expandText")
187
+ ]);
188
+ function measure(params) {
189
+ const root = params.scope.getById(rootId(params.scope));
190
+ if (!root) return;
191
+ const result = measureEllipsisLayout(root, {
192
+ content: params.prop("content"),
193
+ rows: params.prop("rows"),
194
+ direction: params.prop("direction"),
195
+ symbol: params.prop("symbol"),
196
+ actionText: params.prop("expandText")
197
+ });
198
+ if (!result) return;
199
+ const key = measureKey(params), previous = params.context.get("measurement");
200
+ if (previous && previous.key === key && previous.overflow === result.overflow && previous.text === result.text) return;
201
+ params.context.set("measurement", {
202
+ ...result,
203
+ key
204
+ });
205
+ }
206
+ /** Expanded state + measurement lifecycle. The resize observer is a Core effect: start on mount, stop on unmount. */
207
+ const ellipsisMachine = createMachine({
208
+ props: ({ props }) => createEllipsisProps({
209
+ ...props,
210
+ content: props.content ?? ""
211
+ }),
212
+ initialState: () => "ready",
213
+ context({ prop, bindable }) {
214
+ return {
215
+ expanded: bindable(() => ({
216
+ defaultValue: prop("defaultExpanded"),
217
+ value: prop("expanded"),
218
+ onChange: (expanded) => prop("onExpandedChange")?.({ expanded })
219
+ })),
220
+ measurement: bindable(() => ({ defaultValue: null }))
221
+ };
222
+ },
223
+ watch({ track, prop, send }) {
224
+ track([
225
+ () => prop("content"),
226
+ () => prop("rows"),
227
+ () => prop("direction"),
228
+ () => prop("symbol"),
229
+ () => prop("expandText")
230
+ ], () => send({ type: "MEASURE" }));
231
+ },
232
+ effects: ["observeLayout"],
233
+ on: {
234
+ TOGGLE: { actions: ["toggle"] },
235
+ "EXPANDED.SET": { actions: ["setExpanded"] },
236
+ MEASURE: { actions: ["measure"] }
237
+ },
238
+ states: { ready: {} },
239
+ implementations: {
240
+ effects: { observeLayout({ scope, send }) {
241
+ const root = scope.getById(rootId(scope));
242
+ if (!root) return;
243
+ return observeEllipsisLayout(root, () => send({ type: "MEASURE" }));
244
+ } },
245
+ actions: {
246
+ toggle({ context, prop }) {
247
+ if (prop("expandText") || context.get("expanded")) context.set("expanded", !context.get("expanded"));
248
+ },
249
+ setExpanded({ context, event }) {
250
+ if (event.type === "EXPANDED.SET") context.set("expanded", event.value);
251
+ },
252
+ measure
253
+ }
254
+ }
255
+ });
256
+ function connectEllipsis(service, normalize) {
257
+ const content = service.prop("content"), expanded = !!service.context.get("expanded");
258
+ const stored = service.context.get("measurement");
259
+ const current = stored && stored.key === measureKey(service) ? stored : null;
260
+ const overflow = !!current?.overflow, truncated = overflow && !expanded;
261
+ const toggleText = expanded ? service.prop("collapseText") : service.prop("expandText");
262
+ const showToggle = overflow && toggleText !== "";
263
+ const part = (name) => ({
264
+ "data-scope": "ellipsis",
265
+ "data-part": name
266
+ });
267
+ const id = rootId(service.scope);
268
+ return {
269
+ content,
270
+ expanded,
271
+ measured: current !== null,
272
+ overflow,
273
+ truncated,
274
+ visibleText: truncated ? current.text : content,
275
+ toggleText,
276
+ showToggle,
277
+ setExpanded: (value) => service.send({
278
+ type: "EXPANDED.SET",
279
+ value
280
+ }),
281
+ remeasure: () => service.send({ type: "MEASURE" }),
282
+ getRootProps: () => normalize.element({
283
+ ...part("root"),
284
+ id,
285
+ "data-direction": service.prop("direction"),
286
+ "data-expanded": dataAttr(expanded),
287
+ "data-measured": dataAttr(current !== null),
288
+ "data-overflow": dataAttr(overflow),
289
+ "data-truncated": dataAttr(truncated),
290
+ style: { "--qw-ellipsis-rows": String(service.prop("rows")) }
291
+ }),
292
+ getContentProps: () => normalize.element({
293
+ ...part("content"),
294
+ id: contentId(service.scope)
295
+ }),
296
+ getTextProps: () => normalize.element({
297
+ ...part("text"),
298
+ "aria-hidden": truncated ? "true" : void 0
299
+ }),
300
+ getFullTextProps: () => normalize.element({
301
+ ...part("full-text"),
302
+ hidden: !truncated,
303
+ style: truncated ? visuallyHiddenStyle : void 0
304
+ }),
305
+ getToggleProps: () => normalize.button({
306
+ ...part("toggle"),
307
+ type: "button",
308
+ hidden: !showToggle,
309
+ "aria-expanded": expanded,
310
+ "aria-controls": contentId(service.scope),
311
+ onClick() {
312
+ service.send({ type: "TOGGLE" });
313
+ }
314
+ })
315
+ };
316
+ }
317
+ //#endregion
318
+ export { ELLIPSIS_DIRECTIONS, ELLIPSIS_PARTS, ELLIPSIS_PROBE_ATTRIBUTE, buildEllipsisCandidate, connectEllipsis, createEllipsisProps, ellipsisMachine, findEllipsisText, measureEllipsisLayout, normalizeEllipsisRows, observeEllipsisLayout };
319
+
320
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/ellipsis/ellipsis-layout.ts","../../src/ellipsis/ellipsis.ts"],"sourcesContent":["import type { EllipsisDirection } from \"./ellipsis.js\";\n\n/**\n * Ellipsis platform boundary: DOM measurement and resize observation only.\n * Truncation search and expanded/collapsed decisions stay in ellipsis.ts.\n * Nothing here runs at module top level, so importing it is SSR-safe.\n */\nexport interface EllipsisMeasureInput {\n content: string;\n rows: number;\n direction: EllipsisDirection;\n symbol: string;\n /** Visible action label measured on the same line as the truncated text (\"\" = none). */\n actionText: string;\n}\nexport interface EllipsisMeasurement {\n /** True when the full content exceeds `rows` lines. */\n overflow: boolean;\n /** Collapsed visible text (with symbol) when overflowing; otherwise the full content. */\n text: string;\n /** Inline size used for the decision, in CSS pixels. */\n width: number;\n}\n\n/** Inherited typography that determines line breaking. */\nconst COPIED_STYLES = [\"font-family\", \"font-size\", \"font-weight\", \"font-style\", \"font-variant\", \"font-stretch\", \"font-feature-settings\", \"letter-spacing\", \"word-spacing\", \"line-height\", \"text-transform\", \"text-indent\", \"word-break\", \"overflow-wrap\", \"line-break\", \"hyphens\", \"tab-size\", \"direction\", \"unicode-bidi\", \"writing-mode\"] as const;\nexport const ELLIPSIS_PROBE_ATTRIBUTE = \"data-qw-ellipsis-probe\";\n\n/** Code-point safe truncation candidates; `kept` counts content code points that remain visible. */\nexport function buildEllipsisCandidate(chars: readonly string[], kept: number, direction: EllipsisDirection, symbol: string): string {\n const count = Math.max(0, Math.min(chars.length, Math.floor(kept)));\n if (direction === \"start\") return symbol + chars.slice(chars.length - count).join(\"\");\n if (direction === \"middle\") {\n const head = Math.ceil(count / 2), tail = count - head;\n return chars.slice(0, head).join(\"\") + symbol + (tail ? chars.slice(chars.length - tail).join(\"\") : \"\");\n }\n return chars.slice(0, count).join(\"\") + symbol;\n}\n\n/**\n * Pure search: longest candidate that `fits`. `fits` must be monotonic (fewer kept characters never fit worse).\n * Returns null when the full content fits.\n */\nexport function findEllipsisText(content: string, direction: EllipsisDirection, symbol: string, fits: (candidate: string) => boolean): string | null {\n if (fits(content)) return null;\n const chars = Array.from(content);\n let low = 0, high = chars.length - 1, best = 0;\n while (low <= high) {\n const mid = (low + high) >> 1;\n if (fits(buildEllipsisCandidate(chars, mid, direction, symbol))) { best = mid; low = mid + 1; } else high = mid - 1;\n }\n return buildEllipsisCandidate(chars, best, direction, symbol);\n}\n\nfunction px(value: string): number { const parsed = Number.parseFloat(value); return Number.isFinite(parsed) ? parsed : 0; }\n\n/** Measures with a detached-from-layout probe in the same document; returns null when not laid out (zero width). */\nexport function measureEllipsisLayout(root: HTMLElement, input: EllipsisMeasureInput): EllipsisMeasurement | null {\n const doc = root.ownerDocument, view = doc.defaultView;\n if (!view || !doc.body || !root.isConnected) return null;\n const style = view.getComputedStyle(root);\n const width = root.getBoundingClientRect().width - px(style.paddingLeft) - px(style.paddingRight) - px(style.borderLeftWidth) - px(style.borderRightWidth);\n if (!(width > 0)) return null;\n const probe = doc.createElement(\"div\");\n probe.setAttribute(ELLIPSIS_PROBE_ATTRIBUTE, \"\");\n probe.setAttribute(\"aria-hidden\", \"true\");\n for (const name of COPIED_STYLES) probe.style.setProperty(name, style.getPropertyValue(name));\n for (const [name, value] of [[\"position\", \"absolute\"], [\"visibility\", \"hidden\"], [\"pointer-events\", \"none\"], [\"inset-block-start\", \"0\"], [\"inset-inline-start\", \"0\"], [\"display\", \"block\"], [\"box-sizing\", \"content-box\"], [\"padding\", \"0\"], [\"border\", \"0\"], [\"margin\", \"0\"], [\"inline-size\", `${width}px`], [\"block-size\", \"auto\"], [\"max-block-size\", \"none\"], [\"overflow\", \"visible\"], [\"white-space\", style.whiteSpace === \"nowrap\" || style.whiteSpace === \"pre\" ? \"pre-wrap\" : style.whiteSpace || \"normal\"], [\"-webkit-line-clamp\", \"none\"]] as const) probe.style.setProperty(name, value);\n probe.style.setProperty(\"width\", `${width}px`);\n doc.body.append(probe);\n try {\n probe.replaceChildren();\n for (let line = 0; line < input.rows; line++) { if (line) probe.append(doc.createElement(\"br\")); probe.append(doc.createTextNode(\"\\u00a0\")); }\n const limit = probe.getBoundingClientRect().height + 0.5;\n const suffix = input.actionText ? `\\u00a0${input.actionText}\\u00a0` : \"\";\n const height = (text: string) => { probe.textContent = text; return probe.getBoundingClientRect().height; };\n if (height(input.content) <= limit) return { overflow: false, text: input.content, width };\n const text = findEllipsisText(input.content, input.direction, input.symbol, (candidate) => height(candidate + suffix) <= limit);\n return { overflow: text !== null, text: text ?? input.content, width };\n } finally {\n probe.remove();\n }\n}\n\n/** Calls `onChange` when the observed inline size changes (and once on start). Returns stop. */\nexport function observeEllipsisLayout(root: HTMLElement, onChange: () => void): () => void {\n const view = root.ownerDocument.defaultView;\n let disposed = false, last = Number.NaN;\n const notify = () => { if (!disposed) onChange(); };\n let observer: ResizeObserver | undefined;\n if (view && typeof view.ResizeObserver === \"function\") {\n observer = new view.ResizeObserver((entries) => {\n const width = entries[entries.length - 1]?.contentRect?.width;\n if (typeof width === \"number\" && width === last) return;\n if (typeof width === \"number\") last = width;\n notify();\n });\n observer.observe(root);\n } else queueMicrotask(notify);\n const fonts = root.ownerDocument.fonts;\n if (fonts?.ready) void fonts.ready.then(notify, () => {});\n return () => { disposed = true; observer?.disconnect(); };\n}\n","import { createMachine, type Machine, type Params, type Service } from \"@zag-js/core\";\nimport { dataAttr, visuallyHiddenStyle } from \"@zag-js/dom-query\";\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\";\nimport { measureEllipsisLayout, observeEllipsisLayout, type EllipsisMeasurement } from \"./ellipsis-layout.js\";\n\nexport const ELLIPSIS_DIRECTIONS = [\"end\", \"start\", \"middle\"] as const;\nexport const ELLIPSIS_PARTS = [\"root\", \"content\", \"text\", \"full-text\", \"toggle\"] as const;\nexport type EllipsisDirection = (typeof ELLIPSIS_DIRECTIONS)[number];\nexport type EllipsisPart = (typeof ELLIPSIS_PARTS)[number];\nexport interface EllipsisExpandedChangeDetails { expanded: boolean }\n\nexport interface QwEllipsisProps {\n /** Stable instance identity for aria-controls; frameworks generate one when omitted. */\n id?: string;\n /** Plain text content (measurement requires text). */\n content: string;\n /** Visible lines when collapsed; integer ≥ 1, invalid → 1. */\n rows?: number;\n /** Where the ellipsis symbol goes. Default end. */\n direction?: EllipsisDirection;\n /** Controlled expanded state when defined. */\n expanded?: boolean;\n defaultExpanded?: boolean;\n /** Expand action label; \"\" disables expansion. Default 展开. */\n expandText?: string;\n /** Collapse action label; \"\" hides the collapse action. Default 收起. */\n collapseText?: string;\n /** Ellipsis symbol. Default …. */\n symbol?: string;\n onExpandedChange?: (details: EllipsisExpandedChangeDetails) => void;\n}\n\nexport function normalizeEllipsisRows(rows: unknown): number {\n return typeof rows === \"number\" && Number.isFinite(rows) && rows >= 1 ? Math.min(1000, Math.floor(rows)) : 1;\n}\ntype NormalizedProps = QwEllipsisProps & { content: string; rows: number; direction: EllipsisDirection; expandText: string; collapseText: string; symbol: string; defaultExpanded: boolean };\nexport function createEllipsisProps(props: QwEllipsisProps): NormalizedProps {\n if (props.id !== undefined && (typeof props.id !== \"string\" || !props.id.trim())) throw new TypeError(\"Ellipsis requires a nonempty instance id when provided\");\n return {\n ...props,\n content: typeof props.content === \"string\" ? props.content : String(props.content ?? \"\"),\n rows: normalizeEllipsisRows(props.rows),\n direction: ELLIPSIS_DIRECTIONS.includes(props.direction!) ? props.direction! : \"end\",\n expandText: typeof props.expandText === \"string\" ? props.expandText : \"展开\",\n collapseText: typeof props.collapseText === \"string\" ? props.collapseText : \"收起\",\n symbol: typeof props.symbol === \"string\" ? props.symbol : \"…\",\n defaultExpanded: props.defaultExpanded === true,\n expanded: typeof props.expanded === \"boolean\" ? props.expanded : undefined,\n };\n}\ninterface KeyedMeasurement extends EllipsisMeasurement { key: string }\nexport interface QwEllipsisSchema {\n props: NormalizedProps;\n context: { expanded: boolean; measurement: KeyedMeasurement | null };\n state: \"ready\";\n action: \"toggle\" | \"setExpanded\" | \"measure\";\n effect: \"observeLayout\";\n event: { type: \"TOGGLE\" } | { type: \"EXPANDED.SET\"; value: boolean } | { type: \"MEASURE\" };\n}\nexport type QwEllipsisMachine = Machine<QwEllipsisSchema>;\nexport type QwEllipsisService = Service<QwEllipsisSchema>;\ntype EllipsisParams = Pick<Params<QwEllipsisSchema>, \"context\" | \"prop\" | \"scope\">;\n\nfunction hex(id: string) { return id.split(\"\").map((char) => char.charCodeAt(0).toString(16).padStart(4, \"0\")).join(\"\"); }\nconst rootId = (scope: QwEllipsisService[\"scope\"]) => { if (!scope.id?.trim()) throw new TypeError(\"Ellipsis requires a nonempty stable id\"); return `qw-ellipsis-${hex(scope.id)}`; };\nconst contentId = (scope: QwEllipsisService[\"scope\"]) => `${rootId(scope)}-content`;\n/** Measurement identity: a result for other text/options is never shown. */\nconst measureKey = (params: Pick<EllipsisParams, \"prop\">) => JSON.stringify([params.prop(\"content\"), params.prop(\"rows\"), params.prop(\"direction\"), params.prop(\"symbol\"), params.prop(\"expandText\")]);\nfunction measure(params: EllipsisParams) {\n const root = params.scope.getById<HTMLElement>(rootId(params.scope));\n if (!root) return;\n const result = measureEllipsisLayout(root, { content: params.prop(\"content\"), rows: params.prop(\"rows\"), direction: params.prop(\"direction\"), symbol: params.prop(\"symbol\"), actionText: params.prop(\"expandText\") });\n if (!result) return;\n const key = measureKey(params), previous = params.context.get(\"measurement\");\n if (previous && previous.key === key && previous.overflow === result.overflow && previous.text === result.text) return;\n params.context.set(\"measurement\", { ...result, key });\n}\n\n/** Expanded state + measurement lifecycle. The resize observer is a Core effect: start on mount, stop on unmount. */\nexport const ellipsisMachine: QwEllipsisMachine = createMachine<QwEllipsisSchema>({\n props: ({ props }) => createEllipsisProps({ ...props, content: props.content ?? \"\" }),\n initialState: () => \"ready\",\n context({ prop, bindable }) {\n return {\n expanded: bindable(() => ({ defaultValue: prop(\"defaultExpanded\"), value: prop(\"expanded\"), onChange: (expanded) => prop(\"onExpandedChange\")?.({ expanded }) })),\n measurement: bindable<KeyedMeasurement | null>(() => ({ defaultValue: null })),\n };\n },\n watch({ track, prop, send }) {\n track([() => prop(\"content\"), () => prop(\"rows\"), () => prop(\"direction\"), () => prop(\"symbol\"), () => prop(\"expandText\")], () => send({ type: \"MEASURE\" }));\n },\n effects: [\"observeLayout\"],\n on: { TOGGLE: { actions: [\"toggle\"] }, \"EXPANDED.SET\": { actions: [\"setExpanded\"] }, MEASURE: { actions: [\"measure\"] } },\n states: { ready: {} },\n implementations: {\n effects: {\n observeLayout({ scope, send }) {\n const root = scope.getById<HTMLElement>(rootId(scope));\n if (!root) return;\n return observeEllipsisLayout(root, () => send({ type: \"MEASURE\" }));\n },\n },\n actions: {\n toggle({ context, prop }) { if (prop(\"expandText\") || context.get(\"expanded\")) context.set(\"expanded\", !context.get(\"expanded\")); },\n setExpanded({ context, event }) { if (event.type === \"EXPANDED.SET\") context.set(\"expanded\", event.value); },\n measure,\n },\n },\n});\n\nexport interface QwEllipsisApi<T extends PropTypes = PropTypes> {\n content: string;\n expanded: boolean;\n /** A current measurement exists for these props. */\n measured: boolean;\n overflow: boolean;\n /** Visible text is shortened; full text is provided to assistive technology separately. */\n truncated: boolean;\n visibleText: string;\n toggleText: string;\n showToggle: boolean;\n setExpanded(expanded: boolean): void;\n /** Re-run measurement (for example after a caller-driven style change). */\n remeasure(): void;\n getRootProps(): T[\"element\"];\n getContentProps(): T[\"element\"];\n getTextProps(): T[\"element\"];\n getFullTextProps(): T[\"element\"];\n getToggleProps(): T[\"button\"];\n}\n\nexport function connectEllipsis<T extends PropTypes>(service: QwEllipsisService, normalize: NormalizeProps<T>): QwEllipsisApi<T> {\n const content = service.prop(\"content\"), expanded = !!service.context.get(\"expanded\");\n const stored = service.context.get(\"measurement\");\n const current = stored && stored.key === measureKey(service) ? stored : null;\n const overflow = !!current?.overflow, truncated = overflow && !expanded;\n const toggleText = expanded ? service.prop(\"collapseText\") : service.prop(\"expandText\");\n const showToggle = overflow && toggleText !== \"\";\n const part = (name: EllipsisPart) => ({ \"data-scope\": \"ellipsis\", \"data-part\": name });\n const id = rootId(service.scope);\n return {\n content, expanded, measured: current !== null, overflow, truncated,\n visibleText: truncated ? current!.text : content, toggleText, showToggle,\n setExpanded: (value) => service.send({ type: \"EXPANDED.SET\", value }),\n remeasure: () => service.send({ type: \"MEASURE\" }),\n getRootProps: () => normalize.element({ ...part(\"root\"), id, \"data-direction\": service.prop(\"direction\"), \"data-expanded\": dataAttr(expanded), \"data-measured\": dataAttr(current !== null), \"data-overflow\": dataAttr(overflow), \"data-truncated\": dataAttr(truncated), style: { \"--qw-ellipsis-rows\": String(service.prop(\"rows\")) } }),\n getContentProps: () => normalize.element({ ...part(\"content\"), id: contentId(service.scope) }),\n getTextProps: () => normalize.element({ ...part(\"text\"), \"aria-hidden\": truncated ? \"true\" : undefined }),\n getFullTextProps: () => normalize.element({ ...part(\"full-text\"), hidden: !truncated, style: truncated ? visuallyHiddenStyle : undefined }),\n getToggleProps: () => normalize.button({ ...part(\"toggle\"), type: \"button\", hidden: !showToggle, \"aria-expanded\": expanded, \"aria-controls\": contentId(service.scope),\n onClick() { service.send({ type: \"TOGGLE\" }); } }),\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Original 015-empty decorative SVG asset; retained gradient colors are asset data, not component chrome. */
2
+ import type { EmptyVectorNode } from "./empty.js";
3
+ export declare const EMPTY_ILLUSTRATION_ASSET: EmptyVectorNode;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Empty 契约 — 原型 A(无状态),core 无 machine 也无共享枚举。
2
+ * Empty 契约 — 原型 A(无状态),Core 为三栈结构与原有插画的唯一来源。
3
3
  * 本目录是 Empty 的"源头锚点":契约文档与 demo 清单在 ./docs/ 下维护,
4
4
  * 双栈实现(React props / Vue props+slots)必须与 docs 清单严格对齐。
5
5
  * 渲染契约:`data-scope="empty"`,data-part 为 root / icon / title / description / actions。
@@ -10,3 +10,45 @@
10
10
  export declare const EMPTY_PARTS: readonly ["root", "icon", "title", "description", "actions"];
11
11
  /** Empty 各渲染部位(data-part 取值)。 */
12
12
  export type EmptyPart = (typeof EMPTY_PARTS)[number];
13
+ /** Scalar Empty inputs; framework-rich values use content presence. */
14
+ export interface QwEmptyProps {
15
+ title?: string | null;
16
+ description?: string | null;
17
+ hideIcon?: boolean;
18
+ }
19
+ /** Content presence distinguishes omitted from explicitly empty SSR channels. */
20
+ export interface EmptyContentPresence {
21
+ readonly icon?: boolean;
22
+ readonly title?: boolean;
23
+ readonly description?: boolean;
24
+ readonly default?: boolean;
25
+ }
26
+ /** Shared passive structure decisions; no generated role or live region. */
27
+ export interface EmptyState {
28
+ readonly iconMode: "default" | "custom" | "hidden";
29
+ readonly hasTitle: boolean;
30
+ readonly hasDescription: boolean;
31
+ readonly hasActions: boolean;
32
+ readonly titleFromContent: boolean;
33
+ readonly descriptionFromContent: boolean;
34
+ }
35
+ /** Resolve structure once, with explicit channel presence overriding scalars. */
36
+ export declare function resolveEmptyState(props?: QwEmptyProps, presence?: EmptyContentPresence): EmptyState;
37
+ /** Plain passive Empty root. */
38
+ export declare function getEmptyRootProps(): {
39
+ "data-scope": "empty";
40
+ "data-part": "actions" | "description" | "icon" | "root" | "title";
41
+ };
42
+ /** Shared stable selectors for Empty structure. */
43
+ export declare function getEmptyPartProps(part: EmptyPart): {
44
+ "data-scope": "empty";
45
+ "data-part": "actions" | "description" | "icon" | "root" | "title";
46
+ };
47
+ /** Framework-independent retained original vector asset. */
48
+ export interface EmptyVectorNode {
49
+ readonly tag: string;
50
+ readonly attrs: Readonly<Record<string, string>>;
51
+ readonly children: readonly EmptyVectorNode[];
52
+ }
53
+ /** Copy the original illustration with injectively scoped local SVG references. */
54
+ export declare function getEmptyIllustration(identity: string): EmptyVectorNode;
@@ -1,21 +1,2 @@
1
- //#region src/empty/empty.ts
2
- /**
3
- * Empty 契约 — 原型 A(无状态),core 无 machine 也无共享枚举。
4
- * 本目录是 Empty 的"源头锚点":契约文档与 demo 清单在 ./docs/ 下维护,
5
- * 双栈实现(React props / Vue props+slots)必须与 docs 清单严格对齐。
6
- * 渲染契约:`data-scope="empty"`,data-part 为 root / icon / title / description / actions。
7
- *
8
- * data-part 词表以运行时常量数组为唯一事实源(类型从常量推导),__test__ 直接锁死。
9
- */
10
- /** Empty 各渲染部位全集(data-part 取值),双栈与 styles-core 共用。 */
11
- const EMPTY_PARTS = [
12
- "root",
13
- "icon",
14
- "title",
15
- "description",
16
- "actions"
17
- ];
18
- //#endregion
19
- export { EMPTY_PARTS };
20
-
21
- //# sourceMappingURL=index.js.map
1
+ import { a as resolveEmptyState, i as getEmptyRootProps, n as getEmptyIllustration, r as getEmptyPartProps, t as EMPTY_PARTS } from "../empty-CAgyvhUI.js";
2
+ export { EMPTY_PARTS, getEmptyIllustration, getEmptyPartProps, getEmptyRootProps, resolveEmptyState };
@@ -0,0 +1,166 @@
1
+ //#region src/empty/empty-illustration.ts
2
+ const EMPTY_ILLUSTRATION_ASSET = {
3
+ "tag": "svg",
4
+ "attrs": {
5
+ "viewBox": "0 0 120 120",
6
+ "width": "120",
7
+ "height": "120",
8
+ "fill": "none",
9
+ "xmlns": "http://www.w3.org/2000/svg",
10
+ "aria-hidden": "true"
11
+ },
12
+ "children": [
13
+ {
14
+ "tag": "defs",
15
+ "attrs": {},
16
+ "children": [{
17
+ "tag": "linearGradient",
18
+ "attrs": {
19
+ "id": "doc",
20
+ "x1": "19",
21
+ "y1": "20",
22
+ "x2": "98.29",
23
+ "y2": "89.38",
24
+ "gradientUnits": "userSpaceOnUse"
25
+ },
26
+ "children": [{
27
+ "tag": "stop",
28
+ "attrs": {
29
+ "stop-color": "#222222",
30
+ "stop-opacity": "0.1"
31
+ },
32
+ "children": []
33
+ }, {
34
+ "tag": "stop",
35
+ "attrs": {
36
+ "offset": "1",
37
+ "stop-color": "#D8D8D8",
38
+ "stop-opacity": "0.02"
39
+ },
40
+ "children": []
41
+ }]
42
+ }, {
43
+ "tag": "linearGradient",
44
+ "attrs": {
45
+ "id": "wifi",
46
+ "x1": "66",
47
+ "y1": "75",
48
+ "x2": "101",
49
+ "y2": "99.58",
50
+ "gradientUnits": "userSpaceOnUse"
51
+ },
52
+ "children": [{
53
+ "tag": "stop",
54
+ "attrs": { "stop-color": "#CCCCCC" },
55
+ "children": []
56
+ }, {
57
+ "tag": "stop",
58
+ "attrs": {
59
+ "offset": "1",
60
+ "stop-color": "#EFEFEF"
61
+ },
62
+ "children": []
63
+ }]
64
+ }]
65
+ },
66
+ {
67
+ "tag": "path",
68
+ "attrs": {
69
+ "transform": "translate(19 20)",
70
+ "fill-rule": "evenodd",
71
+ "clip-rule": "evenodd",
72
+ "d": "M0 10C0 4.47715 4.47715 0 10 0H60C65.5229 0 70 4.47715 70 10V70C70 75.5229 65.5229 80 60 80H10C4.47715 80 0 75.5229 0 70V10ZM16 17.5C16 16.1193 17.1193 15 18.5 15H50.5C51.8807 15 53 16.1193 53 17.5C53 18.8807 51.8807 20 50.5 20H18.5C17.1193 20 16 18.8807 16 17.5ZM18.5 32C17.1193 32 16 33.1193 16 34.5C16 35.8807 17.1193 37 18.5 37H50.5C51.8807 37 53 35.8807 53 34.5C53 33.1193 51.8807 32 50.5 32H18.5Z",
73
+ "fill": "url(#doc)"
74
+ },
75
+ "children": []
76
+ },
77
+ {
78
+ "tag": "g",
79
+ "attrs": {
80
+ "transform": "translate(66 75)",
81
+ "fill": "url(#wifi)"
82
+ },
83
+ "children": [
84
+ {
85
+ "tag": "path",
86
+ "attrs": { "d": "M17.5156 0C11.2706 0 5.34603 2.33603 0.796994 6.57058L0 7.31249L0.774158 8.07793L3.29835 10.5779L4.02532 11.297L4.77588 10.6095C8.25388 7.41396 12.7717 5.64852 17.5004 5.64852C22.2291 5.64852 26.7545 7.41396 30.2249 10.6095L30.9754 11.297L31.7016 10.5779L34.2266 8.07793L35 7.31249L34.203 6.56984C29.67 2.33676 23.737 0 17.5156 0Z" },
87
+ "children": []
88
+ },
89
+ {
90
+ "tag": "path",
91
+ "attrs": { "d": "M28.5598 12.5317C25.5271 9.78909 21.6114 8.28174 17.5313 8.28174H16.8355L16.8279 8.29644C12.9822 8.45306 9.32459 9.94571 6.46393 12.5317L5.64258 13.2736L6.43196 14.0545L8.98813 16.5861L9.6991 17.2891L10.4497 16.6332C12.4273 14.8979 14.9363 13.9376 17.5077 13.9376C20.095 13.9376 22.604 14.8986 24.5809 16.6332L25.3315 17.2891L26.0424 16.5861L28.5986 14.0545L29.388 13.2736L28.5598 12.5317Z" },
92
+ "children": []
93
+ },
94
+ {
95
+ "tag": "path",
96
+ "attrs": { "d": "M16.7999 24.2862C17.201 24.682 17.8458 24.6818 18.2466 24.2857L22.4014 20.1797L23.2296 19.3598L22.323 18.6172C21.1195 17.7275 19.7904 17.0547 17.5159 17.0547C15.2497 17.0547 14.0067 17.79 12.7095 18.6172L11.8105 19.3598L12.6388 20.1797L16.7999 24.2862Z" },
97
+ "children": []
98
+ }
99
+ ]
100
+ }
101
+ ]
102
+ };
103
+ //#endregion
104
+ //#region src/empty/empty.ts
105
+ /**
106
+ * Empty 契约 — 原型 A(无状态),Core 为三栈结构与原有插画的唯一来源。
107
+ * 本目录是 Empty 的"源头锚点":契约文档与 demo 清单在 ./docs/ 下维护,
108
+ * 双栈实现(React props / Vue props+slots)必须与 docs 清单严格对齐。
109
+ * 渲染契约:`data-scope="empty"`,data-part 为 root / icon / title / description / actions。
110
+ *
111
+ * data-part 词表以运行时常量数组为唯一事实源(类型从常量推导),__test__ 直接锁死。
112
+ */
113
+ /** Empty 各渲染部位全集(data-part 取值),双栈与 styles-core 共用。 */
114
+ const EMPTY_PARTS = [
115
+ "root",
116
+ "icon",
117
+ "title",
118
+ "description",
119
+ "actions"
120
+ ];
121
+ /** Resolve structure once, with explicit channel presence overriding scalars. */
122
+ function resolveEmptyState(props = {}, presence = {}) {
123
+ return {
124
+ iconMode: props.hideIcon === true ? "hidden" : presence.icon ? "custom" : "default",
125
+ hasTitle: presence.title === true || props.title != null,
126
+ hasDescription: presence.description === true || props.description != null,
127
+ hasActions: presence.default === true,
128
+ titleFromContent: presence.title === true,
129
+ descriptionFromContent: presence.description === true
130
+ };
131
+ }
132
+ /** Plain passive Empty root. */
133
+ function getEmptyRootProps() {
134
+ return getEmptyPartProps("root");
135
+ }
136
+ /** Shared stable selectors for Empty structure. */
137
+ function getEmptyPartProps(part) {
138
+ return {
139
+ "data-scope": "empty",
140
+ "data-part": part
141
+ };
142
+ }
143
+ /** Copy the original illustration with injectively scoped local SVG references. */
144
+ function getEmptyIllustration(identity) {
145
+ if (!identity.length) throw new Error("Empty illustration requires a nonempty stable identity");
146
+ let encoded = "";
147
+ for (let index = 0; index < identity.length; index++) encoded += identity.charCodeAt(index).toString(16).padStart(4, "0");
148
+ const prefix = `qw-empty-${encoded}-`;
149
+ const copy = (source) => ({
150
+ tag: source.tag,
151
+ attrs: Object.fromEntries(Object.entries(source.attrs).map(([key, value]) => [key, key === "id" ? `${prefix}${value}` : value.replace(/url\(#(doc|wifi)\)/g, (_original, local) => `url(#${prefix}${local})`)])),
152
+ children: source.children.map(copy)
153
+ });
154
+ const vector = copy(EMPTY_ILLUSTRATION_ASSET);
155
+ return {
156
+ ...vector,
157
+ attrs: {
158
+ ...vector.attrs,
159
+ focusable: "false"
160
+ }
161
+ };
162
+ }
163
+ //#endregion
164
+ export { resolveEmptyState as a, getEmptyRootProps as i, getEmptyIllustration as n, getEmptyPartProps as r, EMPTY_PARTS as t };
165
+
166
+ //# sourceMappingURL=empty-CAgyvhUI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty-CAgyvhUI.js","names":[],"sources":["../src/empty/empty-illustration.ts","../src/empty/empty.ts"],"sourcesContent":["/** Original 015-empty decorative SVG asset; retained gradient colors are asset data, not component chrome. */\nimport type { EmptyVectorNode } from \"./empty.js\";\n\nexport const EMPTY_ILLUSTRATION_ASSET: EmptyVectorNode = {\n \"tag\": \"svg\",\n \"attrs\": {\n \"viewBox\": \"0 0 120 120\",\n \"width\": \"120\",\n \"height\": \"120\",\n \"fill\": \"none\",\n \"xmlns\": \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\"\n },\n \"children\": [\n {\n \"tag\": \"defs\",\n \"attrs\": {},\n \"children\": [\n {\n \"tag\": \"linearGradient\",\n \"attrs\": {\n \"id\": \"doc\",\n \"x1\": \"19\",\n \"y1\": \"20\",\n \"x2\": \"98.29\",\n \"y2\": \"89.38\",\n \"gradientUnits\": \"userSpaceOnUse\"\n },\n \"children\": [\n {\n \"tag\": \"stop\",\n \"attrs\": {\n \"stop-color\": \"#222222\",\n \"stop-opacity\": \"0.1\"\n },\n \"children\": []\n },\n {\n \"tag\": \"stop\",\n \"attrs\": {\n \"offset\": \"1\",\n \"stop-color\": \"#D8D8D8\",\n \"stop-opacity\": \"0.02\"\n },\n \"children\": []\n }\n ]\n },\n {\n \"tag\": \"linearGradient\",\n \"attrs\": {\n \"id\": \"wifi\",\n \"x1\": \"66\",\n \"y1\": \"75\",\n \"x2\": \"101\",\n \"y2\": \"99.58\",\n \"gradientUnits\": \"userSpaceOnUse\"\n },\n \"children\": [\n {\n \"tag\": \"stop\",\n \"attrs\": {\n \"stop-color\": \"#CCCCCC\"\n },\n \"children\": []\n },\n {\n \"tag\": \"stop\",\n \"attrs\": {\n \"offset\": \"1\",\n \"stop-color\": \"#EFEFEF\"\n },\n \"children\": []\n }\n ]\n }\n ]\n },\n {\n \"tag\": \"path\",\n \"attrs\": {\n \"transform\": \"translate(19 20)\",\n \"fill-rule\": \"evenodd\",\n \"clip-rule\": \"evenodd\",\n \"d\": \"M0 10C0 4.47715 4.47715 0 10 0H60C65.5229 0 70 4.47715 70 10V70C70 75.5229 65.5229 80 60 80H10C4.47715 80 0 75.5229 0 70V10ZM16 17.5C16 16.1193 17.1193 15 18.5 15H50.5C51.8807 15 53 16.1193 53 17.5C53 18.8807 51.8807 20 50.5 20H18.5C17.1193 20 16 18.8807 16 17.5ZM18.5 32C17.1193 32 16 33.1193 16 34.5C16 35.8807 17.1193 37 18.5 37H50.5C51.8807 37 53 35.8807 53 34.5C53 33.1193 51.8807 32 50.5 32H18.5Z\",\n \"fill\": \"url(#doc)\"\n },\n \"children\": []\n },\n {\n \"tag\": \"g\",\n \"attrs\": {\n \"transform\": \"translate(66 75)\",\n \"fill\": \"url(#wifi)\"\n },\n \"children\": [\n {\n \"tag\": \"path\",\n \"attrs\": {\n \"d\": \"M17.5156 0C11.2706 0 5.34603 2.33603 0.796994 6.57058L0 7.31249L0.774158 8.07793L3.29835 10.5779L4.02532 11.297L4.77588 10.6095C8.25388 7.41396 12.7717 5.64852 17.5004 5.64852C22.2291 5.64852 26.7545 7.41396 30.2249 10.6095L30.9754 11.297L31.7016 10.5779L34.2266 8.07793L35 7.31249L34.203 6.56984C29.67 2.33676 23.737 0 17.5156 0Z\"\n },\n \"children\": []\n },\n {\n \"tag\": \"path\",\n \"attrs\": {\n \"d\": \"M28.5598 12.5317C25.5271 9.78909 21.6114 8.28174 17.5313 8.28174H16.8355L16.8279 8.29644C12.9822 8.45306 9.32459 9.94571 6.46393 12.5317L5.64258 13.2736L6.43196 14.0545L8.98813 16.5861L9.6991 17.2891L10.4497 16.6332C12.4273 14.8979 14.9363 13.9376 17.5077 13.9376C20.095 13.9376 22.604 14.8986 24.5809 16.6332L25.3315 17.2891L26.0424 16.5861L28.5986 14.0545L29.388 13.2736L28.5598 12.5317Z\"\n },\n \"children\": []\n },\n {\n \"tag\": \"path\",\n \"attrs\": {\n \"d\": \"M16.7999 24.2862C17.201 24.682 17.8458 24.6818 18.2466 24.2857L22.4014 20.1797L23.2296 19.3598L22.323 18.6172C21.1195 17.7275 19.7904 17.0547 17.5159 17.0547C15.2497 17.0547 14.0067 17.79 12.7095 18.6172L11.8105 19.3598L12.6388 20.1797L16.7999 24.2862Z\"\n },\n \"children\": []\n }\n ]\n }\n ]\n};\n","import { EMPTY_ILLUSTRATION_ASSET } from \"./empty-illustration.js\";\n\n/**\n * Empty 契约 — 原型 A(无状态),Core 为三栈结构与原有插画的唯一来源。\n * 本目录是 Empty 的\"源头锚点\":契约文档与 demo 清单在 ./docs/ 下维护,\n * 双栈实现(React props / Vue props+slots)必须与 docs 清单严格对齐。\n * 渲染契约:`data-scope=\"empty\"`,data-part 为 root / icon / title / description / actions。\n *\n * data-part 词表以运行时常量数组为唯一事实源(类型从常量推导),__test__ 直接锁死。\n */\n\n/** Empty 各渲染部位全集(data-part 取值),双栈与 styles-core 共用。 */\nexport const EMPTY_PARTS = [\"root\", \"icon\", \"title\", \"description\", \"actions\"] as const;\n\n/** Empty 各渲染部位(data-part 取值)。 */\nexport type EmptyPart = (typeof EMPTY_PARTS)[number];\n\n/** Scalar Empty inputs; framework-rich values use content presence. */\nexport interface QwEmptyProps {\n title?: string | null;\n description?: string | null;\n hideIcon?: boolean;\n}\n\n/** Content presence distinguishes omitted from explicitly empty SSR channels. */\nexport interface EmptyContentPresence {\n readonly icon?: boolean;\n readonly title?: boolean;\n readonly description?: boolean;\n readonly default?: boolean;\n}\n\n/** Shared passive structure decisions; no generated role or live region. */\nexport interface EmptyState {\n readonly iconMode: \"default\" | \"custom\" | \"hidden\";\n readonly hasTitle: boolean;\n readonly hasDescription: boolean;\n readonly hasActions: boolean;\n readonly titleFromContent: boolean;\n readonly descriptionFromContent: boolean;\n}\n\n/** Resolve structure once, with explicit channel presence overriding scalars. */\nexport function resolveEmptyState(props: QwEmptyProps = {}, presence: EmptyContentPresence = {}): EmptyState {\n return {\n iconMode: props.hideIcon === true ? \"hidden\" : presence.icon ? \"custom\" : \"default\",\n hasTitle: presence.title === true || props.title != null,\n hasDescription: presence.description === true || props.description != null,\n hasActions: presence.default === true,\n titleFromContent: presence.title === true,\n descriptionFromContent: presence.description === true,\n };\n}\n\n/** Plain passive Empty root. */\nexport function getEmptyRootProps() {\n return getEmptyPartProps(\"root\");\n}\n\n/** Shared stable selectors for Empty structure. */\nexport function getEmptyPartProps(part: EmptyPart) {\n return { \"data-scope\": \"empty\" as const, \"data-part\": part };\n}\n\n/** Framework-independent retained original vector asset. */\nexport interface EmptyVectorNode {\n readonly tag: string;\n readonly attrs: Readonly<Record<string, string>>;\n readonly children: readonly EmptyVectorNode[];\n}\n\n/** Copy the original illustration with injectively scoped local SVG references. */\nexport function getEmptyIllustration(identity: string): EmptyVectorNode {\n if (!identity.length) throw new Error(\"Empty illustration requires a nonempty stable identity\");\n let encoded = \"\";\n for (let index = 0; index < identity.length; index++) encoded += identity.charCodeAt(index).toString(16).padStart(4, \"0\");\n const prefix = `qw-empty-${encoded}-`;\n const copy = (source: EmptyVectorNode): EmptyVectorNode => ({\n tag: source.tag,\n attrs: Object.fromEntries(Object.entries(source.attrs).map(([key, value]) => [key, key === \"id\" ? `${prefix}${value}` : value.replace(/url\\(#(doc|wifi)\\)/g, (_original, local: string) => `url(#${prefix}${local})`)])),\n children: source.children.map(copy),\n });\n const vector = copy(EMPTY_ILLUSTRATION_ASSET);\n return { ...vector, attrs: { ...vector.attrs, focusable: \"false\" } };\n}\n"],"mappings":";AAGA,MAAa,2BAA4C;CACvD,OAAO;CACP,SAAS;EACP,WAAW;EACX,SAAS;EACT,UAAU;EACV,QAAQ;EACR,SAAS;EACT,eAAe;CACjB;CACA,YAAY;EACV;GACE,OAAO;GACP,SAAS,CAAC;GACV,YAAY,CACV;IACE,OAAO;IACP,SAAS;KACP,MAAM;KACN,MAAM;KACN,MAAM;KACN,MAAM;KACN,MAAM;KACN,iBAAiB;IACnB;IACA,YAAY,CACV;KACE,OAAO;KACP,SAAS;MACP,cAAc;MACd,gBAAgB;KAClB;KACA,YAAY,CAAC;IACf,GACA;KACE,OAAO;KACP,SAAS;MACP,UAAU;MACV,cAAc;MACd,gBAAgB;KAClB;KACA,YAAY,CAAC;IACf,CACF;GACF,GACA;IACE,OAAO;IACP,SAAS;KACP,MAAM;KACN,MAAM;KACN,MAAM;KACN,MAAM;KACN,MAAM;KACN,iBAAiB;IACnB;IACA,YAAY,CACV;KACE,OAAO;KACP,SAAS,EACP,cAAc,UAChB;KACA,YAAY,CAAC;IACf,GACA;KACE,OAAO;KACP,SAAS;MACP,UAAU;MACV,cAAc;KAChB;KACA,YAAY,CAAC;IACf,CACF;GACF,CACF;EACF;EACA;GACE,OAAO;GACP,SAAS;IACP,aAAa;IACb,aAAa;IACb,aAAa;IACb,KAAK;IACL,QAAQ;GACV;GACA,YAAY,CAAC;EACf;EACA;GACE,OAAO;GACP,SAAS;IACP,aAAa;IACb,QAAQ;GACV;GACA,YAAY;IACV;KACE,OAAO;KACP,SAAS,EACP,KAAK,6UACP;KACA,YAAY,CAAC;IACf;IACA;KACE,OAAO;KACP,SAAS,EACP,KAAK,wYACP;KACA,YAAY,CAAC;IACf;IACA;KACE,OAAO;KACP,SAAS,EACP,KAAK,+PACP;KACA,YAAY,CAAC;IACf;GACF;EACF;CACF;AACF;;;;;;;;;;;;AC5GA,MAAa,cAAc;CAAC;CAAQ;CAAQ;CAAS;CAAe;AAAS;;AA+B7E,SAAgB,kBAAkB,QAAsB,CAAC,GAAG,WAAiC,CAAC,GAAe;CAC3G,OAAO;EACL,UAAU,MAAM,aAAa,OAAO,WAAW,SAAS,OAAO,WAAW;EAC1E,UAAU,SAAS,UAAU,QAAQ,MAAM,SAAS;EACpD,gBAAgB,SAAS,gBAAgB,QAAQ,MAAM,eAAe;EACtE,YAAY,SAAS,YAAY;EACjC,kBAAkB,SAAS,UAAU;EACrC,wBAAwB,SAAS,gBAAgB;CACnD;AACF;;AAGA,SAAgB,oBAAoB;CAClC,OAAO,kBAAkB,MAAM;AACjC;;AAGA,SAAgB,kBAAkB,MAAiB;CACjD,OAAO;EAAE,cAAc;EAAkB,aAAa;CAAK;AAC7D;;AAUA,SAAgB,qBAAqB,UAAmC;CACtE,IAAI,CAAC,SAAS,QAAQ,MAAM,IAAI,MAAM,wDAAwD;CAC9F,IAAI,UAAU;CACd,KAAK,IAAI,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS,WAAW,SAAS,WAAW,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;CACxH,MAAM,SAAS,YAAY,QAAQ;CACnC,MAAM,QAAQ,YAA8C;EAC1D,KAAK,OAAO;EACZ,OAAO,OAAO,YAAY,OAAO,QAAQ,OAAO,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,QAAQ,OAAO,GAAG,SAAS,UAAU,MAAM,QAAQ,wBAAwB,WAAW,UAAkB,QAAQ,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;EACvN,UAAU,OAAO,SAAS,IAAI,IAAI;CACpC;CACA,MAAM,SAAS,KAAK,wBAAwB;CAC5C,OAAO;EAAE,GAAG;EAAQ,OAAO;GAAE,GAAG,OAAO;GAAO,WAAW;EAAQ;CAAE;AACrE"}