@threadlabs/looma 0.2.5 → 0.2.6

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 (427) hide show
  1. package/dist/chunk-3K45IWIJ.js +4733 -0
  2. package/dist/chunk-MLKGABMK.js +9 -0
  3. package/dist/chunk-UHHA4WT5.js +2916 -0
  4. package/dist/declarative-generated.cjs +135 -0
  5. package/dist/declarative-generated.d.cts +10 -0
  6. package/dist/declarative-generated.d.ts +10 -0
  7. package/dist/declarative-generated.js +111 -0
  8. package/dist/declarative.cjs +2944 -0
  9. package/dist/declarative.d.cts +27 -0
  10. package/dist/declarative.d.ts +27 -0
  11. package/dist/declarative.js +13 -0
  12. package/dist/index.cjs +7480 -6457
  13. package/dist/index.d.cts +4 -58
  14. package/dist/index.d.ts +4 -58
  15. package/dist/index.js +15 -27
  16. package/dist/loader.cjs +7654 -0
  17. package/dist/loader.d.cts +4 -0
  18. package/dist/loader.d.ts +4 -0
  19. package/dist/loader.js +16 -0
  20. package/dist/valibot.cjs +31 -0
  21. package/dist/valibot.d.cts +10 -0
  22. package/dist/valibot.d.ts +1 -43
  23. package/dist/valibot.js +2 -0
  24. package/dist/{types/field/validation.d.ts → validation-bxcou-l-.d.cts} +13 -11
  25. package/dist/validation-bxcou-l-.d.ts +58 -0
  26. package/editor/{chunk-B5WVJOPV.js → chunk-BXICJBWS.js} +118 -8
  27. package/editor/{chunk-ZOUKEZ77.js → chunk-JK53ENSG.js} +8 -21
  28. package/editor/chunk-WI7ZA44X.js +2558 -0
  29. package/editor/extensions/index.d.ts +11 -2
  30. package/editor/extensions/index.js +9 -7
  31. package/editor/index.d.ts +1 -1
  32. package/editor/index.js +10 -8
  33. package/editor/ui.js +2 -2
  34. package/editor.css +32 -0
  35. package/layout/index.cjs +466 -400
  36. package/layout/index.d.cts +1 -2
  37. package/layout/index.d.ts +1 -2
  38. package/layout/index.js +471 -395
  39. package/package.json +14 -5
  40. package/vue/chunk-4DPYH3IT.js +3538 -0
  41. package/vue/editor/index.d.ts +17 -7
  42. package/vue/editor/index.js +53 -35
  43. package/vue/index.d.ts +48 -31
  44. package/vue/index.js +1 -1
  45. package/dist/chunk-24OTMNIU.js +0 -1617
  46. package/dist/chunk-D5WRORG6.js +0 -366
  47. package/dist/chunk-HNFCGIBP.js +0 -8
  48. package/dist/chunk-NB6DBRXQ.js +0 -323
  49. package/dist/chunk-OF57X5AR.js +0 -10
  50. package/dist/chunk-TL4FIE7X.js +0 -93
  51. package/dist/chunk-UL7UIUJZ.js +0 -20
  52. package/dist/cjs/app-globals-V2Kpy_OQ.js +0 -5
  53. package/dist/cjs/controlled-state-BFya8rAX.js +0 -9
  54. package/dist/cjs/events-TcQIzpNv.js +0 -19
  55. package/dist/cjs/icons-BAdjrnhS.js +0 -680
  56. package/dist/cjs/id-CYbKpaYr.js +0 -9
  57. package/dist/cjs/index-BHG9Rpil.js +0 -1602
  58. package/dist/cjs/index.cjs.js +0 -2
  59. package/dist/cjs/loader.cjs.js +0 -13
  60. package/dist/cjs/looma.cjs.js +0 -25
  61. package/dist/cjs/manager-Ce25WRtl.js +0 -95
  62. package/dist/cjs/positioning-CCR6ifPj.js +0 -426
  63. package/dist/cjs/ui-affordance-scope.cjs.entry.js +0 -43
  64. package/dist/cjs/ui-avatar-group.cjs.entry.js +0 -43
  65. package/dist/cjs/ui-avatar.cjs.entry.js +0 -50
  66. package/dist/cjs/ui-badge.cjs.entry.js +0 -19
  67. package/dist/cjs/ui-button.cjs.entry.js +0 -75
  68. package/dist/cjs/ui-callout.cjs.entry.js +0 -27
  69. package/dist/cjs/ui-checkbox.cjs.entry.js +0 -97
  70. package/dist/cjs/ui-chip_2.cjs.entry.js +0 -258
  71. package/dist/cjs/ui-combobox.cjs.entry.js +0 -708
  72. package/dist/cjs/ui-context-menu.cjs.entry.js +0 -239
  73. package/dist/cjs/ui-dialog.cjs.entry.js +0 -131
  74. package/dist/cjs/ui-disclosure.cjs.entry.js +0 -112
  75. package/dist/cjs/ui-editable.cjs.entry.js +0 -100
  76. package/dist/cjs/ui-floating-action-button.cjs.entry.js +0 -20
  77. package/dist/cjs/ui-form-field.cjs.entry.js +0 -114
  78. package/dist/cjs/ui-icon-button.cjs.entry.js +0 -23
  79. package/dist/cjs/ui-input.cjs.entry.js +0 -106
  80. package/dist/cjs/ui-menu-item.cjs.entry.js +0 -19
  81. package/dist/cjs/ui-menu.cjs.entry.js +0 -182
  82. package/dist/cjs/ui-popover.cjs.entry.js +0 -135
  83. package/dist/cjs/ui-radio-group.cjs.entry.js +0 -134
  84. package/dist/cjs/ui-radio.cjs.entry.js +0 -94
  85. package/dist/cjs/ui-search-result-row.cjs.entry.js +0 -47
  86. package/dist/cjs/ui-search-shell.cjs.entry.js +0 -39
  87. package/dist/cjs/ui-select.cjs.entry.js +0 -108
  88. package/dist/cjs/ui-switch.cjs.entry.js +0 -74
  89. package/dist/cjs/ui-tabs.cjs.entry.js +0 -118
  90. package/dist/cjs/ui-textarea.cjs.entry.js +0 -110
  91. package/dist/cjs/ui-toast-region.cjs.entry.js +0 -93
  92. package/dist/cjs/ui-top-bar.cjs.entry.js +0 -43
  93. package/dist/cjs/ui-tree-item.cjs.entry.js +0 -135
  94. package/dist/cjs/ui-tree.cjs.entry.js +0 -500
  95. package/dist/collection/collection-manifest.json +0 -45
  96. package/dist/collection/components/ui-affordance-scope/ui-affordance-scope.css +0 -8
  97. package/dist/collection/components/ui-affordance-scope/ui-affordance-scope.js +0 -70
  98. package/dist/collection/components/ui-avatar/ui-avatar.css +0 -35
  99. package/dist/collection/components/ui-avatar/ui-avatar.js +0 -130
  100. package/dist/collection/components/ui-avatar-group/ui-avatar-group.css +0 -32
  101. package/dist/collection/components/ui-avatar-group/ui-avatar-group.js +0 -95
  102. package/dist/collection/components/ui-badge/ui-badge.css +0 -90
  103. package/dist/collection/components/ui-badge/ui-badge.js +0 -62
  104. package/dist/collection/components/ui-button/ui-button.css +0 -121
  105. package/dist/collection/components/ui-button/ui-button.js +0 -141
  106. package/dist/collection/components/ui-callout/ui-callout.css +0 -74
  107. package/dist/collection/components/ui-callout/ui-callout.js +0 -59
  108. package/dist/collection/components/ui-checkbox/ui-checkbox.css +0 -24
  109. package/dist/collection/components/ui-checkbox/ui-checkbox.js +0 -228
  110. package/dist/collection/components/ui-chip/ui-chip.css +0 -57
  111. package/dist/collection/components/ui-chip/ui-chip.js +0 -67
  112. package/dist/collection/components/ui-combobox/ui-combobox.css +0 -47
  113. package/dist/collection/components/ui-combobox/ui-combobox.js +0 -1295
  114. package/dist/collection/components/ui-context-menu/ui-context-menu.css +0 -34
  115. package/dist/collection/components/ui-context-menu/ui-context-menu.js +0 -311
  116. package/dist/collection/components/ui-dialog/ui-dialog.css +0 -72
  117. package/dist/collection/components/ui-dialog/ui-dialog.js +0 -242
  118. package/dist/collection/components/ui-disclosure/ui-disclosure.css +0 -7
  119. package/dist/collection/components/ui-disclosure/ui-disclosure.js +0 -184
  120. package/dist/collection/components/ui-editable/ui-editable.css +0 -2
  121. package/dist/collection/components/ui-editable/ui-editable.js +0 -196
  122. package/dist/collection/components/ui-floating-action-button/ui-floating-action-button.css +0 -73
  123. package/dist/collection/components/ui-floating-action-button/ui-floating-action-button.js +0 -85
  124. package/dist/collection/components/ui-form-field/ui-form-field.css +0 -25
  125. package/dist/collection/components/ui-form-field/ui-form-field.js +0 -180
  126. package/dist/collection/components/ui-icon-button/ui-icon-button.css +0 -145
  127. package/dist/collection/components/ui-icon-button/ui-icon-button.js +0 -128
  128. package/dist/collection/components/ui-input/ui-input.css +0 -48
  129. package/dist/collection/components/ui-input/ui-input.js +0 -217
  130. package/dist/collection/components/ui-menu/ui-menu.css +0 -73
  131. package/dist/collection/components/ui-menu/ui-menu.js +0 -280
  132. package/dist/collection/components/ui-menu-item/ui-menu-item.css +0 -32
  133. package/dist/collection/components/ui-menu-item/ui-menu-item.js +0 -64
  134. package/dist/collection/components/ui-popover/ui-popover.css +0 -58
  135. package/dist/collection/components/ui-popover/ui-popover.js +0 -232
  136. package/dist/collection/components/ui-radio/ui-radio.css +0 -22
  137. package/dist/collection/components/ui-radio/ui-radio.js +0 -226
  138. package/dist/collection/components/ui-radio-group/ui-radio-group.css +0 -10
  139. package/dist/collection/components/ui-radio-group/ui-radio-group.js +0 -247
  140. package/dist/collection/components/ui-search-result-row/ui-search-result-row.css +0 -80
  141. package/dist/collection/components/ui-search-result-row/ui-search-result-row.js +0 -100
  142. package/dist/collection/components/ui-search-shell/ui-search-shell.css +0 -63
  143. package/dist/collection/components/ui-search-shell/ui-search-shell.js +0 -46
  144. package/dist/collection/components/ui-select/ui-select.css +0 -64
  145. package/dist/collection/components/ui-select/ui-select.js +0 -218
  146. package/dist/collection/components/ui-switch/ui-switch.css +0 -63
  147. package/dist/collection/components/ui-switch/ui-switch.js +0 -185
  148. package/dist/collection/components/ui-tabs/ui-tabs.css +0 -68
  149. package/dist/collection/components/ui-tabs/ui-tabs.js +0 -190
  150. package/dist/collection/components/ui-textarea/ui-textarea.css +0 -49
  151. package/dist/collection/components/ui-textarea/ui-textarea.js +0 -241
  152. package/dist/collection/components/ui-toast-region/ui-toast-region.css +0 -59
  153. package/dist/collection/components/ui-toast-region/ui-toast-region.js +0 -126
  154. package/dist/collection/components/ui-tooltip/ui-tooltip.css +0 -43
  155. package/dist/collection/components/ui-tooltip/ui-tooltip.js +0 -430
  156. package/dist/collection/components/ui-top-bar/ui-top-bar.css +0 -51
  157. package/dist/collection/components/ui-top-bar/ui-top-bar.js +0 -52
  158. package/dist/collection/components/ui-tree/ui-tree.css +0 -12
  159. package/dist/collection/components/ui-tree/ui-tree.js +0 -515
  160. package/dist/collection/components/ui-tree-item/ui-tree-item.css +0 -217
  161. package/dist/collection/components/ui-tree-item/ui-tree-item.js +0 -406
  162. package/dist/collection/field/combobox.js +0 -4
  163. package/dist/collection/field/editable.js +0 -1
  164. package/dist/collection/field/multi-combobox.js +0 -1
  165. package/dist/collection/field/valibot.js +0 -5
  166. package/dist/collection/field/validation.js +0 -62
  167. package/dist/collection/icons.js +0 -71
  168. package/dist/collection/input-modality.js +0 -24
  169. package/dist/collection/overlay/manager.js +0 -92
  170. package/dist/collection/overlay/positioning.js +0 -424
  171. package/dist/collection/utils/controlled-state.js +0 -4
  172. package/dist/collection/utils/drag-drop.js +0 -51
  173. package/dist/collection/utils/events.js +0 -13
  174. package/dist/collection/utils/id.js +0 -5
  175. package/dist/collection/utils/initials.js +0 -11
  176. package/dist/components/index.d.ts +0 -102
  177. package/dist/components/index.js +0 -1
  178. package/dist/components/p-6SWSrfmW.js +0 -1
  179. package/dist/components/p-B_DaIVEY.js +0 -1
  180. package/dist/components/p-Bh_1GxOD.js +0 -1
  181. package/dist/components/p-BnGhGgTH.js +0 -1
  182. package/dist/components/p-BzaB_bXo.js +0 -1
  183. package/dist/components/p-C-0syqXZ.js +0 -1
  184. package/dist/components/p-CoFximGM.js +0 -13
  185. package/dist/components/p-JwSoedEO.js +0 -1
  186. package/dist/components/p-Vc4ExHFc.js +0 -1
  187. package/dist/components/p-hgBUJRDa.js +0 -1
  188. package/dist/components/ui-affordance-scope.d.ts +0 -11
  189. package/dist/components/ui-affordance-scope.js +0 -1
  190. package/dist/components/ui-avatar-group.d.ts +0 -11
  191. package/dist/components/ui-avatar-group.js +0 -1
  192. package/dist/components/ui-avatar.d.ts +0 -11
  193. package/dist/components/ui-avatar.js +0 -1
  194. package/dist/components/ui-badge.d.ts +0 -11
  195. package/dist/components/ui-badge.js +0 -1
  196. package/dist/components/ui-button.d.ts +0 -11
  197. package/dist/components/ui-button.js +0 -1
  198. package/dist/components/ui-callout.d.ts +0 -11
  199. package/dist/components/ui-callout.js +0 -1
  200. package/dist/components/ui-checkbox.d.ts +0 -11
  201. package/dist/components/ui-checkbox.js +0 -1
  202. package/dist/components/ui-chip.d.ts +0 -11
  203. package/dist/components/ui-chip.js +0 -1
  204. package/dist/components/ui-combobox.d.ts +0 -11
  205. package/dist/components/ui-combobox.js +0 -1
  206. package/dist/components/ui-context-menu.d.ts +0 -11
  207. package/dist/components/ui-context-menu.js +0 -1
  208. package/dist/components/ui-dialog.d.ts +0 -11
  209. package/dist/components/ui-dialog.js +0 -1
  210. package/dist/components/ui-disclosure.d.ts +0 -11
  211. package/dist/components/ui-disclosure.js +0 -1
  212. package/dist/components/ui-editable.d.ts +0 -11
  213. package/dist/components/ui-editable.js +0 -1
  214. package/dist/components/ui-floating-action-button.d.ts +0 -11
  215. package/dist/components/ui-floating-action-button.js +0 -1
  216. package/dist/components/ui-form-field.d.ts +0 -11
  217. package/dist/components/ui-form-field.js +0 -1
  218. package/dist/components/ui-icon-button.d.ts +0 -11
  219. package/dist/components/ui-icon-button.js +0 -1
  220. package/dist/components/ui-input.d.ts +0 -11
  221. package/dist/components/ui-input.js +0 -1
  222. package/dist/components/ui-menu-item.d.ts +0 -11
  223. package/dist/components/ui-menu-item.js +0 -1
  224. package/dist/components/ui-menu.d.ts +0 -11
  225. package/dist/components/ui-menu.js +0 -1
  226. package/dist/components/ui-popover.d.ts +0 -11
  227. package/dist/components/ui-popover.js +0 -1
  228. package/dist/components/ui-radio-group.d.ts +0 -11
  229. package/dist/components/ui-radio-group.js +0 -1
  230. package/dist/components/ui-radio.d.ts +0 -11
  231. package/dist/components/ui-radio.js +0 -1
  232. package/dist/components/ui-search-result-row.d.ts +0 -11
  233. package/dist/components/ui-search-result-row.js +0 -1
  234. package/dist/components/ui-search-shell.d.ts +0 -11
  235. package/dist/components/ui-search-shell.js +0 -1
  236. package/dist/components/ui-select.d.ts +0 -11
  237. package/dist/components/ui-select.js +0 -1
  238. package/dist/components/ui-switch.d.ts +0 -11
  239. package/dist/components/ui-switch.js +0 -1
  240. package/dist/components/ui-tabs.d.ts +0 -11
  241. package/dist/components/ui-tabs.js +0 -1
  242. package/dist/components/ui-textarea.d.ts +0 -11
  243. package/dist/components/ui-textarea.js +0 -1
  244. package/dist/components/ui-toast-region.d.ts +0 -11
  245. package/dist/components/ui-toast-region.js +0 -1
  246. package/dist/components/ui-tooltip.d.ts +0 -11
  247. package/dist/components/ui-tooltip.js +0 -1
  248. package/dist/components/ui-top-bar.d.ts +0 -11
  249. package/dist/components/ui-top-bar.js +0 -1
  250. package/dist/components/ui-tree-item.d.ts +0 -11
  251. package/dist/components/ui-tree-item.js +0 -1
  252. package/dist/components/ui-tree.d.ts +0 -11
  253. package/dist/components/ui-tree.js +0 -1
  254. package/dist/esm/app-globals-DQuL1Twl.js +0 -3
  255. package/dist/esm/controlled-state-BnGhGgTH.js +0 -6
  256. package/dist/esm/events-JwSoedEO.js +0 -15
  257. package/dist/esm/icons-CoFximGM.js +0 -678
  258. package/dist/esm/id-hgBUJRDa.js +0 -7
  259. package/dist/esm/index-8BGiMGQ0.js +0 -1593
  260. package/dist/esm/index.js +0 -1
  261. package/dist/esm/loader.js +0 -11
  262. package/dist/esm/looma.js +0 -21
  263. package/dist/esm/manager-C-0syqXZ.js +0 -91
  264. package/dist/esm/positioning-ZOr-2PSe.js +0 -421
  265. package/dist/esm/ui-affordance-scope.entry.js +0 -41
  266. package/dist/esm/ui-avatar-group.entry.js +0 -41
  267. package/dist/esm/ui-avatar.entry.js +0 -48
  268. package/dist/esm/ui-badge.entry.js +0 -17
  269. package/dist/esm/ui-button.entry.js +0 -73
  270. package/dist/esm/ui-callout.entry.js +0 -25
  271. package/dist/esm/ui-checkbox.entry.js +0 -95
  272. package/dist/esm/ui-chip_2.entry.js +0 -255
  273. package/dist/esm/ui-combobox.entry.js +0 -706
  274. package/dist/esm/ui-context-menu.entry.js +0 -237
  275. package/dist/esm/ui-dialog.entry.js +0 -129
  276. package/dist/esm/ui-disclosure.entry.js +0 -110
  277. package/dist/esm/ui-editable.entry.js +0 -98
  278. package/dist/esm/ui-floating-action-button.entry.js +0 -18
  279. package/dist/esm/ui-form-field.entry.js +0 -112
  280. package/dist/esm/ui-icon-button.entry.js +0 -21
  281. package/dist/esm/ui-input.entry.js +0 -104
  282. package/dist/esm/ui-menu-item.entry.js +0 -17
  283. package/dist/esm/ui-menu.entry.js +0 -180
  284. package/dist/esm/ui-popover.entry.js +0 -133
  285. package/dist/esm/ui-radio-group.entry.js +0 -132
  286. package/dist/esm/ui-radio.entry.js +0 -92
  287. package/dist/esm/ui-search-result-row.entry.js +0 -45
  288. package/dist/esm/ui-search-shell.entry.js +0 -37
  289. package/dist/esm/ui-select.entry.js +0 -106
  290. package/dist/esm/ui-switch.entry.js +0 -72
  291. package/dist/esm/ui-tabs.entry.js +0 -116
  292. package/dist/esm/ui-textarea.entry.js +0 -108
  293. package/dist/esm/ui-toast-region.entry.js +0 -91
  294. package/dist/esm/ui-top-bar.entry.js +0 -41
  295. package/dist/esm/ui-tree-item.entry.js +0 -133
  296. package/dist/esm/ui-tree.entry.js +0 -498
  297. package/dist/index.cjs.js +0 -1
  298. package/dist/looma/index.esm.js +0 -0
  299. package/dist/looma/looma.esm.js +0 -1
  300. package/dist/looma/p-08f80207.entry.js +0 -1
  301. package/dist/looma/p-0b5b8d9e.entry.js +0 -1
  302. package/dist/looma/p-1249a806.entry.js +0 -1
  303. package/dist/looma/p-16e0669d.entry.js +0 -1
  304. package/dist/looma/p-1c00670f.entry.js +0 -1
  305. package/dist/looma/p-1c5a7522.entry.js +0 -1
  306. package/dist/looma/p-22842f8c.entry.js +0 -1
  307. package/dist/looma/p-2915d5c0.entry.js +0 -1
  308. package/dist/looma/p-3b2961a6.entry.js +0 -1
  309. package/dist/looma/p-3f60f4c8.entry.js +0 -1
  310. package/dist/looma/p-424d6719.entry.js +0 -1
  311. package/dist/looma/p-4caccfce.entry.js +0 -1
  312. package/dist/looma/p-5fdcee1d.entry.js +0 -1
  313. package/dist/looma/p-6d8b99ee.entry.js +0 -1
  314. package/dist/looma/p-6f20d470.entry.js +0 -1
  315. package/dist/looma/p-7c0b5364.entry.js +0 -1
  316. package/dist/looma/p-8BGiMGQ0.js +0 -2
  317. package/dist/looma/p-8bdd9495.entry.js +0 -1
  318. package/dist/looma/p-99116a72.entry.js +0 -1
  319. package/dist/looma/p-9cfbf722.entry.js +0 -1
  320. package/dist/looma/p-9d2662ca.entry.js +0 -1
  321. package/dist/looma/p-9ff2fa19.entry.js +0 -1
  322. package/dist/looma/p-BnGhGgTH.js +0 -1
  323. package/dist/looma/p-C-0syqXZ.js +0 -1
  324. package/dist/looma/p-CoFximGM.js +0 -13
  325. package/dist/looma/p-DQuL1Twl.js +0 -1
  326. package/dist/looma/p-JwSoedEO.js +0 -1
  327. package/dist/looma/p-ZOr-2PSe.js +0 -1
  328. package/dist/looma/p-a2dd4c6c.entry.js +0 -1
  329. package/dist/looma/p-add67e4c.entry.js +0 -1
  330. package/dist/looma/p-b6ede6bb.entry.js +0 -1
  331. package/dist/looma/p-b76e2111.entry.js +0 -1
  332. package/dist/looma/p-ca2a54fd.entry.js +0 -1
  333. package/dist/looma/p-d372b0db.entry.js +0 -1
  334. package/dist/looma/p-d4825822.entry.js +0 -1
  335. package/dist/looma/p-d56571a2.entry.js +0 -1
  336. package/dist/looma/p-d5c3954f.entry.js +0 -1
  337. package/dist/looma/p-e604e906.entry.js +0 -1
  338. package/dist/looma/p-f1f7c5cb.entry.js +0 -1
  339. package/dist/looma/p-hgBUJRDa.js +0 -1
  340. package/dist/types/components/ui-affordance-scope/ui-affordance-scope.d.ts +0 -11
  341. package/dist/types/components/ui-avatar/ui-avatar.d.ts +0 -11
  342. package/dist/types/components/ui-avatar-group/ui-avatar-group.d.ts +0 -11
  343. package/dist/types/components/ui-badge/ui-badge.d.ts +0 -5
  344. package/dist/types/components/ui-button/ui-button.d.ts +0 -13
  345. package/dist/types/components/ui-callout/ui-callout.d.ts +0 -6
  346. package/dist/types/components/ui-checkbox/ui-checkbox.d.ts +0 -20
  347. package/dist/types/components/ui-chip/ui-chip.d.ts +0 -8
  348. package/dist/types/components/ui-combobox/ui-combobox.d.ts +0 -128
  349. package/dist/types/components/ui-context-menu/ui-context-menu.d.ts +0 -43
  350. package/dist/types/components/ui-dialog/ui-dialog.d.ts +0 -27
  351. package/dist/types/components/ui-disclosure/ui-disclosure.d.ts +0 -21
  352. package/dist/types/components/ui-editable/ui-editable.d.ts +0 -24
  353. package/dist/types/components/ui-floating-action-button/ui-floating-action-button.d.ts +0 -6
  354. package/dist/types/components/ui-form-field/ui-form-field.d.ts +0 -18
  355. package/dist/types/components/ui-icon-button/ui-icon-button.d.ts +0 -9
  356. package/dist/types/components/ui-input/ui-input.d.ts +0 -19
  357. package/dist/types/components/ui-menu/ui-menu.d.ts +0 -28
  358. package/dist/types/components/ui-menu-item/ui-menu-item.d.ts +0 -5
  359. package/dist/types/components/ui-popover/ui-popover.d.ts +0 -26
  360. package/dist/types/components/ui-radio/ui-radio.d.ts +0 -20
  361. package/dist/types/components/ui-radio-group/ui-radio-group.d.ts +0 -21
  362. package/dist/types/components/ui-search-result-row/ui-search-result-row.d.ts +0 -15
  363. package/dist/types/components/ui-search-shell/ui-search-shell.d.ts +0 -9
  364. package/dist/types/components/ui-select/ui-select.d.ts +0 -20
  365. package/dist/types/components/ui-switch/ui-switch.d.ts +0 -16
  366. package/dist/types/components/ui-tabs/ui-tabs.d.ts +0 -18
  367. package/dist/types/components/ui-textarea/ui-textarea.d.ts +0 -20
  368. package/dist/types/components/ui-toast-region/ui-toast-region.d.ts +0 -16
  369. package/dist/types/components/ui-tooltip/ui-tooltip.d.ts +0 -57
  370. package/dist/types/components/ui-top-bar/ui-top-bar.d.ts +0 -12
  371. package/dist/types/components/ui-tree/ui-tree.d.ts +0 -53
  372. package/dist/types/components/ui-tree-item/ui-tree-item.d.ts +0 -44
  373. package/dist/types/components.d.ts +0 -1889
  374. package/dist/types/field/combobox.d.ts +0 -46
  375. package/dist/types/field/editable.d.ts +0 -5
  376. package/dist/types/field/multi-combobox.d.ts +0 -11
  377. package/dist/types/field/valibot.d.ts +0 -7
  378. package/dist/types/icons.d.ts +0 -53
  379. package/dist/types/input-modality.d.ts +0 -6
  380. package/dist/types/overlay/manager.d.ts +0 -17
  381. package/dist/types/overlay/positioning.d.ts +0 -74
  382. package/dist/types/stencil-public-runtime.d.ts +0 -1860
  383. package/dist/types/utils/controlled-state.d.ts +0 -4
  384. package/dist/types/utils/drag-drop.d.ts +0 -15
  385. package/dist/types/utils/events.d.ts +0 -4
  386. package/dist/types/utils/id.d.ts +0 -1
  387. package/dist/types/utils/initials.d.ts +0 -1
  388. package/dist/ui-affordance-scope.entry-L6TIXYOP.js +0 -54
  389. package/dist/ui-avatar-group.entry-TCAA6P72.js +0 -51
  390. package/dist/ui-avatar.entry-52DQ7VXA.js +0 -51
  391. package/dist/ui-badge.entry-2XCAA6LL.js +0 -22
  392. package/dist/ui-button.entry-MNFBMNSX.js +0 -83
  393. package/dist/ui-callout.entry-SSHT5TH2.js +0 -32
  394. package/dist/ui-checkbox.entry-LOWIWIWI.js +0 -111
  395. package/dist/ui-chip_2.entry-BIMTSF6C.js +0 -272
  396. package/dist/ui-combobox.entry-25Z4MN7N.js +0 -717
  397. package/dist/ui-context-menu.entry-YZDL5Y4M.js +0 -248
  398. package/dist/ui-dialog.entry-HIXZX5AB.js +0 -146
  399. package/dist/ui-disclosure.entry-2JZHZNDQ.js +0 -126
  400. package/dist/ui-editable.entry-U3VR3XPT.js +0 -110
  401. package/dist/ui-floating-action-button.entry-6S3QN3KJ.js +0 -23
  402. package/dist/ui-form-field.entry-GQOSMLHT.js +0 -120
  403. package/dist/ui-icon-button.entry-QJXKVDM6.js +0 -26
  404. package/dist/ui-input.entry-UWMQ6JMP.js +0 -114
  405. package/dist/ui-menu-item.entry-NHNZKKJS.js +0 -22
  406. package/dist/ui-menu.entry-D53RUJND.js +0 -192
  407. package/dist/ui-popover.entry-7ZSIWCFQ.js +0 -152
  408. package/dist/ui-radio-group.entry-37MSYIH4.js +0 -142
  409. package/dist/ui-radio.entry-7YGCDHXT.js +0 -108
  410. package/dist/ui-search-result-row.entry-6FCCLGAS.js +0 -50
  411. package/dist/ui-search-shell.entry-HSBEXPER.js +0 -41
  412. package/dist/ui-select.entry-GIDIAYRD.js +0 -117
  413. package/dist/ui-switch.entry-MYAL6XPC.js +0 -87
  414. package/dist/ui-tabs.entry-R4TEXQSD.js +0 -128
  415. package/dist/ui-textarea.entry-FW32JNDV.js +0 -119
  416. package/dist/ui-toast-region.entry-BTMFPKZF.js +0 -104
  417. package/dist/ui-top-bar.entry-5DQGJF3B.js +0 -49
  418. package/dist/ui-tree-item.entry-ADT7DSOS.js +0 -145
  419. package/dist/ui-tree.entry-7PYQ5RIN.js +0 -470
  420. package/editor/chunk-64GLF274.js +0 -1271
  421. package/layout/index.css +0 -387
  422. package/loader/cdn.js +0 -1
  423. package/loader/index.cjs.js +0 -1
  424. package/loader/index.d.ts +0 -24
  425. package/loader/index.es2017.js +0 -1
  426. package/loader/index.js +0 -2
  427. package/vue/chunk-ROMBQS2L.js +0 -352
@@ -0,0 +1,4733 @@
1
+ import {
2
+ __export
3
+ } from "./chunk-MLKGABMK.js";
4
+
5
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-affordance-scope.js
6
+ var ui_affordance_scope_exports = {};
7
+ __export(ui_affordance_scope_exports, {
8
+ default: () => controller
9
+ });
10
+ function distance(point, rect) {
11
+ const dx = Math.max(rect.left - point.x, 0, point.x - rect.right);
12
+ const dy = Math.max(rect.top - point.y, 0, point.y - rect.bottom);
13
+ return Math.hypot(dx, dy);
14
+ }
15
+ function controller(host) {
16
+ const element = host.element;
17
+ const owner = element.ownerDocument.defaultView;
18
+ let anchors = [];
19
+ let frame = null;
20
+ let point = null;
21
+ let dirty = false;
22
+ let nearRadius = Number(host.state.nearRadius ?? 16);
23
+ const clear = () => {
24
+ for (const anchor of anchors) anchor.element.removeAttribute("data-ui-proximity");
25
+ element.removeAttribute("data-ui-interaction");
26
+ };
27
+ const measure = () => {
28
+ anchors = Array.from(element.querySelectorAll("[data-ui-affordance]")).filter((anchor) => !anchor.hasAttribute("disabled") && anchor.getAttribute("aria-disabled") !== "true").map((anchor) => ({ element: anchor, rect: anchor.getBoundingClientRect() }));
29
+ dirty = false;
30
+ };
31
+ const update = () => {
32
+ frame = null;
33
+ if (dirty) measure();
34
+ if (!point) {
35
+ clear();
36
+ return;
37
+ }
38
+ let engaged = false;
39
+ for (const anchor of anchors) {
40
+ const near = distance(point, anchor.rect) <= nearRadius;
41
+ anchor.element.toggleAttribute("data-ui-proximity", near);
42
+ if (near) anchor.element.setAttribute("data-ui-proximity", "near");
43
+ engaged ||= near;
44
+ }
45
+ if (engaged) element.setAttribute("data-ui-interaction", "engaged");
46
+ else element.removeAttribute("data-ui-interaction");
47
+ };
48
+ const schedule = () => {
49
+ if (frame === null) frame = owner.requestAnimationFrame(update);
50
+ };
51
+ const invalidate = () => {
52
+ dirty = true;
53
+ schedule();
54
+ };
55
+ const onPointermove = (event) => {
56
+ point = event.pointerType === "touch" ? null : { x: event.clientX, y: event.clientY };
57
+ schedule();
58
+ };
59
+ const observer = new MutationObserver(invalidate);
60
+ observer.observe(element, { childList: true, subtree: true, attributes: true, attributeFilter: ["data-ui-affordance", "disabled", "aria-disabled"] });
61
+ element.addEventListener("pointermove", onPointermove, { passive: true });
62
+ owner.addEventListener("resize", invalidate, { passive: true });
63
+ owner.addEventListener("scroll", invalidate, { passive: true, capture: true });
64
+ owner.visualViewport?.addEventListener("resize", invalidate, { passive: true });
65
+ owner.visualViewport?.addEventListener("scroll", invalidate, { passive: true });
66
+ const stop = host.effect(() => {
67
+ const configured = Number(host.state.nearRadius ?? 16);
68
+ nearRadius = Number.isFinite(configured) ? Math.max(0, configured) : 16;
69
+ invalidate();
70
+ });
71
+ measure();
72
+ return () => {
73
+ stop();
74
+ observer.disconnect();
75
+ element.removeEventListener("pointermove", onPointermove);
76
+ owner.removeEventListener("resize", invalidate);
77
+ owner.removeEventListener("scroll", invalidate, true);
78
+ owner.visualViewport?.removeEventListener("resize", invalidate);
79
+ owner.visualViewport?.removeEventListener("scroll", invalidate);
80
+ if (frame !== null) owner.cancelAnimationFrame(frame);
81
+ clear();
82
+ };
83
+ }
84
+
85
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-avatar-group.js
86
+ var ui_avatar_group_exports = {};
87
+ __export(ui_avatar_group_exports, {
88
+ default: () => controller2
89
+ });
90
+ function controller2(host) {
91
+ const el = host.element;
92
+ const limit = () => {
93
+ const m = Number(host.state.max);
94
+ return Number.isFinite(m) ? Math.max(0, Math.floor(m)) : 0;
95
+ };
96
+ const update = () => {
97
+ const children = [...el.children].filter((c) => !c.hasAttribute("data-ui-avatar-group-overflow"));
98
+ const visible = limit();
99
+ children.forEach((c, i) => {
100
+ c.style.display = i >= visible ? "none" : "";
101
+ });
102
+ const overflow = children.length > visible ? children.length - visible : 0;
103
+ let badge = el.querySelector("[data-ui-avatar-group-overflow]");
104
+ if (overflow > 0) {
105
+ if (badge === null) {
106
+ badge = el.ownerDocument.createElement("span");
107
+ badge.className = "overflow";
108
+ badge.setAttribute("role", "img");
109
+ badge.setAttribute("data-ui-avatar-group-overflow", "");
110
+ el.appendChild(badge);
111
+ }
112
+ badge.textContent = `+${overflow}`;
113
+ badge.setAttribute("aria-label", `${overflow} more ${overflow === 1 ? "person" : "people"}`);
114
+ } else if (badge !== null) {
115
+ badge.remove();
116
+ }
117
+ };
118
+ const observer = new MutationObserver(update);
119
+ observer.observe(el, { childList: true });
120
+ const stop = host.effect(update);
121
+ update();
122
+ return () => {
123
+ stop?.();
124
+ observer.disconnect();
125
+ };
126
+ }
127
+
128
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-avatar.js
129
+ var ui_avatar_exports = {};
130
+ __export(ui_avatar_exports, {
131
+ default: () => controller3
132
+ });
133
+ function toInitials(value) {
134
+ const tokens = (value || "").trim().split(/\s+/).filter((t) => t.length > 0);
135
+ if (tokens.length === 0) return "?";
136
+ if (tokens.length === 1) return tokens[0].slice(0, 2).toUpperCase();
137
+ return `${tokens[0][0] ?? ""}${tokens[1][0] ?? ""}`.toUpperCase();
138
+ }
139
+ function controller3(host) {
140
+ const img = host.element.querySelector("img");
141
+ const fallback = host.element.querySelector(".fallback");
142
+ let hasImage = false;
143
+ const apply = () => {
144
+ const label = host.state.alt || host.state.name || "Avatar";
145
+ host.element.setAttribute("role", "img");
146
+ host.element.setAttribute("aria-label", label);
147
+ if (fallback) fallback.textContent = host.state.fallback || toInitials(host.state.name || host.state.alt);
148
+ if (img) {
149
+ img.src = host.state.src || "";
150
+ img.alt = label;
151
+ img.hidden = !hasImage;
152
+ img.setAttribute("aria-hidden", hasImage ? "false" : "true");
153
+ }
154
+ if (fallback) {
155
+ fallback.hidden = hasImage;
156
+ fallback.setAttribute("aria-hidden", hasImage ? "true" : "false");
157
+ }
158
+ if (hasImage) host.element.setAttribute("data-has-image", "");
159
+ else host.element.removeAttribute("data-has-image");
160
+ };
161
+ const onLoad = () => {
162
+ hasImage = true;
163
+ apply();
164
+ };
165
+ const onError = () => {
166
+ hasImage = false;
167
+ apply();
168
+ };
169
+ img?.addEventListener("load", onLoad);
170
+ img?.addEventListener("error", onError);
171
+ const stop = host.effect(apply);
172
+ return () => {
173
+ stop?.();
174
+ img?.removeEventListener("load", onLoad);
175
+ img?.removeEventListener("error", onError);
176
+ };
177
+ }
178
+
179
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-button.js
180
+ var ui_button_exports = {};
181
+ __export(ui_button_exports, {
182
+ default: () => controller4
183
+ });
184
+ function controller4(host) {
185
+ const element = host.element;
186
+ const button = element.querySelector("button");
187
+ const apply = () => {
188
+ const disabled3 = Boolean(host.state.disabled);
189
+ button && (button.disabled = disabled3);
190
+ };
191
+ const onKeydown = (event) => {
192
+ if (button || host.state.disabled || !["Enter", " "].includes(event.key)) return;
193
+ event.preventDefault();
194
+ element.click();
195
+ };
196
+ element.addEventListener("keydown", onKeydown);
197
+ const stop = host.effect(apply);
198
+ apply();
199
+ return () => {
200
+ stop();
201
+ element.removeEventListener("keydown", onKeydown);
202
+ };
203
+ }
204
+
205
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-checkbox.js
206
+ var ui_checkbox_exports = {};
207
+ __export(ui_checkbox_exports, {
208
+ default: () => controller5
209
+ });
210
+ function triggerFor(event) {
211
+ if (event instanceof KeyboardEvent) return "keyboard";
212
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
213
+ return "programmatic";
214
+ }
215
+ function controller5(host) {
216
+ const element = host.element;
217
+ const input = element.querySelector('input[type="checkbox"]');
218
+ host.state.internalChecked = host.state.checked === void 0 ? Boolean(host.state.defaultChecked) : Boolean(host.state.checked);
219
+ const apply = () => {
220
+ if (host.state.checked !== void 0) host.state.internalChecked = Boolean(host.state.checked);
221
+ const disabled3 = Boolean(host.state.disabled);
222
+ element.setAttribute("aria-disabled", String(disabled3));
223
+ element.setAttribute("aria-checked", host.state.indeterminate ? "mixed" : String(Boolean(host.state.internalChecked)));
224
+ if (!input) return;
225
+ input.checked = Boolean(host.state.internalChecked);
226
+ input.indeterminate = Boolean(host.state.indeterminate);
227
+ input.disabled = disabled3;
228
+ input.required = Boolean(host.state.required);
229
+ input.value = String(host.state.value ?? "on");
230
+ };
231
+ const onChange = (event) => {
232
+ if (!input) return;
233
+ const checked = input.checked;
234
+ if (host.state.checked === void 0) host.state.internalChecked = checked;
235
+ else apply();
236
+ host.dispatch("change", { checked, value: String(host.state.value ?? "on"), trigger: triggerFor(event) });
237
+ };
238
+ input?.addEventListener("change", onChange);
239
+ const stop = host.effect(apply);
240
+ apply();
241
+ return () => {
242
+ stop();
243
+ input?.removeEventListener("change", onChange);
244
+ };
245
+ }
246
+
247
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-combobox.js
248
+ var ui_combobox_exports = {};
249
+ __export(ui_combobox_exports, {
250
+ default: () => controller6,
251
+ focusInput: () => focusInput,
252
+ validate: () => validate
253
+ });
254
+
255
+ // ../../tools/migrate-html-next/generated/core/components/controllers/shared/overlay.js
256
+ var stacks = /* @__PURE__ */ new WeakMap();
257
+ var anchorSequence = 0;
258
+ var anchorBindings = /* @__PURE__ */ new WeakMap();
259
+ function stateFor(document) {
260
+ let state = stacks.get(document);
261
+ if (state) return state;
262
+ state = { records: [], modalCount: 0, listening: false };
263
+ stacks.set(document, state);
264
+ return state;
265
+ }
266
+ function syncScrollLock(document, state) {
267
+ document.documentElement.toggleAttribute("data-ui-scroll-lock", state.modalCount > 0);
268
+ if (state.modalCount > 0) document.documentElement.style.overflow = "hidden";
269
+ else document.documentElement.style.removeProperty("overflow");
270
+ }
271
+ function requestClose(document, reason, trigger) {
272
+ const record = stateFor(document).records.at(-1);
273
+ if (!record || record.dismissible === false && (reason === "escape" || reason === "light-dismiss")) return false;
274
+ record.requestClose(reason, trigger);
275
+ return true;
276
+ }
277
+ function ensureListeners(document, state) {
278
+ if (state.listening) return;
279
+ state.onKeydown = (event) => {
280
+ if (event.key === "Escape") requestClose(document, "escape", "keyboard");
281
+ };
282
+ state.onPointerdown = (event) => {
283
+ const top = state.records.at(-1);
284
+ if (!top || top.dismissible === false) return;
285
+ const boundary = [top.element, ...top.relatedElements ?? []];
286
+ if (event.composedPath().some((target) => target instanceof Node && boundary.some((element) => element.contains(target)))) return;
287
+ requestClose(document, "light-dismiss", "pointer");
288
+ };
289
+ document.addEventListener("keydown", state.onKeydown);
290
+ document.addEventListener("pointerdown", state.onPointerdown, true);
291
+ state.listening = true;
292
+ }
293
+ function removeListeners(document, state) {
294
+ if (!state.listening || state.records.length) return;
295
+ document.removeEventListener("keydown", state.onKeydown);
296
+ document.removeEventListener("pointerdown", state.onPointerdown, true);
297
+ state.listening = false;
298
+ }
299
+ function openOverlay(record) {
300
+ const document = record.element.ownerDocument;
301
+ const state = stateFor(document);
302
+ closeOverlay(document, record.id);
303
+ state.records.push(record);
304
+ if (record.modal) {
305
+ state.modalCount += 1;
306
+ syncScrollLock(document, state);
307
+ }
308
+ ensureListeners(document, state);
309
+ }
310
+ function closeOverlay(document, id2) {
311
+ const state = stateFor(document);
312
+ const index = state.records.findIndex((record) => record.id === id2);
313
+ if (index >= 0) {
314
+ const [record] = state.records.splice(index, 1);
315
+ if (record?.modal) {
316
+ state.modalCount = Math.max(0, state.modalCount - 1);
317
+ syncScrollLock(document, state);
318
+ }
319
+ }
320
+ removeListeners(document, state);
321
+ }
322
+ function requestTopOverlayClose(document, reason, trigger) {
323
+ return requestClose(document, reason, trigger);
324
+ }
325
+ function topLayerOpen(surface) {
326
+ try {
327
+ return surface.matches(":popover-open");
328
+ } catch {
329
+ return !surface.hidden;
330
+ }
331
+ }
332
+ function show(surface) {
333
+ surface.setAttribute("popover", "manual");
334
+ surface.hidden = false;
335
+ if (typeof surface.showPopover === "function" && !topLayerOpen(surface)) {
336
+ try {
337
+ surface.showPopover();
338
+ } catch {
339
+ }
340
+ }
341
+ }
342
+ function hide(surface) {
343
+ if (typeof surface.hidePopover === "function" && topLayerOpen(surface)) {
344
+ try {
345
+ surface.hidePopover();
346
+ } catch {
347
+ }
348
+ }
349
+ surface.hidden = true;
350
+ }
351
+ function bindAnchor(anchor, name) {
352
+ const binding = anchorBindings.get(anchor) ?? { original: anchor.style.getPropertyValue("anchor-name"), names: /* @__PURE__ */ new Set() };
353
+ binding.names.add(name);
354
+ anchorBindings.set(anchor, binding);
355
+ anchor.style.setProperty("anchor-name", [binding.original, ...binding.names].filter(Boolean).join(", "));
356
+ }
357
+ function unbindAnchor(anchor, name) {
358
+ const binding = anchorBindings.get(anchor);
359
+ if (!binding) return;
360
+ binding.names.delete(name);
361
+ if (binding.names.size) anchor.style.setProperty("anchor-name", [binding.original, ...binding.names].filter(Boolean).join(", "));
362
+ else {
363
+ if (binding.original) anchor.style.setProperty("anchor-name", binding.original);
364
+ else anchor.style.removeProperty("anchor-name");
365
+ anchorBindings.delete(anchor);
366
+ }
367
+ }
368
+ function viewport(owner) {
369
+ const visual = owner.visualViewport;
370
+ const left = visual?.offsetLeft ?? 0;
371
+ const top = visual?.offsetTop ?? 0;
372
+ const width = visual?.width ?? owner.innerWidth;
373
+ const height = visual?.height ?? owner.innerHeight;
374
+ return { left, top, right: left + width, bottom: top + height, width, height };
375
+ }
376
+ function clamp(rect, bounds, gutter) {
377
+ const availableWidth = Math.max(0, bounds.width - gutter * 2);
378
+ const availableHeight = Math.max(0, bounds.height - gutter * 2);
379
+ const left = rect.width > availableWidth ? bounds.left + gutter : Math.min(Math.max(rect.left, bounds.left + gutter), bounds.right - gutter - rect.width);
380
+ const top = rect.height > availableHeight ? bounds.top + gutter : Math.min(Math.max(rect.top, bounds.top + gutter), bounds.bottom - gutter - rect.height);
381
+ return { x: left - rect.left, y: top - rect.top };
382
+ }
383
+ function fallbackPosition(surface, anchor, placement, gap, viewportGap, surfaceRect = surface.getBoundingClientRect()) {
384
+ const bounds = viewport(surface.ownerDocument.defaultView);
385
+ const preferTop = placement.startsWith("top");
386
+ const preferEnd = placement.endsWith("end");
387
+ const below = bounds.bottom - anchor.bottom - viewportGap;
388
+ const above = anchor.top - bounds.top - viewportGap;
389
+ const useTop = preferTop ? !(above < surfaceRect.height + gap && below > above) : below < surfaceRect.height + gap && above > below;
390
+ const top = useTop ? anchor.top - surfaceRect.height - gap : anchor.bottom + gap;
391
+ const left = preferEnd ? anchor.right - surfaceRect.width : anchor.left;
392
+ const shift = clamp({ left, top, right: left + surfaceRect.width, bottom: top + surfaceRect.height, width: surfaceRect.width, height: surfaceRect.height }, bounds, viewportGap);
393
+ surface.style.left = `${Math.round(left + shift.x)}px`;
394
+ surface.style.top = `${Math.round(top + shift.y)}px`;
395
+ surface.style.right = "auto";
396
+ surface.style.bottom = "auto";
397
+ }
398
+ function createAnchoredSurface(surface, options = {}) {
399
+ const owner = surface.ownerDocument.defaultView;
400
+ let placement = options.placement ?? "bottom-start";
401
+ const gap = Math.max(0, options.gap ?? 4);
402
+ const viewportGap = Math.max(0, options.viewportGap ?? 8);
403
+ const nativeAnchor = owner.CSS?.supports?.("anchor-name: --ui-anchor-test") && owner.CSS.supports("position-anchor: --ui-anchor-test") && owner.CSS.supports("top: anchor(bottom)");
404
+ const anchorName = `--ui-anchor-${++anchorSequence}`;
405
+ let anchor = options.anchor ?? null;
406
+ let point = null;
407
+ let open = false;
408
+ let frame = null;
409
+ let abort = null;
410
+ let sizeObserver = null;
411
+ surface.setAttribute("popover", "manual");
412
+ surface.dataset.uiPositioning = nativeAnchor ? "anchor" : "fallback";
413
+ surface.style.position = "fixed";
414
+ surface.style.margin = "0";
415
+ const bind = (next) => {
416
+ if (anchor) unbindAnchor(anchor, anchorName);
417
+ anchor = next;
418
+ if (anchor) {
419
+ bindAnchor(anchor, anchorName);
420
+ surface.style.setProperty("position-anchor", anchorName);
421
+ } else surface.style.removeProperty("position-anchor");
422
+ };
423
+ const position = () => {
424
+ frame = null;
425
+ if (!open) return;
426
+ if (point) {
427
+ fallbackPosition(surface, { left: point.x, right: point.x, top: point.y, bottom: point.y, width: 0, height: 0 }, "bottom-start", gap, viewportGap);
428
+ return;
429
+ }
430
+ if (!anchor) return;
431
+ let rect;
432
+ if (nativeAnchor) {
433
+ const blockEnd = placement.startsWith("bottom");
434
+ const inlineEnd = placement.endsWith("end");
435
+ surface.style.top = blockEnd ? `calc(anchor(bottom) + ${gap}px)` : "auto";
436
+ surface.style.bottom = blockEnd ? "auto" : `calc(anchor(top) + ${gap}px)`;
437
+ surface.style.left = inlineEnd ? "auto" : "anchor(left)";
438
+ surface.style.right = inlineEnd ? "anchor(right)" : "auto";
439
+ surface.style.setProperty("position-try-fallbacks", "flip-block, flip-inline");
440
+ rect = surface.getBoundingClientRect();
441
+ if (!rect.width || !rect.height) return;
442
+ const shift = clamp(rect, viewport(owner), viewportGap);
443
+ if (!shift.x && !shift.y) return;
444
+ }
445
+ fallbackPosition(surface, anchor.getBoundingClientRect(), placement, gap, viewportGap, rect);
446
+ };
447
+ const schedule = () => {
448
+ if (open && frame === null) frame = owner.requestAnimationFrame(position);
449
+ };
450
+ const syncListeners = () => {
451
+ const needed = open && (point || anchor);
452
+ if (!needed) {
453
+ abort?.abort();
454
+ abort = null;
455
+ return;
456
+ }
457
+ if (abort) return;
458
+ abort = new AbortController();
459
+ const signal = abort.signal;
460
+ owner.addEventListener("resize", schedule, { passive: true, signal });
461
+ owner.addEventListener("scroll", schedule, { passive: true, capture: true, signal });
462
+ owner.visualViewport?.addEventListener("resize", schedule, { passive: true, signal });
463
+ owner.visualViewport?.addEventListener("scroll", schedule, { passive: true, signal });
464
+ };
465
+ const observeSize = () => {
466
+ if (sizeObserver || !owner.ResizeObserver) return;
467
+ sizeObserver = new owner.ResizeObserver(schedule);
468
+ sizeObserver.observe(surface);
469
+ };
470
+ const stopSize = () => {
471
+ sizeObserver?.disconnect();
472
+ sizeObserver = null;
473
+ };
474
+ bind(anchor);
475
+ return {
476
+ setAnchor(next) {
477
+ point = null;
478
+ bind(next);
479
+ syncListeners();
480
+ schedule();
481
+ },
482
+ setPlacement(next) {
483
+ placement = next || "bottom-start";
484
+ schedule();
485
+ },
486
+ show() {
487
+ point = null;
488
+ open = true;
489
+ syncListeners();
490
+ show(surface);
491
+ position();
492
+ schedule();
493
+ observeSize();
494
+ },
495
+ showAtPoint(next) {
496
+ point = next;
497
+ open = true;
498
+ syncListeners();
499
+ show(surface);
500
+ position();
501
+ schedule();
502
+ observeSize();
503
+ },
504
+ hide() {
505
+ open = false;
506
+ point = null;
507
+ syncListeners();
508
+ stopSize();
509
+ if (frame !== null) owner.cancelAnimationFrame(frame);
510
+ frame = null;
511
+ hide(surface);
512
+ },
513
+ refresh: schedule,
514
+ destroy() {
515
+ open = false;
516
+ abort?.abort();
517
+ abort = null;
518
+ stopSize();
519
+ if (frame !== null) owner.cancelAnimationFrame(frame);
520
+ frame = null;
521
+ hide(surface);
522
+ bind(null);
523
+ }
524
+ };
525
+ }
526
+
527
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-combobox.js
528
+ var instances = /* @__PURE__ */ new WeakMap();
529
+ function configFor(host) {
530
+ return host.state.config && typeof host.state.config === "object" ? host.state.config : {};
531
+ }
532
+ function formatEditingValue(raw, selection, format) {
533
+ const unchanged = { display: raw, selection };
534
+ if (typeof format !== "function") return unchanged;
535
+ let result;
536
+ try {
537
+ result = format(raw, selection);
538
+ } catch {
539
+ return unchanged;
540
+ }
541
+ if (!result) return unchanged;
542
+ const characters = Array.from(raw);
543
+ let cursor = 0;
544
+ for (const character of result.display) if (character === characters[cursor]) cursor += 1;
545
+ if (!Number.isInteger(result.selection.start) || !Number.isInteger(result.selection.end) || cursor !== characters.length || result.selection.start < 0 || result.selection.end < result.selection.start || result.selection.end > result.display.length) return unchanged;
546
+ return result;
547
+ }
548
+ async function validateField(request, config) {
549
+ let output = request.raw;
550
+ let issues = [];
551
+ const check = () => request.signal.throwIfAborted();
552
+ try {
553
+ check();
554
+ if (config.parse) output = await config.parse(request.raw, request);
555
+ check();
556
+ if (config.schema) {
557
+ const result = await config.schema["~standard"].validate(output);
558
+ check();
559
+ if (result.issues) issues = result.issues;
560
+ else if ("value" in result) output = result.value;
561
+ }
562
+ if (!issues.some((issue) => issue.severity !== "warning")) {
563
+ if (config.normalize) output = await config.normalize(output, request);
564
+ check();
565
+ if (config.validator) {
566
+ const result = await config.validator(output, request);
567
+ check();
568
+ issues = [...issues, ...result.issues ?? []];
569
+ if ("output" in result) output = result.output;
570
+ }
571
+ }
572
+ } catch (error) {
573
+ check();
574
+ issues = [{ message: error instanceof Error ? error.message : "Unable to validate this value." }];
575
+ }
576
+ issues = [...issues, ...config.issues ?? []];
577
+ return { output: issues.some((issue) => issue.severity !== "warning") ? void 0 : output, issues };
578
+ }
579
+ async function validate(host) {
580
+ return instances.get(host.element)?.validate();
581
+ }
582
+ async function focusInput(host) {
583
+ instances.get(host.element)?.input?.focus();
584
+ }
585
+ function controller6(host) {
586
+ const element = host.element;
587
+ const document = element.ownerDocument;
588
+ const overlayId = `ui-combobox-${Math.random().toString(36).slice(2)}`;
589
+ let input;
590
+ let field;
591
+ let popup;
592
+ let listbox;
593
+ let itemsContainer;
594
+ let validationElement;
595
+ let statusElement;
596
+ let surface;
597
+ let lookup;
598
+ let validationRun;
599
+ let lookupTimer;
600
+ let composing = false;
601
+ let alive = true;
602
+ let fullSet = false;
603
+ let initialRaw = "";
604
+ let awaitingLabel = null;
605
+ let proposedChange;
606
+ let formattedRaw;
607
+ let formattedWith;
608
+ let lastValue = host.state.value;
609
+ let lastQuery = host.state.query;
610
+ let lastConfig = host.state.config;
611
+ const knownOptions = /* @__PURE__ */ new Map();
612
+ const config = () => configFor(host);
613
+ const items = () => host.state.multiple && Array.isArray(host.state.value) ? host.state.value : [];
614
+ const selectedValues = () => new Set(items().map((item) => item.value));
615
+ const setValidation = (result, touched = host.state.validation?.touched ?? false) => {
616
+ const issues = result.issues ?? [];
617
+ const blocking = issues.some((issue) => issue.severity !== "warning");
618
+ host.state.validation = {
619
+ status: blocking ? "error" : issues.length ? "warning" : "valid",
620
+ touched,
621
+ dirty: host.state.raw !== initialRaw,
622
+ ...result,
623
+ issues
624
+ };
625
+ host.dispatch("validation-change", host.state.validation);
626
+ };
627
+ const resetValidation = () => {
628
+ validationRun?.abort();
629
+ host.state.validation = {
630
+ status: "pristine",
631
+ touched: host.state.validation?.touched ?? false,
632
+ dirty: host.state.raw !== initialRaw,
633
+ issues: []
634
+ };
635
+ host.dispatch("validation-change", host.state.validation);
636
+ };
637
+ const applyServerIssues = () => {
638
+ const issues = config().issues ?? [];
639
+ if (issues.length) setValidation({ issues }, host.state.validation?.touched ?? false);
640
+ else resetValidation();
641
+ };
642
+ const cancelLookup = () => {
643
+ clearTimeout(lookupTimer);
644
+ lookup?.abort();
645
+ lookup = void 0;
646
+ host.state.loading = false;
647
+ };
648
+ const close = () => {
649
+ host.state.expanded = false;
650
+ host.state.active = -1;
651
+ cancelLookup();
652
+ surface?.hide();
653
+ closeOverlay(document, overlayId);
654
+ };
655
+ const canCreate = () => {
656
+ const current = config();
657
+ const candidates = current.options ? [...current.options, ...host.state.rows ?? []] : host.state.rows ?? [];
658
+ return Boolean(current.allowCreate && String(host.state.raw).trim() && !host.state.loading && !host.state.lookupError && !candidates.some((row) => row.label.toLocaleLowerCase() === String(host.state.raw).toLocaleLowerCase()));
659
+ };
660
+ const search = (reason) => {
661
+ cancelLookup();
662
+ fullSet = reason === "disclosure";
663
+ host.state.active = -1;
664
+ host.state.lookupError = "";
665
+ const current = config();
666
+ const query = fullSet ? "" : String(host.state.raw);
667
+ const controller29 = new AbortController();
668
+ lookup = controller29;
669
+ const applyOptions = (options) => {
670
+ if (controller29.signal.aborted || !alive) return;
671
+ for (const option of options) knownOptions.set(option.value, option);
672
+ const selectedOption = host.state.selected == null ? void 0 : knownOptions.get(host.state.selected);
673
+ if (host.state.query === void 0 && awaitingLabel === host.state.selected && selectedOption) {
674
+ host.state.raw = selectedOption.label;
675
+ host.state.display = selectedOption.label;
676
+ awaitingLabel = null;
677
+ formattedRaw = void 0;
678
+ resetValidation();
679
+ }
680
+ const ids = /* @__PURE__ */ new Set();
681
+ const selected = host.state.multiple ? selectedValues() : void 0;
682
+ const filtered = options.filter((option) => {
683
+ if (ids.has(option.id)) return false;
684
+ ids.add(option.id);
685
+ if (fullSet) return true;
686
+ if (selected) return !selected.has(option.value) && (current.filter ? current.filter(option, query, current.context) : option.label.toLocaleLowerCase().includes(query.toLocaleLowerCase()));
687
+ return current.filter ? current.filter(option, query, current.context) : current.provider ? true : option.label.toLocaleLowerCase().includes(query.toLocaleLowerCase());
688
+ });
689
+ const groups = /* @__PURE__ */ new Map();
690
+ for (const row of filtered) {
691
+ const group = row.group ?? "";
692
+ if (!groups.has(group)) groups.set(group, []);
693
+ groups.get(group).push(row);
694
+ }
695
+ host.state.rows = [...groups.values()].flat();
696
+ host.state.loading = false;
697
+ host.dispatch("options-change", host.state.rows);
698
+ };
699
+ if (!current.provider) {
700
+ applyOptions(current.options ?? []);
701
+ return;
702
+ }
703
+ host.state.rows = [];
704
+ host.state.loading = true;
705
+ lookupTimer = setTimeout(async () => {
706
+ try {
707
+ applyOptions(await current.provider({ query, context: current.context, signal: controller29.signal, reason }));
708
+ } catch (error) {
709
+ if (!controller29.signal.aborted && alive) {
710
+ host.state.loading = false;
711
+ host.state.lookupError = error instanceof Error ? error.message : "Unable to load suggestions.";
712
+ }
713
+ }
714
+ }, reason === "disclosure" ? 0 : Math.max(0, Number(current.debounce ?? 200)));
715
+ };
716
+ const open = (reason = "input") => {
717
+ if (host.state.disabled || host.state.readOnly) return;
718
+ host.state.expanded = true;
719
+ if (popup && field) popup.style.minWidth = `${field.getBoundingClientRect().width}px`;
720
+ surface?.show();
721
+ if (popup) openOverlay({ id: overlayId, element: popup, relatedElements: [element], modal: false, requestClose: close });
722
+ search(reason);
723
+ };
724
+ const format = (timing) => {
725
+ const current = config();
726
+ if ((current.formatOn ?? "blur") !== timing || !input) return;
727
+ if (formattedRaw === host.state.raw && formattedWith === current.format) return;
728
+ const result = formatEditingValue(String(host.state.raw), {
729
+ start: input.selectionStart ?? String(host.state.raw).length,
730
+ end: input.selectionEnd ?? String(host.state.raw).length,
731
+ direction: input.selectionDirection ?? "none"
732
+ }, current.format);
733
+ formattedRaw = host.state.raw;
734
+ formattedWith = current.format;
735
+ host.state.display = result.display;
736
+ if (input.value !== result.display) {
737
+ input.value = result.display;
738
+ input.setSelectionRange(result.selection.start, result.selection.end, result.selection.direction);
739
+ }
740
+ };
741
+ const commit = (value, query, option, kind, trigger) => {
742
+ awaitingLabel = null;
743
+ const queryChanged = query !== host.state.raw;
744
+ if (host.state.value === void 0) host.state.selected = value;
745
+ if (host.state.query === void 0 && queryChanged) {
746
+ host.state.raw = query;
747
+ host.state.display = query;
748
+ formattedRaw = void 0;
749
+ }
750
+ resetValidation();
751
+ const detail = { value, query, option, kind, trigger };
752
+ const proposal = { value, query };
753
+ proposedChange = proposal;
754
+ host.dispatch("value-change", detail);
755
+ if (queryChanged) host.dispatch("query-change", { query, display: query, trigger });
756
+ if (kind === "create") host.dispatch("create-entry", detail);
757
+ if (kind === "free-entry") host.dispatch("free-entry", detail);
758
+ if (kind === "invalidation") host.dispatch("dependency-invalidate", detail);
759
+ queueMicrotask(() => {
760
+ if (proposedChange !== proposal) return;
761
+ if (host.state.value !== void 0 && host.state.value !== proposal.value) syncValue();
762
+ if (host.state.query !== void 0 && host.state.query !== proposal.query) syncQuery();
763
+ proposedChange = void 0;
764
+ });
765
+ };
766
+ const emitItems = (next) => host.dispatch("value-change", next);
767
+ const setMultiQuery = (query, trigger) => {
768
+ if (host.state.query === void 0) {
769
+ host.state.raw = query;
770
+ host.state.display = query;
771
+ formattedRaw = void 0;
772
+ }
773
+ if (input) input.value = query;
774
+ host.dispatch("query-change", { query, display: query, trigger });
775
+ };
776
+ const addSelectedItem = (option, trigger) => {
777
+ const current = items();
778
+ host.dispatch("add-item", { item: option, index: current.length, trigger });
779
+ emitItems([...current, option]);
780
+ };
781
+ const createSelectedItem = (query, trigger) => {
782
+ if (query) host.dispatch("create-item", { query, trigger });
783
+ };
784
+ const choose = (index, trigger) => {
785
+ const option = (host.state.rows ?? [])[index];
786
+ if (option?.disabled) return;
787
+ if (host.state.multiple) {
788
+ if (option) addSelectedItem(option, trigger);
789
+ else if (canCreate() && index === host.state.rows.length) createSelectedItem(String(host.state.raw).trim(), trigger);
790
+ else return;
791
+ setMultiQuery("", trigger);
792
+ } else if (option) commit(option.value, option.label, option, "selection", trigger);
793
+ else if (canCreate() && index === host.state.rows.length) commit(null, host.state.raw, null, "create", trigger);
794
+ else return;
795
+ close();
796
+ input?.focus();
797
+ if (!host.state.multiple && config().validateOn !== "submit") queueMicrotask(() => void validateCurrent());
798
+ };
799
+ const commitQuery = (trigger) => {
800
+ const query = String(host.state.raw).trim();
801
+ if (!query) return;
802
+ const option = (host.state.rows ?? []).find((row) => row.label.trim().toLocaleLowerCase() === query.toLocaleLowerCase());
803
+ if (option) {
804
+ setMultiQuery("", trigger);
805
+ addSelectedItem(option, trigger);
806
+ } else if (config().allowCreate) {
807
+ setMultiQuery("", trigger);
808
+ createSelectedItem(query, trigger);
809
+ }
810
+ };
811
+ const itemButtons = () => Array.from(element.querySelectorAll('[part="item"]'));
812
+ const removeItemAt = (index, trigger) => {
813
+ const current = items();
814
+ const item = current[index];
815
+ if (!item || item.disabled || host.state.disabled || host.state.readOnly) return;
816
+ host.dispatch("remove-item", { item, index, trigger });
817
+ emitItems(current.filter((_, position) => position !== index));
818
+ requestAnimationFrame(() => itemButtons()[Math.min(index, itemButtons().length - 1)]?.focus?.() ?? input?.focus());
819
+ };
820
+ const move = (key) => {
821
+ const rows = host.state.rows ?? [];
822
+ const indices = rows.flatMap((row, index) => row.disabled ? [] : [index]);
823
+ if (canCreate()) indices.push(rows.length);
824
+ if (!indices.length) return;
825
+ const current = indices.indexOf(host.state.active);
826
+ const next = key === "Home" ? 0 : key === "End" ? indices.length - 1 : key === "ArrowDown" ? Math.min(current + 1, indices.length - 1) : current < 0 ? indices.length - 1 : Math.max(0, current - 1);
827
+ host.state.active = indices[next];
828
+ requestAnimationFrame(() => element.querySelector(`#option-${host.state.active}`)?.scrollIntoView({ block: "nearest" }));
829
+ };
830
+ const validateCurrent = async () => {
831
+ validationRun?.abort();
832
+ const run = new AbortController();
833
+ validationRun = run;
834
+ host.state.validation = { ...host.state.validation, status: "pending", output: void 0 };
835
+ host.dispatch("validation-change", host.state.validation);
836
+ try {
837
+ const current = config();
838
+ const result = await validateField({ raw: host.state.raw, value: host.state.selected, context: current.context, signal: run.signal }, current);
839
+ if (host.state.required && !String(host.state.raw).trim()) result.issues = [...result.issues, { message: "A value is required." }];
840
+ else if (host.state.raw && host.state.selected === null && !current.allowFreeText && !current.allowCreate) result.issues = [...result.issues, { message: "Choose a suggestion." }];
841
+ if (result.issues.some((issue) => issue.severity !== "warning")) result.output = void 0;
842
+ if (!run.signal.aborted && alive) setValidation(result);
843
+ } catch {
844
+ }
845
+ return host.state.validation;
846
+ };
847
+ const syncValue = () => {
848
+ if (host.state.multiple || host.state.value === void 0) return;
849
+ host.state.selected = host.state.value;
850
+ if (host.state.query === void 0) {
851
+ const proposal = proposedChange;
852
+ const option = config().options?.find((row) => row.value === host.state.selected) ?? (host.state.selected == null ? void 0 : knownOptions.get(host.state.selected));
853
+ const nextRaw = proposal?.value === host.state.selected ? proposal.query : option?.label ?? host.state.selected ?? "";
854
+ if (proposal?.value !== host.state.selected || nextRaw !== host.state.raw) {
855
+ host.state.raw = nextRaw;
856
+ host.state.display = nextRaw;
857
+ formattedRaw = void 0;
858
+ }
859
+ awaitingLabel = !option && host.state.selected !== null ? host.state.selected : null;
860
+ }
861
+ resetValidation();
862
+ };
863
+ const syncQuery = () => {
864
+ if (host.state.query === void 0 || host.state.query === host.state.raw) return;
865
+ if (host.state.value === void 0 && proposedChange?.query !== host.state.query) host.state.selected = null;
866
+ awaitingLabel = null;
867
+ formattedRaw = void 0;
868
+ host.state.raw = host.state.query;
869
+ host.state.display = host.state.query;
870
+ resetValidation();
871
+ if (host.state.expanded) search("input");
872
+ };
873
+ const makeChip = (item) => {
874
+ const projected = element.querySelector(`[slot="item-${CSS.escape(item.id)}"]`);
875
+ if (projected) return projected;
876
+ const chip = document.createElement("ui-chip");
877
+ chip.setAttribute("appearance", "pill");
878
+ chip.textContent = item.label;
879
+ return chip;
880
+ };
881
+ const makeOptionContent = (row) => {
882
+ const projected = element.querySelector(`[slot="option-${CSS.escape(row.id)}"]`);
883
+ if (projected) return [projected];
884
+ const primary = document.createElement("span");
885
+ primary.className = "primary";
886
+ primary.setAttribute("part", "option-primary");
887
+ primary.textContent = row.label;
888
+ if (!row.description) return [primary];
889
+ const secondary = document.createElement("span");
890
+ secondary.className = "secondary";
891
+ secondary.setAttribute("part", "option-secondary");
892
+ secondary.textContent = row.description;
893
+ return [primary, secondary];
894
+ };
895
+ const renderDynamic = () => {
896
+ if (itemsContainer) {
897
+ itemsContainer.replaceChildren();
898
+ items().forEach((item, index) => {
899
+ const button = document.createElement("button");
900
+ button.type = "button";
901
+ button.className = "item";
902
+ button.setAttribute("part", "item");
903
+ button.dataset.value = item.value;
904
+ button.dataset.index = String(index);
905
+ button.tabIndex = -1;
906
+ button.disabled = Boolean(host.state.disabled || host.state.readOnly || item.disabled);
907
+ button.setAttribute("aria-label", `${item.label}, press Delete or Backspace to remove`);
908
+ button.append(makeChip(item));
909
+ itemsContainer.append(button);
910
+ });
911
+ }
912
+ if (listbox) {
913
+ listbox.replaceChildren();
914
+ const rows = host.state.rows ?? [];
915
+ const groups = [...new Set(rows.map((row) => row.group ?? ""))];
916
+ for (const group of groups) {
917
+ const wrapper = document.createElement("div");
918
+ wrapper.setAttribute("role", group ? "group" : "presentation");
919
+ if (group) {
920
+ wrapper.setAttribute("aria-label", group);
921
+ const heading = document.createElement("div");
922
+ heading.className = "group";
923
+ heading.setAttribute("part", "group");
924
+ heading.textContent = group;
925
+ wrapper.append(heading);
926
+ }
927
+ rows.forEach((row, index) => {
928
+ if ((row.group ?? "") !== group) return;
929
+ const option = document.createElement("div");
930
+ option.id = `option-${index}`;
931
+ option.className = "option";
932
+ option.setAttribute("part", "option");
933
+ option.setAttribute("role", "option");
934
+ option.setAttribute("aria-selected", String(host.state.selected === row.value));
935
+ option.setAttribute("aria-disabled", String(Boolean(row.disabled)));
936
+ option.toggleAttribute("data-active", host.state.active === index);
937
+ option.dataset.index = String(index);
938
+ option.append(...makeOptionContent(row));
939
+ wrapper.append(option);
940
+ });
941
+ listbox.append(wrapper);
942
+ }
943
+ if (canCreate()) {
944
+ const option = document.createElement("div");
945
+ option.id = `option-${rows.length}`;
946
+ option.className = "option";
947
+ option.setAttribute("part", "option");
948
+ option.setAttribute("role", "option");
949
+ option.setAttribute("aria-selected", "false");
950
+ option.toggleAttribute("data-active", host.state.active === rows.length);
951
+ option.dataset.index = String(rows.length);
952
+ option.textContent = `Create \u201C${host.state.raw}\u201D`;
953
+ listbox.append(option);
954
+ }
955
+ const message = document.createElement("div");
956
+ message.className = "message";
957
+ if (host.state.loading) message.textContent = "Loading suggestions\u2026";
958
+ else if (host.state.lookupError) message.textContent = host.state.lookupError;
959
+ else if (!rows.length && !canCreate()) message.textContent = "No suggestions.";
960
+ if (message.textContent) listbox.append(message);
961
+ }
962
+ if (validationElement) {
963
+ validationElement.replaceChildren(...(host.state.validation?.issues ?? []).map((issue) => {
964
+ const line = document.createElement("div");
965
+ line.textContent = issue.message;
966
+ return line;
967
+ }));
968
+ validationElement.hidden = !host.state.validation?.issues?.length;
969
+ }
970
+ };
971
+ const wire = () => {
972
+ input = element.querySelector('input[part="input"]');
973
+ field = element.querySelector('[part="field"]');
974
+ popup = element.querySelector('[part="popup"]');
975
+ listbox = element.querySelector("#listbox");
976
+ itemsContainer = element.querySelector(".items");
977
+ validationElement = element.querySelector("#validation");
978
+ statusElement = element.querySelector('[role="status"]');
979
+ if (!surface && popup && field) surface = createAnchoredSurface(popup, { anchor: field, placement: "bottom-start" });
980
+ const clearButton = Array.from(field?.querySelectorAll('button[part="affordance"]') ?? []).find((button) => button.textContent?.trim() === "\xD7");
981
+ const disclosureButton = field?.querySelector('button[aria-controls="listbox"]');
982
+ if (clearButton) clearButton.dataset.comboboxAction = "clear";
983
+ if (disclosureButton) disclosureButton.dataset.comboboxAction = "disclosure";
984
+ };
985
+ const render = () => {
986
+ wire();
987
+ const validation = host.state.validation ?? { status: "pristine", issues: [] };
988
+ element.dataset.validation = validation.status;
989
+ element.dataset.size = String(host.state.size ?? "md");
990
+ const label = element.querySelector('label[part="label"]');
991
+ if (label) {
992
+ label.textContent = `${host.state.label ?? ""}${host.state.required ? " *" : ""}`;
993
+ label.classList.toggle("sr-only", host.state.labelVisibility === "sr-only");
994
+ }
995
+ if (input) {
996
+ if (!composing && input.value !== host.state.display) input.value = String(host.state.display ?? "");
997
+ input.placeholder = String(host.state.placeholder ?? "");
998
+ input.name = String(host.state.name ?? "");
999
+ input.disabled = Boolean(host.state.disabled);
1000
+ input.readOnly = Boolean(host.state.readOnly);
1001
+ input.required = Boolean(host.state.required);
1002
+ input.setAttribute("aria-expanded", String(Boolean(host.state.expanded)));
1003
+ input.setAttribute("aria-invalid", String(validation.status === "error"));
1004
+ input.setAttribute("aria-busy", String(validation.status === "pending"));
1005
+ if (host.state.expanded && host.state.active >= 0) input.setAttribute("aria-activedescendant", `option-${host.state.active}`);
1006
+ else input.removeAttribute("aria-activedescendant");
1007
+ const description = [host.state.helpOpen ? "help-text" : "", validation.issues?.length ? "validation" : ""].filter(Boolean).join(" ");
1008
+ if (description) input.setAttribute("aria-describedby", description);
1009
+ else input.removeAttribute("aria-describedby");
1010
+ }
1011
+ if (popup) popup.hidden = !host.state.expanded;
1012
+ listbox?.setAttribute("aria-label", `${host.state.label ?? ""} suggestions`);
1013
+ listbox?.setAttribute("aria-busy", String(Boolean(host.state.loading)));
1014
+ if (statusElement) {
1015
+ const status = host.state.loading ? "Loading suggestions\u2026" : host.state.lookupError || (host.state.expanded ? `${host.state.rows?.length ?? 0} suggestions available.` : "");
1016
+ statusElement.textContent = `${status} ${validation.status === "pending" ? "Checking value\u2026" : (validation.issues ?? []).map((issue) => issue.message).join(" ")}`.trim();
1017
+ }
1018
+ renderDynamic();
1019
+ if (host.state.expanded) surface?.refresh();
1020
+ };
1021
+ const onInput = (event) => {
1022
+ if (event.target !== input || composing || event.isComposing) return;
1023
+ awaitingLabel = null;
1024
+ formattedRaw = void 0;
1025
+ host.state.raw = input.value;
1026
+ host.state.display = input.value;
1027
+ resetValidation();
1028
+ format("input");
1029
+ host.dispatch("query-change", { query: host.state.raw, display: host.state.display, trigger: "keyboard" });
1030
+ if (host.state.selected !== null) commit(null, host.state.raw, null, "clear", "keyboard");
1031
+ open();
1032
+ if (config().validateOn === "input") void validateCurrent();
1033
+ queueMicrotask(() => {
1034
+ if (host.state.query !== void 0 && host.state.query !== host.state.raw) syncQuery();
1035
+ });
1036
+ };
1037
+ const onKeydown = (event) => {
1038
+ const item = event.target.closest?.('[part="item"]');
1039
+ if (item) {
1040
+ if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;
1041
+ const index = Number(item.dataset.index);
1042
+ if (event.key === "ArrowLeft") {
1043
+ event.preventDefault();
1044
+ itemButtons()[Math.max(0, index - 1)]?.focus();
1045
+ } else if (event.key === "ArrowRight") {
1046
+ event.preventDefault();
1047
+ index === items().length - 1 ? input?.focus() : itemButtons()[index + 1]?.focus();
1048
+ } else if (["Backspace", "Delete"].includes(event.key)) {
1049
+ event.preventDefault();
1050
+ removeItemAt(index, "keyboard");
1051
+ }
1052
+ return;
1053
+ }
1054
+ if (event.target !== input || composing || event.isComposing || host.state.disabled || host.state.readOnly) return;
1055
+ if (host.state.multiple && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
1056
+ if ((host.state.tokenSeparators ?? []).includes(event.key)) {
1057
+ event.preventDefault();
1058
+ commitQuery("keyboard");
1059
+ return;
1060
+ }
1061
+ if (!host.state.raw && (input.selectionStart ?? 0) === 0 && event.key === "ArrowLeft" && items().length) {
1062
+ event.preventDefault();
1063
+ itemButtons().at(-1)?.focus();
1064
+ return;
1065
+ }
1066
+ if (!host.state.raw && (input.selectionStart ?? 0) === 0 && event.key === "Backspace" && items().length) {
1067
+ event.preventDefault();
1068
+ removeItemAt(items().length - 1, "keyboard");
1069
+ return;
1070
+ }
1071
+ }
1072
+ if (event.key === "Escape" && host.state.expanded) {
1073
+ event.preventDefault();
1074
+ event.stopPropagation();
1075
+ close();
1076
+ } else if (event.key === "Tab") close();
1077
+ else if (!event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey && ["ArrowDown", "ArrowUp"].includes(event.key)) {
1078
+ event.preventDefault();
1079
+ if (!host.state.expanded) open("disclosure");
1080
+ move(event.key);
1081
+ } else if (["Home", "End"].includes(event.key) && host.state.expanded && host.state.active >= 0) {
1082
+ event.preventDefault();
1083
+ move(event.key);
1084
+ } else if (event.key === "Enter" && host.state.expanded) {
1085
+ if (host.state.active >= 0) {
1086
+ event.preventDefault();
1087
+ choose(host.state.active, "keyboard");
1088
+ } else if (config().allowFreeText) {
1089
+ event.preventDefault();
1090
+ commit(null, host.state.raw, null, "free-entry", "keyboard");
1091
+ close();
1092
+ }
1093
+ }
1094
+ };
1095
+ const onClick = (event) => {
1096
+ const option = event.target.closest?.('[role="option"][data-index]');
1097
+ if (option) {
1098
+ choose(Number(option.dataset.index), "pointer");
1099
+ return;
1100
+ }
1101
+ const action = event.target.closest?.("[data-combobox-action]")?.dataset.comboboxAction;
1102
+ if (action === "clear") {
1103
+ commit(null, "", null, "clear", "pointer");
1104
+ close();
1105
+ input?.focus();
1106
+ } else if (action === "disclosure") {
1107
+ host.state.expanded ? close() : open("disclosure");
1108
+ input?.focus();
1109
+ } else if (field?.contains(event.target) && !event.target.closest?.("button")) input?.focus();
1110
+ };
1111
+ const onPointerdown = (event) => {
1112
+ if (event.target.closest?.('[role="option"]')) event.preventDefault();
1113
+ };
1114
+ const onFocusout = (event) => {
1115
+ if (event.relatedTarget instanceof Node && element.contains(event.relatedTarget)) return;
1116
+ close();
1117
+ format("blur");
1118
+ host.state.validation = { ...host.state.validation, touched: true };
1119
+ if (!host.state.multiple && config().allowFreeText && host.state.selected === null) commit(null, host.state.raw, null, "free-entry", "keyboard");
1120
+ if ((config().validateOn ?? "blur") === "blur") void validateCurrent();
1121
+ };
1122
+ const onCompositionstart = (event) => {
1123
+ if (event.target === input) composing = true;
1124
+ };
1125
+ const onCompositionend = (event) => {
1126
+ if (event.target === input) {
1127
+ composing = false;
1128
+ onInput(new InputEvent("input"));
1129
+ }
1130
+ };
1131
+ const onTooltipOpen = (event) => {
1132
+ if (event.target.closest?.('[data-component-root~="ui-tooltip"]')) host.state.helpOpen = true;
1133
+ };
1134
+ const onTooltipClose = (event) => {
1135
+ if (event.target.closest?.('[data-component-root~="ui-tooltip"]')) host.state.helpOpen = false;
1136
+ };
1137
+ if (host.state.multiple) {
1138
+ host.state.selected = null;
1139
+ host.state.raw = host.state.query ?? host.state.defaultQuery ?? "";
1140
+ } else {
1141
+ host.state.selected = host.state.value !== void 0 ? host.state.value : host.state.defaultValue ?? null;
1142
+ host.state.raw = host.state.query ?? host.state.defaultQuery ?? "";
1143
+ if (host.state.query === void 0 && !host.state.raw && host.state.selected !== null) {
1144
+ host.state.raw = config().options?.find((row) => row.value === host.state.selected)?.label ?? host.state.selected;
1145
+ }
1146
+ if (host.state.query === void 0 && host.state.selected !== null && host.state.raw === host.state.selected) awaitingLabel = host.state.selected;
1147
+ }
1148
+ host.state.display = host.state.raw;
1149
+ initialRaw = host.state.raw;
1150
+ host.state.validation = { status: "pristine", touched: false, dirty: false, issues: [] };
1151
+ applyServerIssues();
1152
+ wire();
1153
+ const api = { get input() {
1154
+ return input;
1155
+ }, validate: validateCurrent };
1156
+ instances.set(element, api);
1157
+ const listeners = { input: onInput, keydown: onKeydown, click: onClick, pointerdown: onPointerdown, focusout: onFocusout, compositionstart: onCompositionstart, compositionend: onCompositionend, open: onTooltipOpen, close: onTooltipClose };
1158
+ for (const [name, listener] of Object.entries(listeners)) element.addEventListener(name, listener);
1159
+ const observer = new MutationObserver(wire);
1160
+ observer.observe(element, { childList: true, subtree: true });
1161
+ const stop = host.effect(() => {
1162
+ if (host.state.value !== lastValue) {
1163
+ lastValue = host.state.value;
1164
+ syncValue();
1165
+ }
1166
+ if (host.state.query !== lastQuery) {
1167
+ lastQuery = host.state.query;
1168
+ syncQuery();
1169
+ }
1170
+ if (host.state.config !== lastConfig) {
1171
+ const previous = configFor({ state: { config: lastConfig } });
1172
+ const next = config();
1173
+ lastConfig = host.state.config;
1174
+ validationRun?.abort();
1175
+ if (next.provider !== previous.provider || next.context !== previous.context) knownOptions.clear();
1176
+ if (next.context !== previous.context) {
1177
+ close();
1178
+ const policy = next.invalidation ?? "retain-query";
1179
+ if (host.state.multiple) {
1180
+ if (policy === "clear") setMultiQuery("", "programmatic");
1181
+ } else commit(policy === "retain" ? host.state.selected : null, policy === "clear" ? "" : host.state.raw, null, "invalidation", "programmatic");
1182
+ }
1183
+ applyServerIssues();
1184
+ if (host.state.expanded) search("context");
1185
+ }
1186
+ if (host.state.disabled || host.state.readOnly) close();
1187
+ render();
1188
+ });
1189
+ render();
1190
+ return () => {
1191
+ alive = false;
1192
+ stop();
1193
+ observer.disconnect();
1194
+ for (const [name, listener] of Object.entries(listeners)) element.removeEventListener(name, listener);
1195
+ close();
1196
+ validationRun?.abort();
1197
+ surface?.destroy();
1198
+ instances.delete(element);
1199
+ };
1200
+ }
1201
+
1202
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-context-menu.js
1203
+ var ui_context_menu_exports = {};
1204
+ __export(ui_context_menu_exports, {
1205
+ default: () => controller7
1206
+ });
1207
+ function disabled(item) {
1208
+ return item.getAttribute("aria-disabled") === "true" || item.hasAttribute("disabled") || item.getAttribute("disabled") === "true";
1209
+ }
1210
+ function controller7(host) {
1211
+ const element = host.element;
1212
+ const document = element.ownerDocument;
1213
+ const menuSurface = element.querySelector(".menu");
1214
+ const overlayId = `ui-context-menu-${Math.random().toString(36).slice(2, 11)}`;
1215
+ let trigger = null;
1216
+ let contextTarget = null;
1217
+ let surface = null;
1218
+ let point = null;
1219
+ let lastFor = host.state.for;
1220
+ let lastOpenProp = host.state.open;
1221
+ host.state.internalOpen = Boolean(host.state.open || host.state.defaultOpen);
1222
+ const items = () => Array.from(element.querySelectorAll('[data-component-root~="ui-menu-item"]')).filter((item) => !disabled(item));
1223
+ const focusFirst = () => requestAnimationFrame(() => items()[0]?.focus());
1224
+ const detach = () => {
1225
+ trigger?.removeEventListener("click", onTriggerClick);
1226
+ trigger?.removeEventListener("keydown", onTriggerKeydown);
1227
+ contextTarget?.removeEventListener("contextmenu", onContextMenu);
1228
+ };
1229
+ const resolveTargets = () => {
1230
+ const nextTrigger = element.querySelector('[slot="trigger"]');
1231
+ const nextContext = (host.state.for ? document.getElementById(String(host.state.for)) : null) ?? nextTrigger ?? element.parentElement;
1232
+ if (nextTrigger === trigger && nextContext === contextTarget) return;
1233
+ detach();
1234
+ trigger = nextTrigger;
1235
+ contextTarget = nextContext;
1236
+ trigger?.addEventListener("click", onTriggerClick);
1237
+ trigger?.addEventListener("keydown", onTriggerKeydown);
1238
+ contextTarget?.addEventListener("contextmenu", onContextMenu);
1239
+ surface?.setAnchor(trigger);
1240
+ };
1241
+ const syncNested = (open) => {
1242
+ const nested = menuSurface?.querySelector('[data-component-root~="ui-menu"]');
1243
+ if (!nested) return;
1244
+ nested.open = open;
1245
+ nested.setAttribute("aria-hidden", String(!open));
1246
+ if (open && typeof nested.showPopover === "function") {
1247
+ nested.setAttribute("popover", "manual");
1248
+ try {
1249
+ if (!nested.matches(":popover-open")) nested.showPopover();
1250
+ } catch {
1251
+ }
1252
+ } else if (!open && typeof nested.hidePopover === "function") {
1253
+ try {
1254
+ if (nested.matches(":popover-open")) nested.hidePopover();
1255
+ } catch {
1256
+ }
1257
+ }
1258
+ };
1259
+ const close = (reason, input, returnFocus = true) => {
1260
+ if (!host.state.internalOpen) return;
1261
+ host.state.internalOpen = false;
1262
+ host.dispatch("close", { open: false, reason, trigger: input });
1263
+ if (returnFocus) trigger?.focus();
1264
+ };
1265
+ const apply = () => {
1266
+ if (host.state.for !== lastFor) {
1267
+ lastFor = host.state.for;
1268
+ resolveTargets();
1269
+ }
1270
+ if (host.state.open !== lastOpenProp) {
1271
+ lastOpenProp = host.state.open;
1272
+ host.state.internalOpen = Boolean(host.state.open);
1273
+ }
1274
+ const open = Boolean(host.state.internalOpen);
1275
+ if (open) element.setAttribute("data-focus-trigger", String(host.state.focusTrigger ?? "programmatic"));
1276
+ else element.removeAttribute("data-focus-trigger");
1277
+ if (trigger) {
1278
+ trigger.setAttribute("aria-haspopup", "menu");
1279
+ trigger.setAttribute("aria-expanded", String(open));
1280
+ }
1281
+ syncNested(open);
1282
+ if (open) {
1283
+ if (point) surface?.showAtPoint(point);
1284
+ else surface?.show();
1285
+ openOverlay({ id: overlayId, modal: false, element, dismissible: true, requestClose: close });
1286
+ } else {
1287
+ surface?.hide();
1288
+ closeOverlay(document, overlayId);
1289
+ }
1290
+ };
1291
+ const openFromTrigger = (input) => {
1292
+ if (!trigger) return;
1293
+ point = null;
1294
+ host.state.focusTrigger = input;
1295
+ host.state.internalOpen = true;
1296
+ host.dispatch("open", { open: true, reason: "action", trigger: input });
1297
+ focusFirst();
1298
+ };
1299
+ function onTriggerClick(event) {
1300
+ const input = event.detail === 0 ? "keyboard" : "pointer";
1301
+ if (host.state.internalOpen) close("action", input);
1302
+ else openFromTrigger(input);
1303
+ }
1304
+ function onTriggerKeydown(event) {
1305
+ if (!["Enter", " ", "ArrowDown"].includes(event.key)) return;
1306
+ event.preventDefault();
1307
+ if (!host.state.internalOpen) openFromTrigger("keyboard");
1308
+ else focusFirst();
1309
+ }
1310
+ function onContextMenu(event) {
1311
+ event.preventDefault();
1312
+ point = { x: event.clientX, y: event.clientY };
1313
+ host.state.focusTrigger = "pointer";
1314
+ surface?.showAtPoint(point);
1315
+ host.state.internalOpen = true;
1316
+ host.dispatch("open", { open: true, reason: "action", trigger: "pointer" });
1317
+ focusFirst();
1318
+ }
1319
+ const onKeydown = (event) => {
1320
+ if (!host.state.internalOpen) return;
1321
+ host.state.focusTrigger = "keyboard";
1322
+ if (event.key === "Escape") {
1323
+ event.preventDefault();
1324
+ requestTopOverlayClose(document, "escape", "keyboard");
1325
+ } else if (["Enter", " "].includes(event.key)) {
1326
+ const item = event.target.closest?.('[data-component-root~="ui-menu-item"]');
1327
+ if (!item || disabled(item)) return;
1328
+ event.preventDefault();
1329
+ host.dispatch("select", { value: item.getAttribute("data-value") ?? item.getAttribute("value") ?? "", trigger: "keyboard" });
1330
+ close("action", "keyboard");
1331
+ }
1332
+ };
1333
+ const onClick = (event) => {
1334
+ const item = event.target.closest?.('[data-component-root~="ui-menu-item"]');
1335
+ if (!item || disabled(item)) return;
1336
+ host.dispatch("select", { value: item.getAttribute("data-value") ?? item.getAttribute("value") ?? "", trigger: "pointer" });
1337
+ close("action", "pointer");
1338
+ };
1339
+ resolveTargets();
1340
+ if (menuSurface) surface = createAnchoredSurface(menuSurface, { anchor: trigger, placement: "bottom-start" });
1341
+ element.addEventListener("keydown", onKeydown);
1342
+ element.addEventListener("click", onClick);
1343
+ const observer = new MutationObserver(() => {
1344
+ resolveTargets();
1345
+ syncNested(Boolean(host.state.internalOpen));
1346
+ });
1347
+ observer.observe(element, { childList: true, subtree: true });
1348
+ const stop = host.effect(apply);
1349
+ apply();
1350
+ return () => {
1351
+ stop();
1352
+ observer.disconnect();
1353
+ detach();
1354
+ element.removeEventListener("keydown", onKeydown);
1355
+ element.removeEventListener("click", onClick);
1356
+ surface?.destroy();
1357
+ closeOverlay(document, overlayId);
1358
+ };
1359
+ }
1360
+
1361
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-dialog.js
1362
+ var ui_dialog_exports = {};
1363
+ __export(ui_dialog_exports, {
1364
+ default: () => controller8
1365
+ });
1366
+ function inferredLabel(element, explicit) {
1367
+ if (String(explicit ?? "").trim()) return String(explicit).trim();
1368
+ return element.querySelector('[slot="heading"], [data-ui-dialog-title], h1, h2, h3, h4, h5, h6')?.textContent?.trim() || "Dialog";
1369
+ }
1370
+ function controller8(host) {
1371
+ const element = host.element;
1372
+ const document = element.ownerDocument;
1373
+ const dialog = element.querySelector("dialog");
1374
+ const overlayId = `ui-dialog-${Math.random().toString(36).slice(2, 11)}`;
1375
+ host.state.internalOpen = host.state.open === void 0 ? Boolean(host.state.defaultOpen) : Boolean(host.state.open);
1376
+ const requestClose2 = (reason, trigger) => {
1377
+ if (host.state.open === void 0) host.state.internalOpen = false;
1378
+ host.dispatch("close", { open: false, reason, trigger });
1379
+ };
1380
+ const apply = () => {
1381
+ if (host.state.open !== void 0) host.state.internalOpen = Boolean(host.state.open);
1382
+ host.state.accessibleLabel = inferredLabel(element, host.state.label);
1383
+ dialog?.setAttribute("aria-label", String(host.state.accessibleLabel));
1384
+ const open = Boolean(host.state.internalOpen);
1385
+ if (!dialog) return;
1386
+ if (open) {
1387
+ if (!dialog.open) {
1388
+ if (host.state.modal === false) dialog.show();
1389
+ else dialog.showModal();
1390
+ }
1391
+ openOverlay({ id: overlayId, modal: host.state.modal !== false, element, dismissible: host.state.dismissible !== false, requestClose: requestClose2 });
1392
+ } else {
1393
+ if (dialog.open) dialog.close();
1394
+ closeOverlay(document, overlayId);
1395
+ }
1396
+ };
1397
+ const onClose = () => {
1398
+ if (!host.state.internalOpen) return;
1399
+ if (host.state.open === void 0) {
1400
+ host.state.internalOpen = false;
1401
+ closeOverlay(document, overlayId);
1402
+ } else requestAnimationFrame(apply);
1403
+ host.dispatch("close", { open: false, reason: "programmatic", trigger: "programmatic" });
1404
+ };
1405
+ const onKeydown = (event) => {
1406
+ if (event.key === "Escape") {
1407
+ event.preventDefault();
1408
+ requestTopOverlayClose(document, "escape", "keyboard");
1409
+ }
1410
+ };
1411
+ const onCancel = (event) => {
1412
+ event.preventDefault();
1413
+ requestTopOverlayClose(document, "escape", "keyboard");
1414
+ };
1415
+ const observer = new MutationObserver(() => {
1416
+ const label = inferredLabel(element, host.state.label);
1417
+ if (label !== host.state.accessibleLabel) host.state.accessibleLabel = label;
1418
+ });
1419
+ observer.observe(element, { childList: true, subtree: true, characterData: true });
1420
+ dialog?.addEventListener("close", onClose);
1421
+ dialog?.addEventListener("cancel", onCancel);
1422
+ element.addEventListener("keydown", onKeydown);
1423
+ const stop = host.effect(apply);
1424
+ apply();
1425
+ return () => {
1426
+ stop();
1427
+ observer.disconnect();
1428
+ dialog?.removeEventListener("close", onClose);
1429
+ dialog?.removeEventListener("cancel", onCancel);
1430
+ element.removeEventListener("keydown", onKeydown);
1431
+ closeOverlay(document, overlayId);
1432
+ };
1433
+ }
1434
+
1435
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-disclosure.js
1436
+ var ui_disclosure_exports = {};
1437
+ __export(ui_disclosure_exports, {
1438
+ default: () => controller9
1439
+ });
1440
+ var nextDisclosureId = 0;
1441
+ function triggerFor2(event) {
1442
+ if (event instanceof KeyboardEvent) return "keyboard";
1443
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
1444
+ return "programmatic";
1445
+ }
1446
+ function controller9(host) {
1447
+ const element = host.element;
1448
+ const trigger = element.querySelector("[data-ui-disclosure-trigger], button, [aria-controls]");
1449
+ const controlsId = trigger?.getAttribute("aria-controls") ?? "";
1450
+ const children = Array.from(element.children);
1451
+ const content = controlsId ? element.ownerDocument.getElementById(controlsId) : children.find((child) => child !== trigger) ?? null;
1452
+ if (trigger && content) {
1453
+ if (!content.id) content.id = `disclosure-content-${++nextDisclosureId}`;
1454
+ trigger.setAttribute("aria-controls", content.id);
1455
+ host.state.contentId = content.id;
1456
+ }
1457
+ host.state.internalOpen = host.state.open === void 0 ? Boolean(host.state.defaultOpen) : Boolean(host.state.open);
1458
+ const apply = () => {
1459
+ if (host.state.open !== void 0) host.state.internalOpen = Boolean(host.state.open);
1460
+ const open = Boolean(host.state.internalOpen);
1461
+ trigger?.setAttribute("aria-expanded", String(open));
1462
+ if (content) content.hidden = !open;
1463
+ if (trigger instanceof HTMLButtonElement) trigger.disabled = Boolean(host.state.disabled);
1464
+ else trigger?.setAttribute("aria-disabled", String(Boolean(host.state.disabled)));
1465
+ };
1466
+ const setOpen = (next, event, triggerType = triggerFor2(event)) => {
1467
+ if (host.state.disabled || Boolean(host.state.internalOpen) === next) return;
1468
+ if (host.state.open === void 0) host.state.internalOpen = next;
1469
+ apply();
1470
+ host.dispatch(next ? "open" : "close", { open: next, reason: "action", trigger: triggerType });
1471
+ };
1472
+ const onClick = (event) => {
1473
+ if (host.state.disabled) event.preventDefault();
1474
+ else setOpen(!Boolean(host.state.internalOpen), event);
1475
+ };
1476
+ const onKeydown = (event) => {
1477
+ if (host.state.disabled || !["Enter", " "].includes(event.key)) return;
1478
+ event.preventDefault();
1479
+ setOpen(!Boolean(host.state.internalOpen), event, "keyboard");
1480
+ };
1481
+ trigger?.addEventListener("click", onClick);
1482
+ trigger?.addEventListener("keydown", onKeydown);
1483
+ const stop = host.effect(apply);
1484
+ apply();
1485
+ return () => {
1486
+ stop();
1487
+ trigger?.removeEventListener("click", onClick);
1488
+ trigger?.removeEventListener("keydown", onKeydown);
1489
+ };
1490
+ }
1491
+
1492
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-editable.js
1493
+ var ui_editable_exports = {};
1494
+ __export(ui_editable_exports, {
1495
+ default: () => controller10
1496
+ });
1497
+ function triggerElement(event) {
1498
+ return event.composedPath().find((node) => node instanceof HTMLElement && node.hasAttribute("data-ui-editable-trigger"));
1499
+ }
1500
+ function controller10(host) {
1501
+ const element = host.element;
1502
+ const document = element.ownerDocument;
1503
+ let trigger = null;
1504
+ host.state.internalEdit = host.state.edit === void 0 ? Boolean(host.state.defaultEdit) : Boolean(host.state.edit);
1505
+ const apply = () => {
1506
+ if (host.state.edit !== void 0) host.state.internalEdit = Boolean(host.state.edit);
1507
+ const editing = Boolean(host.state.internalEdit);
1508
+ const preview = element.querySelector('[part="preview"]');
1509
+ const editor = element.querySelector('[part="edit"]');
1510
+ if (preview) preview.hidden = editing;
1511
+ if (editor) editor.hidden = !editing;
1512
+ };
1513
+ const focusEditor = () => {
1514
+ const editRoot = element.querySelector('[slot="edit"]');
1515
+ const selector = "input, textarea, select, button, [tabindex], [data-component-root~='ui-combobox']";
1516
+ const candidate = editRoot?.matches(selector) ? editRoot : editRoot?.querySelector(selector);
1517
+ if (typeof candidate?.focusInput === "function") void candidate.focusInput();
1518
+ else candidate?.focus?.();
1519
+ };
1520
+ const requestEdit = (next, reason, input) => {
1521
+ if (host.state.disabled || Boolean(host.state.internalEdit) === next) return;
1522
+ if (host.state.edit === void 0) host.state.internalEdit = next;
1523
+ apply();
1524
+ host.dispatch("edit-change", { edit: next, reason, trigger: input });
1525
+ requestAnimationFrame(() => next ? focusEditor() : trigger?.focus?.());
1526
+ };
1527
+ const onClick = (event) => {
1528
+ if (host.state.internalEdit || host.state.disabled) return;
1529
+ const candidate = triggerElement(event);
1530
+ if (!candidate) return;
1531
+ trigger = candidate;
1532
+ requestEdit(true, "activate", "pointer");
1533
+ };
1534
+ const onKeydown = (event) => {
1535
+ if (host.state.internalEdit && event.key === "Escape") {
1536
+ event.preventDefault();
1537
+ event.stopPropagation();
1538
+ requestEdit(false, "escape", "keyboard");
1539
+ return;
1540
+ }
1541
+ if (host.state.internalEdit || !["Enter", " "].includes(event.key)) return;
1542
+ const candidate = triggerElement(event);
1543
+ if (!candidate) return;
1544
+ event.preventDefault();
1545
+ trigger = candidate;
1546
+ requestEdit(true, "activate", "keyboard");
1547
+ };
1548
+ const onDocumentPointerdown = (event) => {
1549
+ if (host.state.internalEdit && !event.composedPath().includes(element)) {
1550
+ requestEdit(false, "light-dismiss", "pointer");
1551
+ }
1552
+ };
1553
+ element.addEventListener("click", onClick);
1554
+ element.addEventListener("keydown", onKeydown);
1555
+ document.addEventListener("pointerdown", onDocumentPointerdown, true);
1556
+ const stop = host.effect(apply);
1557
+ apply();
1558
+ return () => {
1559
+ stop();
1560
+ element.removeEventListener("click", onClick);
1561
+ element.removeEventListener("keydown", onKeydown);
1562
+ document.removeEventListener("pointerdown", onDocumentPointerdown, true);
1563
+ };
1564
+ }
1565
+
1566
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-form-field.js
1567
+ var ui_form_field_exports = {};
1568
+ __export(ui_form_field_exports, {
1569
+ default: () => controller11
1570
+ });
1571
+ var nextFieldId = 0;
1572
+ function id(prefix) {
1573
+ nextFieldId += 1;
1574
+ return `${prefix}-${nextFieldId}`;
1575
+ }
1576
+ function descriptionIds(input) {
1577
+ return Array.from(new Set((input.getAttribute("aria-describedby") ?? "").split(/\s+/).filter(Boolean)));
1578
+ }
1579
+ function controller11(host) {
1580
+ const element = host.element;
1581
+ let activeInput = null;
1582
+ let owned = /* @__PURE__ */ new Set();
1583
+ let queued = false;
1584
+ const removeOwned = (input) => {
1585
+ if (!input || owned.size === 0) return;
1586
+ const remaining = descriptionIds(input).filter((value) => !owned.has(value));
1587
+ if (remaining.length) input.setAttribute("aria-describedby", remaining.join(" "));
1588
+ else input.removeAttribute("aria-describedby");
1589
+ };
1590
+ const wire = () => {
1591
+ const label = element.querySelector("label");
1592
+ const input = element.querySelector("input, textarea, select");
1593
+ const help = element.querySelector('[data-slot="help"]');
1594
+ const error = element.querySelector('[data-slot="error"], [role="alert"]');
1595
+ if (input !== activeInput) {
1596
+ removeOwned(activeInput);
1597
+ activeInput = input;
1598
+ owned = /* @__PURE__ */ new Set();
1599
+ }
1600
+ if (!input) return;
1601
+ if (!input.id) input.id = id("form-field-input");
1602
+ if (label && !label.getAttribute("for")) label.setAttribute("for", input.id);
1603
+ const external = descriptionIds(input).filter((value) => !owned.has(value));
1604
+ const described = [];
1605
+ if (help) {
1606
+ if (!help.id) help.id = id("form-field-help");
1607
+ described.push(help.id);
1608
+ }
1609
+ if (error) {
1610
+ if (!error.id) error.id = id("form-field-error");
1611
+ described.push(error.id);
1612
+ }
1613
+ owned = new Set(described.filter((value) => !external.includes(value)));
1614
+ const next = Array.from(/* @__PURE__ */ new Set([...external, ...described])).join(" ");
1615
+ if (next && input.getAttribute("aria-describedby") !== next) input.setAttribute("aria-describedby", next);
1616
+ else if (!next && input.hasAttribute("aria-describedby")) input.removeAttribute("aria-describedby");
1617
+ input.disabled = Boolean(host.state.disabled);
1618
+ input.required = Boolean(host.state.required);
1619
+ input.setAttribute("aria-invalid", String(Boolean(host.state.invalid)));
1620
+ };
1621
+ const schedule = () => {
1622
+ if (queued) return;
1623
+ queued = true;
1624
+ queueMicrotask(() => {
1625
+ queued = false;
1626
+ wire();
1627
+ });
1628
+ };
1629
+ const observer = new MutationObserver(schedule);
1630
+ observer.observe(element, { childList: true, subtree: true, attributes: true, attributeFilter: ["aria-describedby", "data-slot", "id", "role"] });
1631
+ const stop = host.effect(schedule);
1632
+ wire();
1633
+ return () => {
1634
+ stop();
1635
+ observer.disconnect();
1636
+ removeOwned(activeInput);
1637
+ };
1638
+ }
1639
+
1640
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-icon-button.js
1641
+ var ui_icon_button_exports = {};
1642
+ __export(ui_icon_button_exports, {
1643
+ default: () => controller12
1644
+ });
1645
+ function controller12(host) {
1646
+ const element = host.element;
1647
+ const button = element.querySelector("button");
1648
+ const apply = () => {
1649
+ const disabled3 = Boolean(host.state.disabled);
1650
+ if (host.state.anticipatory) element.setAttribute("data-ui-affordance", "button");
1651
+ else element.removeAttribute("data-ui-affordance");
1652
+ if (button) {
1653
+ button.disabled = disabled3;
1654
+ const label = String(host.state.label ?? "");
1655
+ if (label) button.setAttribute("aria-label", label);
1656
+ else button.removeAttribute("aria-label");
1657
+ }
1658
+ };
1659
+ const stop = host.effect(apply);
1660
+ apply();
1661
+ return stop;
1662
+ }
1663
+
1664
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-input.js
1665
+ var ui_input_exports = {};
1666
+ __export(ui_input_exports, {
1667
+ default: () => controller13
1668
+ });
1669
+ function triggerFor3(event) {
1670
+ if (event instanceof KeyboardEvent) return "keyboard";
1671
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
1672
+ return "programmatic";
1673
+ }
1674
+ function controller13(host) {
1675
+ const element = host.element;
1676
+ const input = element.querySelector("input");
1677
+ if (host.state.value !== void 0) host.state.internalValue = String(host.state.value);
1678
+ const apply = () => {
1679
+ if (!input) return;
1680
+ const controlled = host.state.value !== void 0;
1681
+ if (controlled) {
1682
+ host.state.internalValue = String(host.state.value);
1683
+ input.value = String(host.state.internalValue);
1684
+ }
1685
+ input.defaultValue = String(host.state.defaultValue ?? "");
1686
+ input.disabled = Boolean(host.state.disabled);
1687
+ input.readOnly = Boolean(host.state.readOnly);
1688
+ input.setAttribute("aria-invalid", String(Boolean(host.state.invalid)));
1689
+ };
1690
+ const emitValue = (name, event) => {
1691
+ if (!input) return;
1692
+ host.state.internalValue = input.value;
1693
+ host.dispatch(name, { value: input.value, trigger: triggerFor3(event) });
1694
+ };
1695
+ const onInput = (event) => emitValue("input", event);
1696
+ const onChange = (event) => emitValue("change", event);
1697
+ input?.addEventListener("input", onInput);
1698
+ input?.addEventListener("change", onChange);
1699
+ const stop = host.effect(apply);
1700
+ apply();
1701
+ return () => {
1702
+ stop();
1703
+ input?.removeEventListener("input", onInput);
1704
+ input?.removeEventListener("change", onChange);
1705
+ };
1706
+ }
1707
+
1708
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-menu.js
1709
+ var ui_menu_exports = {};
1710
+ __export(ui_menu_exports, {
1711
+ default: () => controller14
1712
+ });
1713
+ function triggerFor4(event) {
1714
+ if (event instanceof KeyboardEvent) return "keyboard";
1715
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
1716
+ return "programmatic";
1717
+ }
1718
+ function disabled2(item) {
1719
+ return item.getAttribute("aria-disabled") === "true" || item.hasAttribute("disabled") || item.getAttribute("disabled") === "true";
1720
+ }
1721
+ function controller14(host) {
1722
+ const element = host.element;
1723
+ const document = element.ownerDocument;
1724
+ const overlayId = `ui-menu-${Math.random().toString(36).slice(2, 11)}`;
1725
+ const items = () => Array.from(element.querySelectorAll('[data-component-root~="ui-menu-item"]'));
1726
+ let anchor = null;
1727
+ let surface = null;
1728
+ let lastFor;
1729
+ let lastPlacement;
1730
+ host.state.internalOpen = host.state.open === void 0 ? Boolean(host.state.defaultOpen) : Boolean(host.state.open);
1731
+ const close = (reason, trigger) => {
1732
+ if (!host.state.internalOpen) return;
1733
+ if (host.state.open === void 0) host.state.internalOpen = false;
1734
+ host.dispatch("close", { open: false, reason, trigger });
1735
+ if (reason === "escape") anchor?.focus();
1736
+ };
1737
+ const setup = () => {
1738
+ const nextFor = String(host.state.for ?? "");
1739
+ const nextPlacement = String(host.state.placement ?? "bottom-start");
1740
+ if (nextFor === lastFor && nextPlacement === lastPlacement && surface) return;
1741
+ lastFor = nextFor;
1742
+ lastPlacement = nextPlacement;
1743
+ surface?.destroy();
1744
+ anchor = nextFor ? document.getElementById(nextFor) : null;
1745
+ surface = anchor ? createAnchoredSurface(element, { anchor, placement: nextPlacement }) : null;
1746
+ };
1747
+ const apply = () => {
1748
+ if (host.state.open !== void 0) host.state.internalOpen = Boolean(host.state.open);
1749
+ setup();
1750
+ const open = Boolean(host.state.internalOpen);
1751
+ if (anchor) {
1752
+ anchor.setAttribute("aria-haspopup", "menu");
1753
+ anchor.setAttribute("aria-expanded", String(open));
1754
+ }
1755
+ if (open) {
1756
+ surface?.show();
1757
+ openOverlay({ id: overlayId, modal: false, element, relatedElements: anchor ? [anchor] : [], dismissible: true, requestClose: close });
1758
+ } else {
1759
+ surface?.hide();
1760
+ closeOverlay(document, overlayId);
1761
+ }
1762
+ };
1763
+ const select = (item, trigger) => {
1764
+ if (!item || disabled2(item)) return;
1765
+ const value = item.getAttribute("data-value") ?? item.getAttribute("value") ?? "";
1766
+ host.dispatch("select", { value, trigger });
1767
+ host.dispatch("close", { open: false, reason: "action", trigger });
1768
+ if (host.state.open === void 0) host.state.internalOpen = false;
1769
+ };
1770
+ const onClick = (event) => select(event.target.closest?.('[data-component-root~="ui-menu-item"]'), triggerFor4(event));
1771
+ const onKeydown = (event) => {
1772
+ if (event.key === "Escape") {
1773
+ event.preventDefault();
1774
+ requestTopOverlayClose(document, "escape", "keyboard");
1775
+ return;
1776
+ }
1777
+ const enabled = items().filter((item) => !disabled2(item));
1778
+ const target = event.target.closest?.('[data-component-root~="ui-menu-item"]');
1779
+ const index = target ? enabled.indexOf(target) : -1;
1780
+ if (["Enter", " "].includes(event.key)) {
1781
+ if (index >= 0) {
1782
+ event.preventDefault();
1783
+ select(target, "keyboard");
1784
+ }
1785
+ } else if (["ArrowDown", "ArrowUp"].includes(event.key) && enabled.length) {
1786
+ event.preventDefault();
1787
+ const next = event.key === "ArrowDown" ? index < 0 ? 0 : Math.min(index + 1, enabled.length - 1) : index <= 0 ? enabled.length - 1 : index - 1;
1788
+ enabled[next]?.focus();
1789
+ }
1790
+ };
1791
+ element.addEventListener("click", onClick);
1792
+ element.addEventListener("keydown", onKeydown);
1793
+ const stop = host.effect(apply);
1794
+ apply();
1795
+ return () => {
1796
+ stop();
1797
+ element.removeEventListener("click", onClick);
1798
+ element.removeEventListener("keydown", onKeydown);
1799
+ surface?.destroy();
1800
+ closeOverlay(document, overlayId);
1801
+ };
1802
+ }
1803
+
1804
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-popover.js
1805
+ var ui_popover_exports = {};
1806
+ __export(ui_popover_exports, {
1807
+ default: () => controller15
1808
+ });
1809
+ function controller15(host) {
1810
+ const element = host.element;
1811
+ const document = element.ownerDocument;
1812
+ const overlayId = `ui-popover-${Math.random().toString(36).slice(2, 11)}`;
1813
+ let anchor = null;
1814
+ let surface = null;
1815
+ let lastFor;
1816
+ let lastPlacement;
1817
+ let lastOpen;
1818
+ host.state.internalOpen = host.state.open === void 0 ? Boolean(host.state.defaultOpen) : Boolean(host.state.open);
1819
+ const close = (reason, trigger) => {
1820
+ if (host.state.open === void 0) host.state.internalOpen = false;
1821
+ host.dispatch("close", { open: false, reason, trigger });
1822
+ };
1823
+ const setup = () => {
1824
+ const nextFor = String(host.state.for ?? "");
1825
+ const nextPlacement = String(host.state.placement ?? "bottom-start");
1826
+ if (surface && nextFor === lastFor && nextPlacement === lastPlacement) return;
1827
+ lastFor = nextFor;
1828
+ lastPlacement = nextPlacement;
1829
+ surface?.destroy();
1830
+ anchor = nextFor ? document.getElementById(nextFor) : null;
1831
+ surface = anchor ? createAnchoredSurface(element, { anchor, placement: nextPlacement }) : null;
1832
+ };
1833
+ const apply = () => {
1834
+ if (host.state.open !== void 0) host.state.internalOpen = Boolean(host.state.open);
1835
+ setup();
1836
+ const open = Boolean(host.state.internalOpen);
1837
+ if (open) {
1838
+ surface?.show();
1839
+ openOverlay({ id: overlayId, modal: false, element, relatedElements: anchor ? [anchor] : [], dismissible: true, requestClose: close });
1840
+ } else {
1841
+ surface?.hide();
1842
+ closeOverlay(document, overlayId);
1843
+ }
1844
+ if (lastOpen !== void 0 && lastOpen !== open) {
1845
+ host.dispatch(open ? "open" : "close", { open, reason: "programmatic", trigger: "programmatic" });
1846
+ }
1847
+ lastOpen = open;
1848
+ };
1849
+ const onKeydown = (event) => {
1850
+ if (event.key === "Escape") requestTopOverlayClose(document, "escape", "keyboard");
1851
+ };
1852
+ element.addEventListener("keydown", onKeydown);
1853
+ const stop = host.effect(apply);
1854
+ apply();
1855
+ return () => {
1856
+ stop();
1857
+ element.removeEventListener("keydown", onKeydown);
1858
+ surface?.destroy();
1859
+ closeOverlay(document, overlayId);
1860
+ };
1861
+ }
1862
+
1863
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-radio-group.js
1864
+ var ui_radio_group_exports = {};
1865
+ __export(ui_radio_group_exports, {
1866
+ default: () => controller16
1867
+ });
1868
+ function triggerFor5(event) {
1869
+ if (event instanceof KeyboardEvent) return "keyboard";
1870
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
1871
+ return "programmatic";
1872
+ }
1873
+ function controller16(host) {
1874
+ const element = host.element;
1875
+ const groupName = String(host.state.name || `ui-radio-group-${Math.random().toString(36).slice(2, 9)}`);
1876
+ const radios = () => Array.from(element.querySelectorAll('[data-component-root~="ui-radio"]'));
1877
+ host.state.internalValue = String(host.state.value ?? "");
1878
+ let lastValue = host.state.value;
1879
+ const apply = () => {
1880
+ if (host.state.value !== lastValue) {
1881
+ lastValue = host.state.value;
1882
+ host.state.internalValue = String(host.state.value ?? "");
1883
+ }
1884
+ const disabled3 = Boolean(host.state.disabled);
1885
+ const current = String(host.state.internalValue ?? "");
1886
+ const items = radios();
1887
+ const selectedIndex = items.findIndex((radio) => (radio.getAttribute("data-value") ?? radio.getAttribute("value") ?? "") === current);
1888
+ items.forEach((radio, index) => {
1889
+ const input = radio.querySelector('input[type="radio"]');
1890
+ const checked = (radio.getAttribute("data-value") ?? radio.getAttribute("value") ?? "") === current;
1891
+ radio.checked = checked;
1892
+ radio.name = groupName;
1893
+ radio.setAttribute("aria-checked", String(checked));
1894
+ radio.disabled = disabled3;
1895
+ if (!input) return;
1896
+ input.checked = checked;
1897
+ input.name = groupName;
1898
+ input.disabled = disabled3;
1899
+ input.tabIndex = index === (selectedIndex >= 0 ? selectedIndex : 0) ? 0 : -1;
1900
+ });
1901
+ };
1902
+ const setValue = (value, trigger) => {
1903
+ const previousValue = String(host.state.internalValue ?? "");
1904
+ host.state.internalValue = value;
1905
+ apply();
1906
+ host.dispatch("select", { value, previousValue, trigger });
1907
+ host.dispatch("change", { checked: true, value, trigger });
1908
+ };
1909
+ const onChange = (event) => {
1910
+ const radio = event.target.closest?.('[data-component-root~="ui-radio"]');
1911
+ const value = radio?.getAttribute("data-value") ?? radio?.getAttribute("value") ?? "";
1912
+ if (value && value !== host.state.internalValue) setValue(value, triggerFor5(event));
1913
+ };
1914
+ const onKeydown = (event) => {
1915
+ const items = radios();
1916
+ if (!items.length) return;
1917
+ const current = items.findIndex((radio2) => (radio2.getAttribute("data-value") ?? radio2.getAttribute("value") ?? "") === host.state.internalValue);
1918
+ const vertical = host.state.orientation === "vertical";
1919
+ const previous = vertical ? "ArrowUp" : "ArrowLeft";
1920
+ const next = vertical ? "ArrowDown" : "ArrowRight";
1921
+ if (event.key !== previous && event.key !== next) return;
1922
+ event.preventDefault();
1923
+ const index = event.key === next ? current < 0 ? 0 : Math.min(current + 1, items.length - 1) : current <= 0 ? items.length - 1 : current - 1;
1924
+ const radio = items[index];
1925
+ const value = radio?.getAttribute("data-value") ?? radio?.getAttribute("value") ?? "";
1926
+ if (value) {
1927
+ setValue(value, "keyboard");
1928
+ radio.querySelector('input[type="radio"]')?.focus();
1929
+ }
1930
+ };
1931
+ element.addEventListener("change", onChange);
1932
+ element.addEventListener("keydown", onKeydown);
1933
+ const stop = host.effect(apply);
1934
+ apply();
1935
+ return () => {
1936
+ stop();
1937
+ element.removeEventListener("change", onChange);
1938
+ element.removeEventListener("keydown", onKeydown);
1939
+ };
1940
+ }
1941
+
1942
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-radio.js
1943
+ var ui_radio_exports = {};
1944
+ __export(ui_radio_exports, {
1945
+ default: () => controller17
1946
+ });
1947
+ function triggerFor6(event) {
1948
+ if (event instanceof KeyboardEvent) return "keyboard";
1949
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
1950
+ return "programmatic";
1951
+ }
1952
+ function controller17(host) {
1953
+ const element = host.element;
1954
+ const input = element.querySelector('input[type="radio"]');
1955
+ host.state.internalChecked = host.state.checked === void 0 ? Boolean(host.state.defaultChecked) : Boolean(host.state.checked);
1956
+ const apply = () => {
1957
+ if (host.state.checked !== void 0) host.state.internalChecked = Boolean(host.state.checked);
1958
+ const disabled3 = Boolean(host.state.disabled);
1959
+ element.setAttribute("aria-disabled", String(disabled3));
1960
+ element.setAttribute("aria-checked", String(Boolean(host.state.internalChecked)));
1961
+ if (!input) return;
1962
+ input.checked = Boolean(host.state.internalChecked);
1963
+ input.disabled = disabled3;
1964
+ input.name = String(host.state.name ?? "");
1965
+ input.required = Boolean(host.state.required);
1966
+ input.value = String(host.state.value ?? "on");
1967
+ };
1968
+ const onChange = (event) => {
1969
+ if (!input?.checked) return;
1970
+ if (host.state.checked === void 0) host.state.internalChecked = true;
1971
+ else apply();
1972
+ host.dispatch("change", { checked: true, value: String(host.state.value ?? "on"), trigger: triggerFor6(event) });
1973
+ };
1974
+ input?.addEventListener("change", onChange);
1975
+ const stop = host.effect(apply);
1976
+ apply();
1977
+ return () => {
1978
+ stop();
1979
+ input?.removeEventListener("change", onChange);
1980
+ };
1981
+ }
1982
+
1983
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-search-result-row.js
1984
+ var ui_search_result_row_exports = {};
1985
+ __export(ui_search_result_row_exports, {
1986
+ default: () => controller18,
1987
+ hasContent: () => hasContent
1988
+ });
1989
+ function hasContent(region) {
1990
+ return [...region.childNodes].some((node) => node.nodeType !== 3 || Boolean(node.textContent?.trim()));
1991
+ }
1992
+ function controller18(host) {
1993
+ const regions = {
1994
+ hasLeading: host.element.querySelector(".search-result-row__leading"),
1995
+ hasMeta: host.element.querySelector(".search-result-row__meta"),
1996
+ hasExcerpt: host.element.querySelector(".search-result-row__excerpt"),
1997
+ hasTrailing: host.element.querySelector(".search-result-row__trailing")
1998
+ };
1999
+ const syncSlots = () => {
2000
+ for (const [state, region] of Object.entries(regions)) host.state[state] = Boolean(region && hasContent(region));
2001
+ };
2002
+ const observer = new MutationObserver(syncSlots);
2003
+ for (const region of Object.values(regions)) {
2004
+ if (region) observer.observe(region, { childList: true, subtree: true });
2005
+ }
2006
+ syncSlots();
2007
+ return () => observer.disconnect();
2008
+ }
2009
+
2010
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-search-shell.js
2011
+ var ui_search_shell_exports = {};
2012
+ __export(ui_search_shell_exports, {
2013
+ default: () => controller19,
2014
+ hasContent: () => hasContent2
2015
+ });
2016
+ function hasContent2(region) {
2017
+ return [...region.childNodes].some((node) => node.nodeType !== 3 || Boolean(node.textContent?.trim()));
2018
+ }
2019
+ function controller19(host) {
2020
+ const status = host.element.querySelector(".search-shell__status");
2021
+ const footer = host.element.querySelector(".search-shell__footer");
2022
+ const syncSlots = () => {
2023
+ if (status) status.hidden = !hasContent2(status);
2024
+ if (footer) footer.hidden = !hasContent2(footer);
2025
+ };
2026
+ const observer = new MutationObserver(syncSlots);
2027
+ if (status) observer.observe(status, { childList: true, subtree: true });
2028
+ if (footer) observer.observe(footer, { childList: true, subtree: true });
2029
+ syncSlots();
2030
+ return () => observer.disconnect();
2031
+ }
2032
+
2033
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-select.js
2034
+ var ui_select_exports = {};
2035
+ __export(ui_select_exports, {
2036
+ default: () => controller20
2037
+ });
2038
+ function triggerFor7(event) {
2039
+ if (event instanceof KeyboardEvent) return "keyboard";
2040
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
2041
+ return "programmatic";
2042
+ }
2043
+ function controller20(host) {
2044
+ const element = host.element;
2045
+ const select = element.querySelector("select");
2046
+ let initialized = false;
2047
+ if (host.state.value !== void 0) host.state.internalValue = String(host.state.value);
2048
+ const apply = () => {
2049
+ if (!select) return;
2050
+ if (host.state.value !== void 0) {
2051
+ host.state.internalValue = String(host.state.value);
2052
+ select.value = String(host.state.internalValue);
2053
+ } else if (!initialized && host.state.defaultValue !== void 0) {
2054
+ select.value = String(host.state.defaultValue);
2055
+ }
2056
+ initialized = true;
2057
+ select.disabled = Boolean(host.state.disabled);
2058
+ select.required = Boolean(host.state.required);
2059
+ select.setAttribute("aria-invalid", String(Boolean(host.state.invalid)));
2060
+ };
2061
+ const emitValue = (name, event) => {
2062
+ if (!select) return;
2063
+ host.state.internalValue = select.value;
2064
+ host.dispatch(name, { value: select.value, trigger: triggerFor7(event) });
2065
+ };
2066
+ const onInput = (event) => emitValue("input", event);
2067
+ const onChange = (event) => emitValue("change", event);
2068
+ select?.addEventListener("input", onInput);
2069
+ select?.addEventListener("change", onChange);
2070
+ const stop = host.effect(apply);
2071
+ apply();
2072
+ return () => {
2073
+ stop();
2074
+ select?.removeEventListener("input", onInput);
2075
+ select?.removeEventListener("change", onChange);
2076
+ };
2077
+ }
2078
+
2079
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-switch.js
2080
+ var ui_switch_exports = {};
2081
+ __export(ui_switch_exports, {
2082
+ default: () => controller21
2083
+ });
2084
+ function controller21(host) {
2085
+ const element = host.element;
2086
+ const input = element.querySelector('input[type="checkbox"]');
2087
+ host.state.internalChecked = host.state.checked === void 0 ? Boolean(host.state.defaultChecked) : Boolean(host.state.checked);
2088
+ const apply = () => {
2089
+ if (host.state.checked !== void 0) host.state.internalChecked = Boolean(host.state.checked);
2090
+ const checked = Boolean(host.state.internalChecked);
2091
+ const disabled3 = Boolean(host.state.disabled);
2092
+ element.setAttribute("aria-checked", String(checked));
2093
+ element.setAttribute("aria-disabled", String(disabled3));
2094
+ element.tabIndex = disabled3 ? -1 : 0;
2095
+ if (!input) return;
2096
+ input.checked = checked;
2097
+ input.disabled = disabled3;
2098
+ input.required = Boolean(host.state.required);
2099
+ input.value = String(host.state.value ?? "on");
2100
+ };
2101
+ const toggle = (trigger) => {
2102
+ if (host.state.disabled) return;
2103
+ const checked = !Boolean(host.state.internalChecked);
2104
+ if (host.state.checked === void 0) host.state.internalChecked = checked;
2105
+ apply();
2106
+ host.dispatch("change", { checked, value: String(host.state.value ?? "on"), trigger });
2107
+ };
2108
+ const onKeydown = (event) => {
2109
+ if (event.key !== " " || host.state.disabled) return;
2110
+ event.preventDefault();
2111
+ toggle("keyboard");
2112
+ };
2113
+ const onClick = (event) => {
2114
+ if (event.target !== input) toggle("pointer");
2115
+ };
2116
+ const onChange = () => {
2117
+ if (!input) return;
2118
+ const checked = input.checked;
2119
+ if (host.state.checked === void 0) host.state.internalChecked = checked;
2120
+ host.dispatch("change", { checked, value: String(host.state.value ?? "on"), trigger: "pointer" });
2121
+ if (host.state.checked !== void 0) apply();
2122
+ };
2123
+ element.addEventListener("keydown", onKeydown);
2124
+ element.addEventListener("click", onClick);
2125
+ input?.addEventListener("change", onChange);
2126
+ const stop = host.effect(apply);
2127
+ apply();
2128
+ return () => {
2129
+ stop();
2130
+ element.removeEventListener("keydown", onKeydown);
2131
+ element.removeEventListener("click", onClick);
2132
+ input?.removeEventListener("change", onChange);
2133
+ };
2134
+ }
2135
+
2136
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-tabs.js
2137
+ var ui_tabs_exports = {};
2138
+ __export(ui_tabs_exports, {
2139
+ default: () => controller22
2140
+ });
2141
+ function triggerFor8(event) {
2142
+ if (event instanceof KeyboardEvent) return "keyboard";
2143
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
2144
+ return "programmatic";
2145
+ }
2146
+ function controller22(host) {
2147
+ const element = host.element;
2148
+ const tabs = () => Array.from(element.querySelectorAll('[role="tab"]'));
2149
+ host.state.internalValue = host.state.value === void 0 ? String(host.state.defaultValue ?? "") : String(host.state.value);
2150
+ if (host.state.value === void 0 && !host.state.internalValue) {
2151
+ const first = tabs()[0];
2152
+ host.state.internalValue = first?.id || first?.getAttribute("aria-controls") || "";
2153
+ }
2154
+ const apply = () => {
2155
+ if (host.state.value !== void 0) host.state.internalValue = String(host.state.value);
2156
+ for (const tab of tabs()) {
2157
+ const value = tab.id || tab.getAttribute("aria-controls") || "";
2158
+ const selected = value === host.state.internalValue;
2159
+ tab.setAttribute("aria-selected", String(selected));
2160
+ tab.tabIndex = selected ? 0 : -1;
2161
+ const controls = tab.getAttribute("aria-controls");
2162
+ const panel = controls && (element.querySelector(`#${CSS.escape(controls)}`) || element.ownerDocument.getElementById(controls));
2163
+ if (panel) panel.hidden = !selected;
2164
+ }
2165
+ };
2166
+ const select = (tab, trigger) => {
2167
+ const value = tab.id || tab.getAttribute("aria-controls") || "";
2168
+ if (!value) return;
2169
+ const previousValue = String(host.state.internalValue || "") || void 0;
2170
+ if (host.state.value === void 0) host.state.internalValue = value;
2171
+ apply();
2172
+ host.dispatch("select", { value, previousValue, trigger });
2173
+ };
2174
+ const onClick = (event) => {
2175
+ const tab = event.target.closest?.('[role="tab"]');
2176
+ if (tab && element.contains(tab)) select(tab, triggerFor8(event));
2177
+ };
2178
+ const onKeydown = (event) => {
2179
+ const tab = event.target.closest?.('[role="tab"]');
2180
+ if (!tab || !element.contains(tab)) return;
2181
+ const items = tabs();
2182
+ const index = items.indexOf(tab);
2183
+ const vertical = host.state.orientation === "vertical";
2184
+ const previous = vertical ? "ArrowUp" : "ArrowLeft";
2185
+ const next = vertical ? "ArrowDown" : "ArrowRight";
2186
+ if (event.key !== previous && event.key !== next) return;
2187
+ event.preventDefault();
2188
+ const nextIndex = event.key === next ? Math.min(index + 1, items.length - 1) : index <= 0 ? items.length - 1 : index - 1;
2189
+ const nextTab = items[nextIndex];
2190
+ if (nextTab) {
2191
+ select(nextTab, "keyboard");
2192
+ nextTab.focus();
2193
+ }
2194
+ };
2195
+ element.addEventListener("click", onClick);
2196
+ element.addEventListener("keydown", onKeydown);
2197
+ const stop = host.effect(apply);
2198
+ apply();
2199
+ return () => {
2200
+ stop();
2201
+ element.removeEventListener("click", onClick);
2202
+ element.removeEventListener("keydown", onKeydown);
2203
+ };
2204
+ }
2205
+
2206
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-textarea.js
2207
+ var ui_textarea_exports = {};
2208
+ __export(ui_textarea_exports, {
2209
+ default: () => controller23
2210
+ });
2211
+ function triggerFor9(event) {
2212
+ if (event instanceof KeyboardEvent) return "keyboard";
2213
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
2214
+ return "programmatic";
2215
+ }
2216
+ function controller23(host) {
2217
+ const element = host.element;
2218
+ const textarea = element.querySelector("textarea");
2219
+ if (host.state.value !== void 0) host.state.internalValue = String(host.state.value);
2220
+ const apply = () => {
2221
+ if (!textarea) return;
2222
+ if (host.state.value !== void 0) {
2223
+ host.state.internalValue = String(host.state.value);
2224
+ textarea.value = String(host.state.internalValue);
2225
+ }
2226
+ textarea.defaultValue = String(host.state.defaultValue ?? "");
2227
+ textarea.disabled = Boolean(host.state.disabled);
2228
+ textarea.readOnly = Boolean(host.state.readOnly);
2229
+ textarea.rows = Number(host.state.rows ?? 4);
2230
+ textarea.setAttribute("aria-invalid", String(Boolean(host.state.invalid)));
2231
+ };
2232
+ const emitValue = (name, event) => {
2233
+ if (!textarea) return;
2234
+ host.state.internalValue = textarea.value;
2235
+ host.dispatch(name, { value: textarea.value, trigger: triggerFor9(event) });
2236
+ };
2237
+ const onInput = (event) => emitValue("input", event);
2238
+ const onChange = (event) => emitValue("change", event);
2239
+ textarea?.addEventListener("input", onInput);
2240
+ textarea?.addEventListener("change", onChange);
2241
+ const stop = host.effect(apply);
2242
+ apply();
2243
+ return () => {
2244
+ stop();
2245
+ textarea?.removeEventListener("input", onInput);
2246
+ textarea?.removeEventListener("change", onChange);
2247
+ };
2248
+ }
2249
+
2250
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-toast-region.js
2251
+ var ui_toast_region_exports = {};
2252
+ __export(ui_toast_region_exports, {
2253
+ default: () => controller24
2254
+ });
2255
+ function triggerFor10(event) {
2256
+ if (event instanceof KeyboardEvent) return "keyboard";
2257
+ if (event instanceof MouseEvent || event instanceof PointerEvent) return "pointer";
2258
+ return "programmatic";
2259
+ }
2260
+ function controller24(host) {
2261
+ const element = host.element;
2262
+ let pendingDismiss = null;
2263
+ element.setAttribute("popover", "manual");
2264
+ element.dataset.uiPositioning = "viewport";
2265
+ const toasts = () => Array.from(element.querySelectorAll("[data-ui-toast]"));
2266
+ const setSurfaceOpen = (open) => {
2267
+ element.hidden = !open;
2268
+ if (open && typeof element.showPopover === "function") {
2269
+ try {
2270
+ if (!element.matches(":popover-open")) element.showPopover();
2271
+ } catch {
2272
+ }
2273
+ } else if (!open && typeof element.hidePopover === "function") {
2274
+ try {
2275
+ if (element.matches(":popover-open")) element.hidePopover();
2276
+ } catch {
2277
+ }
2278
+ }
2279
+ };
2280
+ const sync = () => {
2281
+ const open = Boolean(host.state.open) && toasts().length > 0;
2282
+ const wasOpen = Boolean(host.state.internalOpen);
2283
+ const completed = pendingDismiss && !element.contains(pendingDismiss.toast) ? pendingDismiss : null;
2284
+ host.state.internalOpen = open;
2285
+ setSurfaceOpen(open);
2286
+ if (wasOpen && !open && completed) {
2287
+ host.dispatch("close", { open: false, reason: "action", trigger: completed.trigger });
2288
+ }
2289
+ if (completed || !host.state.open) pendingDismiss = null;
2290
+ };
2291
+ const onClick = (event) => {
2292
+ const dismiss = event.target.closest?.("[data-ui-toast-dismiss]");
2293
+ const toast = dismiss?.closest?.("[data-ui-toast]");
2294
+ if (!toast) return;
2295
+ const trigger = triggerFor10(event);
2296
+ pendingDismiss = { toast, trigger };
2297
+ host.dispatch("dismiss", { id: toast.id || "", reason: "action", trigger });
2298
+ };
2299
+ const observer = new MutationObserver(sync);
2300
+ observer.observe(element, { childList: true, subtree: true });
2301
+ element.addEventListener("click", onClick);
2302
+ const stop = host.effect(sync);
2303
+ sync();
2304
+ return () => {
2305
+ stop();
2306
+ observer.disconnect();
2307
+ element.removeEventListener("click", onClick);
2308
+ setSurfaceOpen(false);
2309
+ };
2310
+ }
2311
+
2312
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-tooltip.js
2313
+ var ui_tooltip_exports = {};
2314
+ __export(ui_tooltip_exports, {
2315
+ default: () => controller25
2316
+ });
2317
+ function controller25(host) {
2318
+ const element = host.element;
2319
+ const document = element.ownerDocument;
2320
+ const overlayId = element.id || `ui-tooltip-${Math.random().toString(36).slice(2, 11)}`;
2321
+ if (!element.id) element.id = overlayId;
2322
+ let pinned = false;
2323
+ let focused = false;
2324
+ let trigger = null;
2325
+ let surface = null;
2326
+ let showTimer = null;
2327
+ let hideTimer = null;
2328
+ let lastFor;
2329
+ let lastPlacement;
2330
+ host.state.internalOpen = host.state.open === void 0 ? Boolean(host.state.defaultOpen) : Boolean(host.state.open);
2331
+ const clearShow = () => {
2332
+ if (showTimer !== null) clearTimeout(showTimer);
2333
+ showTimer = null;
2334
+ };
2335
+ const clearHide = () => {
2336
+ if (hideTimer !== null) clearTimeout(hideTimer);
2337
+ hideTimer = null;
2338
+ };
2339
+ const clearTimers = () => {
2340
+ clearShow();
2341
+ clearHide();
2342
+ };
2343
+ const setOpen = (open, input) => {
2344
+ if (Boolean(host.state.internalOpen) === open) return;
2345
+ if (host.state.open === void 0) host.state.internalOpen = open;
2346
+ host.dispatch(open ? "open" : "close", { open, reason: "action", trigger: input });
2347
+ };
2348
+ const onClick = (event) => {
2349
+ if (!host.state.toggleOnClick) return;
2350
+ clearTimers();
2351
+ pinned = !pinned;
2352
+ setOpen(pinned, event.detail === 0 ? "keyboard" : "pointer");
2353
+ };
2354
+ const onKeydown = (event) => {
2355
+ if (event.key === "Escape") clearTimers();
2356
+ };
2357
+ const onEnter = (event) => {
2358
+ if (event.pointerType === "touch") return;
2359
+ clearHide();
2360
+ if (host.state.internalOpen || showTimer !== null) return;
2361
+ showTimer = setTimeout(() => {
2362
+ showTimer = null;
2363
+ setOpen(true, "pointer");
2364
+ }, Math.max(0, Number(host.state.showDelay ?? 500)));
2365
+ };
2366
+ const onLeave = () => {
2367
+ clearShow();
2368
+ if (focused || pinned || !host.state.internalOpen || hideTimer !== null) return;
2369
+ hideTimer = setTimeout(() => {
2370
+ hideTimer = null;
2371
+ setOpen(false, "pointer");
2372
+ }, Math.max(0, Number(host.state.hideDelay ?? 100)));
2373
+ };
2374
+ const onFocusin = () => {
2375
+ focused = true;
2376
+ clearTimers();
2377
+ setOpen(true, "keyboard");
2378
+ };
2379
+ const onFocusout = (event) => {
2380
+ if (event.relatedTarget && element.contains(event.relatedTarget)) return;
2381
+ focused = false;
2382
+ pinned = false;
2383
+ clearTimers();
2384
+ setOpen(false, "keyboard");
2385
+ };
2386
+ const detach = () => {
2387
+ if (!trigger) return;
2388
+ const ids = (trigger.getAttribute("aria-describedby") ?? "").split(/\s+/).filter((id2) => id2 && id2 !== element.id);
2389
+ if (ids.length) trigger.setAttribute("aria-describedby", ids.join(" "));
2390
+ else trigger.removeAttribute("aria-describedby");
2391
+ trigger.removeEventListener("click", onClick);
2392
+ trigger.removeEventListener("keydown", onKeydown);
2393
+ trigger.removeEventListener("pointerenter", onEnter);
2394
+ trigger.removeEventListener("pointerleave", onLeave);
2395
+ trigger.removeEventListener("focusin", onFocusin);
2396
+ trigger.removeEventListener("focusout", onFocusout);
2397
+ };
2398
+ const attach = () => {
2399
+ if (!trigger) return;
2400
+ const ids = new Set((trigger.getAttribute("aria-describedby") ?? "").split(/\s+/).filter(Boolean));
2401
+ ids.add(element.id);
2402
+ trigger.setAttribute("aria-describedby", [...ids].join(" "));
2403
+ trigger.addEventListener("click", onClick);
2404
+ trigger.addEventListener("keydown", onKeydown);
2405
+ trigger.addEventListener("pointerenter", onEnter);
2406
+ trigger.addEventListener("pointerleave", onLeave);
2407
+ trigger.addEventListener("focusin", onFocusin);
2408
+ trigger.addEventListener("focusout", onFocusout);
2409
+ };
2410
+ const setup = () => {
2411
+ const nextFor = String(host.state.for ?? "");
2412
+ const nextPlacement = String(host.state.placement ?? "top-start");
2413
+ if (surface && nextFor === lastFor && nextPlacement === lastPlacement) return;
2414
+ lastFor = nextFor;
2415
+ lastPlacement = nextPlacement;
2416
+ const nextTrigger = nextFor ? document.getElementById(nextFor) : element.previousElementSibling;
2417
+ if (nextTrigger !== trigger) {
2418
+ detach();
2419
+ trigger = nextTrigger;
2420
+ attach();
2421
+ }
2422
+ surface?.destroy();
2423
+ surface = createAnchoredSurface(element, { anchor: trigger, placement: nextPlacement });
2424
+ };
2425
+ const close = (reason, input) => {
2426
+ if (reason !== "escape" && !(reason === "light-dismiss" && host.state.toggleOnClick)) return;
2427
+ pinned = false;
2428
+ clearTimers();
2429
+ if (host.state.open === void 0) host.state.internalOpen = false;
2430
+ host.dispatch("close", { open: false, reason, trigger: input });
2431
+ };
2432
+ const apply = () => {
2433
+ if (host.state.open !== void 0) host.state.internalOpen = Boolean(host.state.open);
2434
+ setup();
2435
+ const open = Boolean(host.state.internalOpen);
2436
+ element.hidden = !open;
2437
+ if (open) {
2438
+ surface?.show();
2439
+ openOverlay({ id: overlayId, modal: false, element, relatedElements: trigger ? [trigger] : [], dismissible: true, requestClose: close });
2440
+ } else {
2441
+ surface?.hide();
2442
+ closeOverlay(document, overlayId);
2443
+ }
2444
+ };
2445
+ const onSurfaceEnter = () => clearHide();
2446
+ element.addEventListener("pointerenter", onSurfaceEnter);
2447
+ element.addEventListener("pointerleave", onLeave);
2448
+ const stop = host.effect(apply);
2449
+ apply();
2450
+ return () => {
2451
+ stop();
2452
+ clearTimers();
2453
+ detach();
2454
+ surface?.destroy();
2455
+ element.removeEventListener("pointerenter", onSurfaceEnter);
2456
+ element.removeEventListener("pointerleave", onLeave);
2457
+ closeOverlay(document, overlayId);
2458
+ };
2459
+ }
2460
+
2461
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-top-bar.js
2462
+ var ui_top_bar_exports = {};
2463
+ __export(ui_top_bar_exports, {
2464
+ default: () => controller26
2465
+ });
2466
+ function hasContent3(region) {
2467
+ return [...region.childNodes].some((node) => node.nodeType !== 3 || Boolean(node.textContent?.trim()));
2468
+ }
2469
+ function controller26(host) {
2470
+ const regions = ["leading", "search", "actions"].map((name) => host.element.querySelector(`.top-bar__${name}`)).filter(Boolean);
2471
+ const syncSlots = () => {
2472
+ for (const region of regions) region.hidden = !hasContent3(region);
2473
+ };
2474
+ const observer = new MutationObserver(syncSlots);
2475
+ for (const region of regions) observer.observe(region, { childList: true, subtree: true });
2476
+ syncSlots();
2477
+ return () => observer.disconnect();
2478
+ }
2479
+
2480
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-tree-item.js
2481
+ var ui_tree_item_exports = {};
2482
+ __export(ui_tree_item_exports, {
2483
+ default: () => controller27
2484
+ });
2485
+ function triggerFor11(event) {
2486
+ if (typeof KeyboardEvent !== "undefined" && event instanceof KeyboardEvent) return "keyboard";
2487
+ if (typeof MouseEvent !== "undefined" && event instanceof MouseEvent || typeof PointerEvent !== "undefined" && event instanceof PointerEvent || ["click", "pointerdown", "pointerup"].includes(event.type)) return "pointer";
2488
+ return "programmatic";
2489
+ }
2490
+ function parentItem(element) {
2491
+ return element.parentElement?.closest('[data-component-root~="ui-tree-item"]') ?? null;
2492
+ }
2493
+ function controller27(host) {
2494
+ const element = host.element;
2495
+ const row = element.querySelector('[part="row"]');
2496
+ const disclosure = element.querySelector('[part="disclosure"]');
2497
+ const children = element.querySelector('[part="children"]');
2498
+ const dragHandle = element.querySelector('[part="drag-handle"]');
2499
+ host.state.internalExpanded = host.state.expanded === void 0 ? Boolean(host.state.defaultExpanded) : Boolean(host.state.expanded);
2500
+ const expanded = () => host.state.expanded === void 0 ? Boolean(host.state.internalExpanded) : Boolean(host.state.expanded);
2501
+ const updateLevel = () => {
2502
+ const tree = element.closest('[data-component-root~="ui-tree"]');
2503
+ let ancestor = parentItem(element);
2504
+ let level = 1;
2505
+ while (ancestor && tree?.contains(ancestor)) {
2506
+ level += 1;
2507
+ ancestor = parentItem(ancestor);
2508
+ }
2509
+ host.state.structuralLevel = level;
2510
+ };
2511
+ const apply = () => {
2512
+ if (host.state.expanded !== void 0) host.state.internalExpanded = Boolean(host.state.expanded);
2513
+ const container = Boolean(host.state.container);
2514
+ const disabled3 = Boolean(host.state.disabled);
2515
+ const open = container && expanded();
2516
+ const level = Number(host.state.structuralLevel ?? 1);
2517
+ element.setAttribute("role", "treeitem");
2518
+ if (host.state.label) element.setAttribute("aria-label", String(host.state.label));
2519
+ else element.removeAttribute("aria-label");
2520
+ element.setAttribute("aria-level", String(level));
2521
+ element.setAttribute("aria-selected", String(Boolean(host.state.selected)));
2522
+ element.setAttribute("aria-disabled", String(disabled3));
2523
+ if (container) element.setAttribute("aria-expanded", String(open));
2524
+ else element.removeAttribute("aria-expanded");
2525
+ element.tabIndex = disabled3 || !host.state.tabStop ? -1 : 0;
2526
+ element.style.setProperty("--ui-tree-item-depth", String(level - 1));
2527
+ element.style.marginInlineStart = level > 1 ? "var(--ui-tree-indent, 16px)" : "0px";
2528
+ if (children) children.hidden = !open;
2529
+ if (disclosure) {
2530
+ disclosure.disabled = disabled3;
2531
+ disclosure.setAttribute("aria-expanded", String(open));
2532
+ disclosure.setAttribute("aria-label", `${open ? "Collapse" : "Expand"} ${host.state.label || "item"}`);
2533
+ }
2534
+ disclosure?.querySelector(".disclosure-icon")?.classList.toggle("disclosure-icon--expanded", open);
2535
+ if (dragHandle) {
2536
+ const label = `Drag ${host.state.label || "item"} to reorder`;
2537
+ dragHandle.setAttribute("aria-label", label);
2538
+ dragHandle.title = label;
2539
+ dragHandle.draggable = Boolean(host.state.sortable) && !disabled3;
2540
+ }
2541
+ };
2542
+ const setExpanded = (open, trigger) => {
2543
+ if (!host.state.container || host.state.disabled || expanded() === open) return;
2544
+ if (host.state.expanded === void 0) host.state.internalExpanded = open;
2545
+ apply();
2546
+ host.dispatch("expand", { id: String(host.state.itemId ?? ""), expanded: open, trigger });
2547
+ element.dispatchEvent(new CustomEvent("ui-tree-expansion-change", { bubbles: true }));
2548
+ };
2549
+ const onAutoExpand = () => setExpanded(true, "pointer");
2550
+ const onStructure = () => {
2551
+ updateLevel();
2552
+ apply();
2553
+ };
2554
+ const onRoving = (event) => {
2555
+ host.state.tabStop = Boolean(event.detail?.active) && !host.state.disabled;
2556
+ };
2557
+ const onExpansionRequest = (event) => {
2558
+ if (typeof event.detail?.expanded === "boolean") setExpanded(event.detail.expanded, event.detail.trigger ?? "keyboard");
2559
+ };
2560
+ const onDisclosureClick = (event) => {
2561
+ event.stopPropagation();
2562
+ setExpanded(!expanded(), triggerFor11(event));
2563
+ };
2564
+ const onDisclosureKeydown = (event) => {
2565
+ if (!["ArrowRight", "ArrowLeft"].includes(event.key)) return;
2566
+ event.preventDefault();
2567
+ event.stopPropagation();
2568
+ setExpanded(event.key === "ArrowRight", "keyboard");
2569
+ };
2570
+ const onRowClick = (event) => {
2571
+ if (!host.state.container || host.state.disabled) return;
2572
+ const interactive = event.composedPath().some((node) => node instanceof HTMLElement && (node.matches('a, button, input, select, textarea, [role="button"], [role="link"]') || node.getAttribute("slot") === "actions"));
2573
+ if (!interactive) setExpanded(!expanded(), triggerFor11(event));
2574
+ };
2575
+ element.addEventListener("ui-tree-auto-expand", onAutoExpand);
2576
+ element.addEventListener("ui-tree-structure-sync", onStructure);
2577
+ element.addEventListener("ui-tree-roving-tab-stop", onRoving);
2578
+ element.addEventListener("ui-tree-request-expanded", onExpansionRequest);
2579
+ disclosure?.addEventListener("click", onDisclosureClick);
2580
+ disclosure?.addEventListener("keydown", onDisclosureKeydown);
2581
+ row?.addEventListener("click", onRowClick);
2582
+ updateLevel();
2583
+ const stop = host.effect(apply);
2584
+ apply();
2585
+ return () => {
2586
+ stop();
2587
+ element.removeEventListener("ui-tree-auto-expand", onAutoExpand);
2588
+ element.removeEventListener("ui-tree-structure-sync", onStructure);
2589
+ element.removeEventListener("ui-tree-roving-tab-stop", onRoving);
2590
+ element.removeEventListener("ui-tree-request-expanded", onExpansionRequest);
2591
+ disclosure?.removeEventListener("click", onDisclosureClick);
2592
+ disclosure?.removeEventListener("keydown", onDisclosureKeydown);
2593
+ row?.removeEventListener("click", onRowClick);
2594
+ };
2595
+ }
2596
+
2597
+ // ../../tools/migrate-html-next/generated/core/components/controllers/ui-tree.js
2598
+ var ui_tree_exports = {};
2599
+ __export(ui_tree_exports, {
2600
+ default: () => controller28
2601
+ });
2602
+ function classify(rect, y, acceptsChildren) {
2603
+ const progress = rect.height > 0 ? Math.min(1, Math.max(0, (y - rect.top) / rect.height)) : 0.5;
2604
+ if (!acceptsChildren) return progress < 0.5 ? "before" : "after";
2605
+ if (progress < 0.25) return "before";
2606
+ if (progress > 0.75) return "after";
2607
+ return "inside";
2608
+ }
2609
+ function itemId(item) {
2610
+ return item.dataset.itemId || item.getAttribute("item-id") || "";
2611
+ }
2612
+ function parentItem2(item, tree) {
2613
+ const parent = item.parentElement?.closest('[data-component-root~="ui-tree-item"]') ?? null;
2614
+ return parent && tree.contains(parent) ? parent : null;
2615
+ }
2616
+ function controller28(host) {
2617
+ const element = host.element;
2618
+ const document = element.ownerDocument;
2619
+ const itemSelector = '[data-component-root~="ui-tree-item"]';
2620
+ let source = null;
2621
+ let target = null;
2622
+ let position = null;
2623
+ let rejection = null;
2624
+ let rejectedTarget = null;
2625
+ let rejectedPosition = null;
2626
+ let tabStop = null;
2627
+ let hoverTimer = null;
2628
+ let hoverKey = null;
2629
+ const allItems = () => Array.from(element.querySelectorAll(itemSelector));
2630
+ const visibleItems = () => allItems().filter((item) => item.getClientRects().length > 0 && item.getAttribute("aria-disabled") !== "true");
2631
+ const rowFor = (item) => item.querySelector('[part="row"]');
2632
+ const acceptsChildren = (item) => item.getAttribute("data-container") === "true" && item.getAttribute("aria-disabled") !== "true";
2633
+ const metadata = (item) => ({
2634
+ type: item.dataset.dragType || item.getAttribute("drag-type") || "item",
2635
+ scope: item.dataset.dropScope || item.getAttribute("drop-scope") || "",
2636
+ accepts: (item.dataset.accepts || item.getAttribute("accepts") || "").split(",").map((value) => value.trim()).filter(Boolean)
2637
+ });
2638
+ const depth = (item) => Number(item.dataset.dropDepth ?? item.getAttribute("drop-depth")) || Number(item.getAttribute("aria-level")) || 1;
2639
+ const subtreeDepth = (item) => {
2640
+ const override = item.dataset.subtreeDepth ?? item.getAttribute("subtree-depth");
2641
+ if (override != null) return Math.max(0, Math.floor(Number(override)));
2642
+ return Array.from(item.querySelectorAll(itemSelector)).reduce((deepest, descendant) => {
2643
+ let nesting = 0;
2644
+ let ancestor = parentItem2(descendant, element);
2645
+ while (ancestor && ancestor !== item) {
2646
+ nesting += 1;
2647
+ ancestor = parentItem2(ancestor, element);
2648
+ }
2649
+ return ancestor === item ? Math.max(deepest, nesting + 1) : deepest;
2650
+ }, 0);
2651
+ };
2652
+ const rejected = (from, to, nextPosition) => {
2653
+ if (from.contains(to)) return { reason: "descendant" };
2654
+ const fromMeta = metadata(from);
2655
+ const toMeta = metadata(to);
2656
+ if (nextPosition === "inside") {
2657
+ if (!acceptsChildren(to) || toMeta.accepts.length && !toMeta.accepts.includes(fromMeta.type)) return { reason: "incompatible" };
2658
+ } else if (fromMeta.type !== toMeta.type) return { reason: "incompatible" };
2659
+ const maxDepth = Math.max(0, Math.floor(Number(host.state.maxDepth ?? 0)));
2660
+ if (maxDepth > 0) {
2661
+ const resultingDepth = Math.max(0, Math.floor(depth(to))) + (nextPosition === "inside" ? 1 : 0) + subtreeDepth(from);
2662
+ if (resultingDepth > maxDepth) return { reason: "max-depth", maxDepth, resultingDepth };
2663
+ }
2664
+ return null;
2665
+ };
2666
+ const cancelHover = () => {
2667
+ if (hoverTimer !== null) clearTimeout(hoverTimer);
2668
+ hoverTimer = null;
2669
+ hoverKey = null;
2670
+ };
2671
+ const expandTarget = (id2) => {
2672
+ const item = allItems().find((candidate) => itemId(candidate) === id2);
2673
+ if (item?.getAttribute("aria-expanded") === "false") item.dispatchEvent(new CustomEvent("ui-tree-auto-expand"));
2674
+ };
2675
+ const scheduleHover = (id2) => {
2676
+ if (hoverKey === id2 && hoverTimer !== null) return;
2677
+ cancelHover();
2678
+ hoverKey = id2;
2679
+ hoverTimer = setTimeout(() => {
2680
+ const key = hoverKey;
2681
+ hoverTimer = null;
2682
+ hoverKey = null;
2683
+ if (key) expandTarget(key);
2684
+ }, Math.max(0, Number(host.state.hoverExpandDelay ?? 700)));
2685
+ };
2686
+ const clearTarget = () => {
2687
+ target?.removeAttribute("data-drop-position");
2688
+ target = null;
2689
+ position = null;
2690
+ cancelHover();
2691
+ };
2692
+ const finish = () => {
2693
+ source?.removeAttribute("data-dragging");
2694
+ source = null;
2695
+ clearTarget();
2696
+ rejection = null;
2697
+ rejectedTarget = null;
2698
+ rejectedPosition = null;
2699
+ };
2700
+ const itemFromEvent = (event) => event.composedPath().find((node) => node instanceof HTMLElement && node.matches?.(itemSelector)) ?? null;
2701
+ const itemAtPoint = (x, y) => document.elementFromPoint(x, y)?.closest?.(itemSelector) ?? null;
2702
+ const updateTarget = (nextTarget, y, transfer) => {
2703
+ if (!source || !nextTarget || nextTarget === source) {
2704
+ clearTarget();
2705
+ rejection = rejectedTarget = rejectedPosition = null;
2706
+ return false;
2707
+ }
2708
+ const row = rowFor(nextTarget);
2709
+ if (!row) return false;
2710
+ const nextPosition = classify(row.getBoundingClientRect(), y, acceptsChildren(nextTarget));
2711
+ const nextRejection = rejected(source, nextTarget, nextPosition);
2712
+ if (nextRejection) {
2713
+ if (transfer) transfer.dropEffect = "none";
2714
+ clearTarget();
2715
+ if (nextRejection.reason === "max-depth") {
2716
+ rejection = nextRejection;
2717
+ rejectedTarget = nextTarget;
2718
+ rejectedPosition = nextPosition;
2719
+ } else rejection = rejectedTarget = rejectedPosition = null;
2720
+ return false;
2721
+ }
2722
+ rejection = rejectedTarget = rejectedPosition = null;
2723
+ if (transfer) transfer.dropEffect = "move";
2724
+ if (target !== nextTarget || position !== nextPosition) {
2725
+ clearTarget();
2726
+ target = nextTarget;
2727
+ position = nextPosition;
2728
+ target.setAttribute("data-drop-position", position);
2729
+ }
2730
+ if (position === "inside" && target.getAttribute("aria-expanded") === "false") scheduleHover(itemId(target));
2731
+ else cancelHover();
2732
+ return true;
2733
+ };
2734
+ const dispatchReorder = (from, to, nextPosition) => {
2735
+ const sourceId = itemId(from);
2736
+ const targetId = itemId(to);
2737
+ if (!sourceId || !targetId) return;
2738
+ if (nextPosition === "inside") expandTarget(targetId);
2739
+ const fromMeta = metadata(from);
2740
+ const toMeta = metadata(to);
2741
+ host.dispatch("reorder", { sourceId, targetId, position: nextPosition, sourceType: fromMeta.type, targetType: toMeta.type, sourceScope: fromMeta.scope, targetScope: toMeta.scope, trigger: "pointer" });
2742
+ };
2743
+ const dispatchRejected = (from, to, nextPosition, detail) => {
2744
+ const sourceId = itemId(from);
2745
+ const targetId = itemId(to);
2746
+ if (sourceId && targetId) host.dispatch("reorder-rejected", { sourceId, targetId, position: nextPosition, reason: "max-depth", maxDepth: detail.maxDepth, resultingDepth: detail.resultingDepth, trigger: "pointer" });
2747
+ };
2748
+ const onDragStart = (event) => {
2749
+ const item = itemFromEvent(event);
2750
+ const fromHandle = event.composedPath().some((node) => node instanceof HTMLElement && node.getAttribute("part") === "drag-handle");
2751
+ if (!item || item.getAttribute("data-sortable") !== "true" || item.getAttribute("aria-disabled") === "true" || !fromHandle) {
2752
+ event.preventDefault();
2753
+ return;
2754
+ }
2755
+ const id2 = itemId(item);
2756
+ const row = rowFor(item);
2757
+ if (!id2 || !row) {
2758
+ event.preventDefault();
2759
+ return;
2760
+ }
2761
+ source = item;
2762
+ item.setAttribute("data-dragging", "true");
2763
+ if (event.dataTransfer) {
2764
+ event.dataTransfer.effectAllowed = "move";
2765
+ event.dataTransfer.setData("text/plain", id2);
2766
+ if (typeof event.dataTransfer.setDragImage === "function") event.dataTransfer.setDragImage(row, 16, Math.max(0, row.getBoundingClientRect().height / 2));
2767
+ }
2768
+ };
2769
+ const onDrag = (event) => {
2770
+ if (!source || !event.clientX && !event.clientY) return;
2771
+ const item = itemAtPoint(event.clientX, event.clientY);
2772
+ if (item) updateTarget(item, event.clientY, event.dataTransfer);
2773
+ };
2774
+ const onDragOver = (event) => {
2775
+ if (source && updateTarget(itemFromEvent(event), event.clientY, event.dataTransfer)) event.preventDefault();
2776
+ };
2777
+ const onDragLeave = (event) => {
2778
+ if (event.relatedTarget && element.contains(event.relatedTarget)) return;
2779
+ if (!itemAtPoint(event.clientX, event.clientY)) {
2780
+ clearTarget();
2781
+ rejection = rejectedTarget = rejectedPosition = null;
2782
+ }
2783
+ };
2784
+ const onDrop = (event) => {
2785
+ if (!source || !target || !position) return;
2786
+ event.preventDefault();
2787
+ dispatchReorder(source, target, position);
2788
+ finish();
2789
+ };
2790
+ const onDragEnd = (event) => {
2791
+ if (source && rejectedTarget && rejectedPosition && rejection) dispatchRejected(source, rejectedTarget, rejectedPosition, rejection);
2792
+ else if (source) {
2793
+ const item = itemAtPoint(event.clientX, event.clientY);
2794
+ const row = item && item !== source ? rowFor(item) : null;
2795
+ if (item && row) {
2796
+ const nextPosition = classify(row.getBoundingClientRect(), event.clientY, acceptsChildren(item));
2797
+ const nextRejection = rejected(source, item, nextPosition);
2798
+ if (!nextRejection) dispatchReorder(source, item, nextPosition);
2799
+ else if (nextRejection.reason === "max-depth") dispatchRejected(source, item, nextPosition, nextRejection);
2800
+ }
2801
+ }
2802
+ finish();
2803
+ };
2804
+ const syncTabStop = (preferred = null) => {
2805
+ const items = visibleItems();
2806
+ const next = preferred && items.includes(preferred) ? preferred : tabStop && items.includes(tabStop) ? tabStop : items[0] ?? null;
2807
+ tabStop = next;
2808
+ for (const item of items) item.dispatchEvent(new CustomEvent("ui-tree-roving-tab-stop", { detail: { active: item === next } }));
2809
+ };
2810
+ const syncStructure = () => {
2811
+ for (const item of allItems()) item.dispatchEvent(new CustomEvent("ui-tree-structure-sync"));
2812
+ syncTabStop();
2813
+ };
2814
+ const interactive = (event) => {
2815
+ for (const node of event.composedPath()) {
2816
+ if (node instanceof HTMLElement && node.matches?.(itemSelector)) break;
2817
+ if (node instanceof HTMLElement && node.matches('a, button, input, select, textarea, [role="button"], [role="link"]')) return true;
2818
+ }
2819
+ return false;
2820
+ };
2821
+ const focusItem = (item) => {
2822
+ syncTabStop(item);
2823
+ item.focus();
2824
+ };
2825
+ const onFocusin = (event) => {
2826
+ if (!interactive(event)) {
2827
+ const item = itemFromEvent(event);
2828
+ if (item) syncTabStop(item);
2829
+ }
2830
+ };
2831
+ const onExpansion = () => requestAnimationFrame(() => syncTabStop());
2832
+ const onKeydown = (event) => {
2833
+ if (interactive(event)) return;
2834
+ const current = itemFromEvent(event);
2835
+ if (!current) return;
2836
+ const items = visibleItems();
2837
+ const index = items.indexOf(current);
2838
+ if (index < 0) return;
2839
+ const next = event.key === "ArrowDown" ? items[index + 1] : event.key === "ArrowUp" ? items[index - 1] : event.key === "Home" ? items[0] : event.key === "End" ? items.at(-1) : null;
2840
+ if (next) {
2841
+ event.preventDefault();
2842
+ focusItem(next);
2843
+ return;
2844
+ }
2845
+ if (event.key === "ArrowLeft") {
2846
+ if (current.getAttribute("aria-expanded") === "true") {
2847
+ event.preventDefault();
2848
+ current.dispatchEvent(new CustomEvent("ui-tree-request-expanded", { detail: { expanded: false, trigger: "keyboard" } }));
2849
+ } else {
2850
+ const parent = parentItem2(current, element);
2851
+ if (parent) {
2852
+ event.preventDefault();
2853
+ focusItem(parent);
2854
+ }
2855
+ }
2856
+ } else if (event.key === "ArrowRight") {
2857
+ if (current.getAttribute("aria-expanded") === "false") {
2858
+ event.preventDefault();
2859
+ current.dispatchEvent(new CustomEvent("ui-tree-request-expanded", { detail: { expanded: true, trigger: "keyboard" } }));
2860
+ } else if (current.getAttribute("aria-expanded") === "true") {
2861
+ const child = items.find((item) => parentItem2(item, element) === current);
2862
+ if (child) {
2863
+ event.preventDefault();
2864
+ focusItem(child);
2865
+ }
2866
+ }
2867
+ }
2868
+ };
2869
+ const listeners = { dragstart: onDragStart, drag: onDrag, dragenter: onDragOver, dragover: onDragOver, dragleave: onDragLeave, drop: onDrop, dragend: onDragEnd, keydown: onKeydown, focusin: onFocusin, "ui-tree-expansion-change": onExpansion };
2870
+ for (const [name, listener] of Object.entries(listeners)) element.addEventListener(name, listener);
2871
+ const observer = new MutationObserver(syncStructure);
2872
+ observer.observe(element, { childList: true, subtree: true });
2873
+ const stop = host.effect(() => element.setAttribute("aria-label", String(host.state.label || "Tree")));
2874
+ syncStructure();
2875
+ return () => {
2876
+ stop();
2877
+ observer.disconnect();
2878
+ cancelHover();
2879
+ for (const [name, listener] of Object.entries(listeners)) element.removeEventListener(name, listener);
2880
+ };
2881
+ }
2882
+
2883
+ // ../../tools/migrate-html-next/generated/adoption/core/registry.js
2884
+ var records = [
2885
+ { tag: "ui-affordance-scope", source: `<template component="ui-affordance-scope" controller="./controllers/ui-affordance-scope.js" status="early" summary="Migrated Looma ui-affordance-scope component.">
2886
+ <defs>
2887
+ <prop name="nearRadius" type="number" default="16">nearRadius token.</prop>
2888
+ </defs>
2889
+ <span><slot></slot></span>
2890
+ <style>:scope {
2891
+ display: contents;
2892
+ --ui-affordance-scope-engaged: 0;
2893
+ }
2894
+
2895
+ :scope[data-ui-interaction='engaged'] {
2896
+ --ui-affordance-scope-engaged: 1;
2897
+ }
2898
+ </style>
2899
+ </template>
2900
+ `, controller: ui_affordance_scope_exports },
2901
+ { tag: "ui-avatar-group", source: '<template component="ui-avatar-group" controller="./controllers/ui-avatar-group.js" status="early" summary="Migrated Looma ui-avatar-group component.">\n <defs>\n <prop name="max" type="number" default="5">max token.</prop>\n <prop name="label" type="string" default="People">label token.</prop>\n <state name="overflowCount" :value="0"></state>\n </defs>\n <div role="group" :aria-label="label"><slot></slot></div>\n <style>:scope {\n display: flex;\n align-items: center;\n flex-direction: row-reverse;\n gap: 0;\n}\n\n:slotted(*) {\n margin-inline-end: -0.5rem;\n flex-shrink: 0;\n}\n\n:slotted(*:last-of-type) {\n margin-inline-end: 0;\n}\n\n.overflow {\n margin-inline-end: -0.5rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: 2.5rem;\n block-size: 2.5rem;\n border-radius: 999px;\n border: 1px solid var(--ui-border-default);\n background: var(--ui-surface-muted);\n color: var(--ui-text-secondary);\n font: inherit;\n font-size: 0.75rem;\n font-weight: 600;\n flex-shrink: 0;\n}\n</style>\n</template>\n', controller: ui_avatar_group_exports },
2902
+ { tag: "ui-avatar", source: '<template component="ui-avatar" controller="./controllers/ui-avatar.js" status="early" summary="Migrated Looma ui-avatar component.">\n <defs>\n <prop name="src" type="string" default="">src token.</prop>\n <prop name="alt" type="string" default="">alt token.</prop>\n <prop name="name" type="string" default="">name token.</prop>\n <prop name="fallback" type="string" default="">fallback token.</prop>\n <state name="hasImage" :value="false"></state>\n </defs>\n <span role="img" :data-has-image="hasImage"><div class="avatar"><img :src="src" :hidden="not hasImage"></img><span class="fallback"></span></div></span>\n <style>:scope {\n display: inline-flex;\n}\n\n.avatar {\n display: inline-grid;\n place-items: center;\n overflow: hidden;\n inline-size: 2.5rem;\n block-size: 2.5rem;\n border-radius: 999px;\n border: 1px solid var(--ui-border-default);\n background: var(--ui-surface-muted);\n color: var(--ui-text-secondary);\n font: inherit;\n font-size: 0.875rem;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.avatar img {\n grid-area: 1 / 1;\n inline-size: 100%;\n block-size: 100%;\n object-fit: cover;\n}\n\n.avatar .fallback {\n grid-area: 1 / 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: 100%;\n block-size: 100%;\n}\n</style>\n</template>\n', controller: ui_avatar_exports },
2903
+ { tag: "ui-badge", source: `<template component="ui-badge" status="early" summary="Migrated Looma ui-badge component.">
2904
+ <defs>
2905
+ <prop name="variant" type="string">variant token.</prop>
2906
+ <prop name="tone" type="string">tone token.</prop>
2907
+ </defs>
2908
+ <span :data-variant="variant" :data-tone="tone"><span class="badge__surface"><slot></slot></span></span>
2909
+ <style>:scope {
2910
+ --ui-badge-surface: var(--ui-surface-muted);
2911
+ --ui-badge-text: var(--ui-text-secondary);
2912
+ --ui-badge-border: var(--ui-border-default);
2913
+ --ui-badge-font-size: var(--ui-font-size-xs);
2914
+ --ui-badge-font-weight: var(--ui-font-normal);
2915
+ --ui-badge-line-height: var(--ui-line-height-tight);
2916
+ --ui-badge-padding-block: var(--ui-space-0-5);
2917
+ --ui-badge-padding-inline: var(--ui-space-2);
2918
+
2919
+ display: inline-flex;
2920
+ max-width: 100%;
2921
+ }
2922
+
2923
+ .badge__surface {
2924
+ display: inline-flex;
2925
+ align-items: center;
2926
+ justify-content: center;
2927
+ max-width: 100%;
2928
+ padding: var(--ui-badge-padding-block) var(--ui-badge-padding-inline);
2929
+ border: 1px solid var(--ui-badge-border);
2930
+ border-radius: var(--ui-radius-round);
2931
+ background: var(--ui-badge-surface);
2932
+ color: var(--ui-badge-text);
2933
+ font-family: var(--ui-font-family-sans);
2934
+ font-size: var(--ui-badge-font-size);
2935
+ font-weight: var(--ui-badge-font-weight);
2936
+ line-height: var(--ui-badge-line-height);
2937
+ white-space: nowrap;
2938
+ }
2939
+
2940
+ :scope[data-tone='accent'] .badge__surface {
2941
+ --ui-badge-surface: var(--ui-accent-solid);
2942
+ --ui-badge-border: var(--ui-accent-solid);
2943
+ --ui-badge-text: var(--ui-text-on-accent);
2944
+ }
2945
+
2946
+ :scope[data-tone='danger'] .badge__surface {
2947
+ --ui-badge-surface: var(--ui-danger-solid);
2948
+ --ui-badge-border: var(--ui-danger-solid);
2949
+ --ui-badge-text: var(--ui-text-on-accent);
2950
+ }
2951
+
2952
+ :scope[data-tone='success'] .badge__surface {
2953
+ --ui-badge-surface: var(--ui-success-solid);
2954
+ --ui-badge-border: var(--ui-success-solid);
2955
+ --ui-badge-text: var(--ui-text-on-accent);
2956
+ }
2957
+
2958
+ :scope[data-tone='warning'] .badge__surface {
2959
+ --ui-badge-surface: var(--ui-warning-solid);
2960
+ --ui-badge-border: var(--ui-warning-solid);
2961
+ --ui-badge-text: var(--ui-text-primary);
2962
+ }
2963
+
2964
+ :scope[data-tone='info'] .badge__surface {
2965
+ --ui-badge-surface: var(--ui-info-solid);
2966
+ --ui-badge-border: var(--ui-info-solid);
2967
+ --ui-badge-text: var(--ui-text-on-accent);
2968
+ }
2969
+
2970
+ :scope[data-variant='subtle'][data-tone='accent'] .badge__surface {
2971
+ --ui-badge-surface: var(--ui-accent-soft);
2972
+ --ui-badge-border: var(--ui-accent-soft);
2973
+ --ui-badge-text: var(--ui-accent-solid);
2974
+ }
2975
+
2976
+ :scope[data-variant='subtle'][data-tone='danger'] .badge__surface {
2977
+ --ui-badge-surface: var(--ui-danger-soft);
2978
+ --ui-badge-border: var(--ui-danger-soft);
2979
+ --ui-badge-text: var(--ui-danger-solid);
2980
+ }
2981
+
2982
+ :scope[data-variant='subtle'][data-tone='success'] .badge__surface {
2983
+ --ui-badge-surface: var(--ui-success-soft);
2984
+ --ui-badge-border: var(--ui-success-soft);
2985
+ --ui-badge-text: var(--ui-success-solid);
2986
+ }
2987
+
2988
+ :scope[data-variant='subtle'][data-tone='warning'] .badge__surface {
2989
+ --ui-badge-surface: var(--ui-warning-soft);
2990
+ --ui-badge-border: var(--ui-warning-soft);
2991
+ --ui-badge-text: var(--ui-warning-solid);
2992
+ }
2993
+
2994
+ :scope[data-variant='subtle'][data-tone='info'] .badge__surface {
2995
+ --ui-badge-surface: var(--ui-info-soft);
2996
+ --ui-badge-border: var(--ui-info-soft);
2997
+ --ui-badge-text: var(--ui-info-solid);
2998
+ }
2999
+ </style>
3000
+ </template>
3001
+ `, controller: void 0 },
3002
+ { tag: "ui-button", source: `<template component="ui-button" controller="./controllers/ui-button.js" status="early" summary="Migrated Looma ui-button component.">
3003
+ <defs>
3004
+ <prop name="variant" type="string" default="outline">variant token.</prop>
3005
+ <prop name="size" type="string">size token.</prop>
3006
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3007
+ </defs>
3008
+ <span :data-size="size" :data-variant="variant"><slot></slot></span>
3009
+ <style>:scope {
3010
+ display: inline-flex;
3011
+ vertical-align: middle;
3012
+ color: var(--ui-action-secondary-text, var(--ui-text-primary));
3013
+ }
3014
+
3015
+ :scope[data-variant='solid'] {
3016
+ color: var(--ui-action-primary-text, var(--ui-text-on-accent));
3017
+ }
3018
+
3019
+ :scope[data-variant='outline'] :slotted(button),
3020
+ :slotted(button) {
3021
+ appearance: none;
3022
+ min-block-size: var(--ui-button-min-block-size, 2.5rem);
3023
+ border: 1px solid var(--ui-control-border, var(--ui-border-default));
3024
+ border-radius: var(--ui-button-radius, var(--ui-radius-2));
3025
+ background: var(--ui-action-secondary-surface, var(--ui-surface-default));
3026
+ color: inherit;
3027
+ font: inherit;
3028
+ font-weight: var(--ui-font-medium, 500);
3029
+ line-height: var(--ui-line-height-tight);
3030
+ padding: var(--ui-space-2) var(--ui-space-3);
3031
+ cursor: pointer;
3032
+ transition:
3033
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
3034
+ border-color var(--ui-motion-fast) var(--ui-motion-ease),
3035
+ color var(--ui-motion-fast) var(--ui-motion-ease),
3036
+ box-shadow var(--ui-motion-fast) var(--ui-motion-ease),
3037
+ transform var(--ui-motion-fast) var(--ui-motion-ease);
3038
+ margin: 0;
3039
+ }
3040
+
3041
+ :scope[data-size='sm'] :slotted(button) {
3042
+ padding: var(--ui-space-1) var(--ui-space-2);
3043
+ font-size: 0.875rem;
3044
+ }
3045
+
3046
+ :scope[data-size='lg'] :slotted(button) {
3047
+ min-block-size: var(--ui-control-min-block-size, 2.75rem);
3048
+ padding: var(--ui-space-3) var(--ui-space-4);
3049
+ font-size: 1rem;
3050
+ }
3051
+
3052
+ :slotted(button:hover:enabled) {
3053
+ background: var(--ui-action-secondary-surface-hover, var(--ui-surface-muted));
3054
+ border-color: var(--ui-control-border-hover, var(--ui-border-strong));
3055
+ }
3056
+
3057
+ :slotted(button:active:enabled) {
3058
+ background: var(--ui-surface-subtle);
3059
+ }
3060
+
3061
+ :scope[data-variant='solid'] :slotted(button) {
3062
+ border-color: var(--ui-action-primary-surface, var(--ui-accent-solid));
3063
+ background: var(--ui-action-primary-surface, var(--ui-accent-solid));
3064
+ color: var(--ui-action-primary-text, var(--ui-text-on-accent));
3065
+ box-shadow: var(--ui-button-solid-shadow, inset 0 1px rgb(255 255 255 / 0.16), var(--ui-shadow-xs));
3066
+ }
3067
+
3068
+ :scope[data-variant='solid'] :slotted(button:hover:enabled) {
3069
+ background: var(--ui-action-primary-surface-hover, var(--ui-accent-hover));
3070
+ border-color: var(--ui-action-primary-surface-hover, var(--ui-accent-hover));
3071
+ box-shadow: var(--ui-shadow-sm);
3072
+ transform: translateY(-1px);
3073
+ }
3074
+
3075
+ :scope[data-variant='solid'] :slotted(button:active:enabled) {
3076
+ background: var(--ui-action-primary-surface-active, var(--ui-accent-active));
3077
+ border-color: var(--ui-action-primary-surface-active, var(--ui-accent-active));
3078
+ box-shadow: none;
3079
+ transform: translateY(0);
3080
+ }
3081
+
3082
+ :scope[data-variant='destructive'] :slotted(button) {
3083
+ border-color: var(--ui-danger-solid);
3084
+ background: var(--ui-danger-solid);
3085
+ color: var(--ui-text-on-accent);
3086
+ box-shadow: var(--ui-button-destructive-shadow, inset 0 1px rgb(255 255 255 / 0.14), var(--ui-shadow-xs));
3087
+ }
3088
+
3089
+ :scope[data-variant='destructive'] :slotted(button:hover:enabled) {
3090
+ background: var(--ui-danger-hover);
3091
+ border-color: var(--ui-danger-hover);
3092
+ box-shadow: var(--ui-shadow-sm);
3093
+ transform: translateY(-1px);
3094
+ }
3095
+
3096
+ :scope[data-variant='destructive'] :slotted(button:active:enabled) {
3097
+ box-shadow: none;
3098
+ transform: translateY(0);
3099
+ }
3100
+
3101
+ :scope[data-variant='ghost'] :slotted(button) {
3102
+ border-color: transparent;
3103
+ background: transparent;
3104
+ }
3105
+
3106
+ :scope[data-variant='ghost'] :slotted(button:hover:enabled) {
3107
+ background: var(--ui-surface-muted);
3108
+ border-color: transparent;
3109
+ }
3110
+
3111
+ :scope[data-variant='ghost'] :slotted(button:active:enabled) {
3112
+ background: var(--ui-surface-subtle);
3113
+ border-color: transparent;
3114
+ }
3115
+
3116
+ :slotted(button:focus-visible) {
3117
+ outline: 2px solid var(--ui-focus-ring);
3118
+ outline-offset: 2px;
3119
+ }
3120
+
3121
+ :scope[data-disabled='true'],
3122
+ :scope[data-disabled='true'] {
3123
+ opacity: 0.6;
3124
+ cursor: not-allowed;
3125
+ }
3126
+
3127
+ :slotted(button:disabled) {
3128
+ cursor: not-allowed;
3129
+ }
3130
+ </style>
3131
+ </template>
3132
+ `, controller: ui_button_exports },
3133
+ { tag: "ui-callout", source: `<template component="ui-callout" status="early" summary="Migrated Looma ui-callout component.">
3134
+ <defs>
3135
+ <prop name="tone" type="info | note | warning | success | error" default="info">tone token.</prop>
3136
+ </defs>
3137
+ <div role="note" :data-tone="tone"><div class="callout__surface"><span class="icon" aria-hidden="true"></span><div class="content"><slot></slot></div></div></div>
3138
+ <style>:scope {
3139
+ --ui-callout-surface: var(--ui-info-soft);
3140
+ --ui-callout-text: var(--ui-text-primary);
3141
+ --ui-callout-border: var(--ui-info-solid);
3142
+ --ui-callout-icon: var(--ui-info-solid);
3143
+ --ui-callout-padding-block: var(--ui-space-2);
3144
+ --ui-callout-padding-inline: var(--ui-space-3);
3145
+ --ui-callout-icon-column: 1rem;
3146
+ --ui-callout-gap: var(--ui-space-2);
3147
+ --ui-callout-icon-size: 1rem;
3148
+ --ui-callout-border-width: 1px;
3149
+ --ui-callout-leading-border-width: 4px;
3150
+
3151
+ display: block;
3152
+ max-width: 100%;
3153
+ }
3154
+
3155
+ .callout__surface {
3156
+ display: grid;
3157
+ grid-template-columns: var(--ui-callout-icon-column) minmax(0, 1fr);
3158
+ gap: var(--ui-callout-gap);
3159
+ align-items: start;
3160
+ padding: var(--ui-callout-padding-block) var(--ui-callout-padding-inline);
3161
+ border: var(--ui-callout-border-width) solid color-mix(in srgb, var(--ui-callout-border) 35%, transparent);
3162
+ border-inline-start: var(--ui-callout-leading-border-width) solid var(--ui-callout-border);
3163
+ border-radius: var(--ui-radius-2);
3164
+ background: var(--ui-callout-surface);
3165
+ color: var(--ui-callout-text);
3166
+ font-family: var(--ui-font-family-sans);
3167
+ font-size: var(--ui-font-size-sm);
3168
+ font-weight: var(--ui-font-normal);
3169
+ line-height: var(--ui-line-height-md);
3170
+ }
3171
+
3172
+ .icon {
3173
+ display: grid;
3174
+ place-items: center;
3175
+ inline-size: var(--ui-callout-icon-column);
3176
+ block-size: var(--ui-callout-icon-column);
3177
+ color: var(--ui-callout-icon);
3178
+ }
3179
+
3180
+ .icon svg {
3181
+ inline-size: var(--ui-callout-icon-size);
3182
+ block-size: var(--ui-callout-icon-size);
3183
+ }
3184
+
3185
+ .content {
3186
+ min-inline-size: 0;
3187
+ }
3188
+
3189
+ :scope[data-tone='note'] {
3190
+ --ui-callout-surface: var(--ui-surface-muted);
3191
+ --ui-callout-border: var(--ui-border-strong);
3192
+ --ui-callout-icon: var(--ui-text-secondary);
3193
+ }
3194
+
3195
+ :scope[data-tone='warning'] {
3196
+ --ui-callout-surface: var(--ui-warning-soft);
3197
+ --ui-callout-border: var(--ui-warning-solid);
3198
+ --ui-callout-icon: var(--ui-warning-solid);
3199
+ }
3200
+
3201
+ :scope[data-tone='success'] {
3202
+ --ui-callout-surface: var(--ui-success-soft);
3203
+ --ui-callout-border: var(--ui-success-solid);
3204
+ --ui-callout-icon: var(--ui-success-solid);
3205
+ }
3206
+
3207
+ :scope[data-tone='error'] {
3208
+ --ui-callout-surface: var(--ui-danger-soft);
3209
+ --ui-callout-border: var(--ui-danger-solid);
3210
+ --ui-callout-icon: var(--ui-danger-solid);
3211
+ }
3212
+ </style>
3213
+ </template>
3214
+ `, controller: void 0 },
3215
+ { tag: "ui-checkbox", source: `<template component="ui-checkbox" controller="./controllers/ui-checkbox.js" status="early" summary="Migrated Looma ui-checkbox component.">
3216
+ <defs>
3217
+ <prop name="checked" type="boolean">checked token.</prop>
3218
+ <prop name="defaultChecked" type="boolean" default="false">defaultChecked token.</prop>
3219
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3220
+ <prop name="indeterminate" type="boolean" default="false">indeterminate token.</prop>
3221
+ <prop name="required" type="boolean" default="false">required token.</prop>
3222
+ <prop name="value" type="string" default="on">value token.</prop>
3223
+ <state name="internalChecked" :value="false"></state>
3224
+ <event name="change" type="object({ checked: boolean, value: string, trigger: keyboard | pointer | programmatic })"></event>
3225
+ </defs>
3226
+ <span role="checkbox" :data-disabled="disabled"><slot></slot></span>
3227
+ <style>:scope {
3228
+ display: inline-flex;
3229
+ align-items: center;
3230
+ gap: var(--ui-space-2);
3231
+ color: var(--ui-text-primary);
3232
+ }
3233
+
3234
+ :scope[aria-disabled='true'],
3235
+ :scope[data-disabled='true'] {
3236
+ opacity: 0.6;
3237
+ cursor: not-allowed;
3238
+ }
3239
+
3240
+ :slotted(input[type='checkbox']) {
3241
+ accent-color: var(--ui-accent-solid);
3242
+ width: 1.125em;
3243
+ height: 1.125em;
3244
+ cursor: pointer;
3245
+ }
3246
+
3247
+ :slotted(input[type='checkbox']:focus-visible) {
3248
+ outline: 2px solid var(--ui-accent-solid);
3249
+ outline-offset: 2px;
3250
+ }
3251
+ </style>
3252
+ </template>
3253
+ `, controller: ui_checkbox_exports },
3254
+ { tag: "ui-chip", source: `<template component="ui-chip" status="early" summary="Migrated Looma ui-chip component.">
3255
+ <defs>
3256
+ <prop name="appearance" type="tag | pill" default="tag">appearance token.</prop>
3257
+ <prop name="size" type="xs | sm" default="xs">size token.</prop>
3258
+ </defs>
3259
+ <span :data-appearance="appearance" :data-size="size"><span class="chip__surface"><span class="chip__label"><slot></slot></span></span></span>
3260
+ <style>:scope {
3261
+ --ui-chip-surface: var(--ui-surface-subtle);
3262
+ --ui-chip-text: var(--ui-text-secondary);
3263
+ --ui-chip-border: var(--ui-border-default);
3264
+ --ui-chip-font-size: var(--ui-font-size-xs);
3265
+ --ui-chip-font-weight: var(--ui-font-normal);
3266
+ --ui-chip-line-height: var(--ui-line-height-tight);
3267
+ --ui-chip-padding-block: var(--ui-space-0-5);
3268
+ --ui-chip-padding-inline: var(--ui-space-2);
3269
+ --ui-chip-notch: var(--ui-space-1);
3270
+
3271
+ display: inline-flex;
3272
+ min-width: 0;
3273
+ max-width: 100%;
3274
+ }
3275
+
3276
+ :scope[data-size='sm'] {
3277
+ --ui-chip-font-size: var(--ui-font-size-sm);
3278
+ }
3279
+
3280
+ .chip__surface {
3281
+ display: inline-flex;
3282
+ align-items: center;
3283
+ box-sizing: border-box;
3284
+ min-width: 0;
3285
+ max-width: 100%;
3286
+ padding: var(--ui-chip-padding-block) var(--ui-chip-padding-inline);
3287
+ border: 1px solid var(--ui-chip-border);
3288
+ background: var(--ui-chip-surface);
3289
+ /* The shared light-DOM reset establishes a baseline host color; the chip's
3290
+ semantic text hook must remain authoritative for consumer color systems. */
3291
+ color: var(--ui-chip-text) !important;
3292
+ /* The shared light-DOM reset establishes inherited defaults; this compact
3293
+ metadata primitive owns its own typography contract. */
3294
+ font-family: var(--ui-font-family-sans) !important;
3295
+ font-size: var(--ui-chip-font-size) !important;
3296
+ font-weight: var(--ui-chip-font-weight) !important;
3297
+ line-height: var(--ui-chip-line-height) !important;
3298
+ }
3299
+
3300
+ .chip__label {
3301
+ min-width: 0;
3302
+ max-width: 100%;
3303
+ overflow: hidden;
3304
+ text-overflow: ellipsis;
3305
+ white-space: nowrap;
3306
+ }
3307
+
3308
+ :scope[data-appearance='pill'] .chip__surface {
3309
+ border-radius: var(--ui-radius-round);
3310
+ }
3311
+
3312
+ :scope[data-appearance='tag'] .chip__surface {
3313
+ border: 0;
3314
+ padding-inline-end: calc(var(--ui-chip-padding-inline) + var(--ui-chip-notch));
3315
+ clip-path: polygon(0 0, calc(100% - var(--ui-chip-notch)) 0, 100% 50%, calc(100% - var(--ui-chip-notch)) 100%, 0 100%);
3316
+ }
3317
+ </style>
3318
+ </template>
3319
+ `, controller: void 0 },
3320
+ { tag: "ui-combobox", source: `
3321
+
3322
+ <template component="ui-combobox" controller="./controllers/ui-combobox.js" status="early" summary="Migrated Looma ui-combobox component.">
3323
+ <defs>
3324
+ <prop name="label" type="string" default="">label token.</prop>
3325
+ <prop name="placeholder" type="string" default="">placeholder token.</prop>
3326
+ <prop name="name" type="string" default="">name token.</prop>
3327
+ <prop name="value" type="string | null | list(object({ id: string, value: string, label: string, description?: string, metadata?: unknown, group?: string, disabled?: boolean }))">value token.</prop>
3328
+ <prop name="defaultValue" type="string">defaultValue token.</prop>
3329
+ <prop name="multiple" type="boolean" default="false">multiple token.</prop>
3330
+ <prop name="tokenSeparators" type="list(string)">tokenSeparators token.</prop>
3331
+ <prop name="query" type="string">query token.</prop>
3332
+ <prop name="defaultQuery" type="string" default="">defaultQuery token.</prop>
3333
+ <prop name="config" type="unknown">config token.</prop>
3334
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3335
+ <prop name="readOnly" type="boolean" default="false">readOnly token.</prop>
3336
+ <prop name="required" type="boolean" default="false">required token.</prop>
3337
+ <prop name="size" type="sm | md" default="md">size token.</prop>
3338
+ <prop name="labelVisibility" type="visible | sr-only" default="visible">labelVisibility token.</prop>
3339
+ <prop name="disclosure" type="boolean" default="false">disclosure token.</prop>
3340
+ <prop name="clearable" type="boolean" default="false">clearable token.</prop>
3341
+ <prop name="help" type="string" default="">help token.</prop>
3342
+ <state name="raw" :value="''"></state>
3343
+ <state name="display" :value="''"></state>
3344
+ <state name="selected" :value="null"></state>
3345
+ <state name="expanded" :value="false"></state>
3346
+ <state name="rows" :value="[]"></state>
3347
+ <state name="active" :value="-1"></state>
3348
+ <state name="loading" :value="false"></state>
3349
+ <state name="helpOpen" :value="false"></state>
3350
+ <state name="lookupError" :value="''"></state>
3351
+ <state name="validation" :value="{ status: 'pristine', touched: false, dirty: false, issues: [] }"></state>
3352
+ <event name="query-change" type="object({ query: string, display: string, trigger: keyboard | pointer | programmatic })"></event>
3353
+ <event name="value-change" type="object({ value: string | null, query: string, option: object({ id: string, value: string, label: string, description?: string, metadata?: unknown, group?: string, disabled?: boolean }) | null, kind: selection | clear | free-entry | create | invalidation, trigger: keyboard | pointer | programmatic }) | list(object({ id: string, value: string, label: string, description?: string, metadata?: unknown, group?: string, disabled?: boolean }))"></event>
3354
+ <event name="free-entry" type="object({ value: string | null, query: string, option: object({ id: string, value: string, label: string, description?: string, metadata?: unknown, group?: string, disabled?: boolean }) | null, kind: selection | clear | free-entry | create | invalidation, trigger: keyboard | pointer | programmatic })"></event>
3355
+ <event name="create-entry" type="object({ value: string | null, query: string, option: object({ id: string, value: string, label: string, description?: string, metadata?: unknown, group?: string, disabled?: boolean }) | null, kind: selection | clear | free-entry | create | invalidation, trigger: keyboard | pointer | programmatic })"></event>
3356
+ <event name="dependency-invalidate" type="object({ value: string | null, query: string, option: object({ id: string, value: string, label: string, description?: string, metadata?: unknown, group?: string, disabled?: boolean }) | null, kind: selection | clear | free-entry | create | invalidation, trigger: keyboard | pointer | programmatic })"></event>
3357
+ <event name="validation-change" type="object({ status: pristine | pending | valid | warning | error, touched: boolean, dirty: boolean, issues: list(object({ message: string, path?: list(unknown), severity?: error | warning })), output?: unknown })"></event>
3358
+ <event name="options-change" type="list(object({ id: string, value: string, label: string, description?: string, metadata?: unknown, group?: string, disabled?: boolean }))"></event>
3359
+ <event name="add-item" type="object({ item: object({ id: string, value: string, label: string, description?: string, metadata?: unknown, group?: string, disabled?: boolean }), index: integer, trigger: keyboard | pointer | programmatic })"></event>
3360
+ <event name="remove-item" type="object({ item: object({ id: string, value: string, label: string, description?: string, metadata?: unknown, group?: string, disabled?: boolean }), index: integer, trigger: keyboard | pointer | programmatic })"></event>
3361
+ <event name="create-item" type="object({ query: string, trigger: keyboard | pointer | programmatic })"></event>
3362
+ <method name="validate" export="validate" returns="promise(unknown)"></method>
3363
+ <method name="focusInput" export="focusInput" returns="promise(undefined)"></method>
3364
+ </defs>
3365
+ <div .value="value" .tokenSeparators="tokenSeparators" .config="config" :data-size="size"><label for="input" part="label"><template $value="label"></template></label><div class="field" part="field"><slot name="start"></slot><div $if="multiple" class="items" role="group"></div><input id="input" role="combobox" aria-autocomplete="list" aria-controls="listbox" :value="display" :placeholder="placeholder" :name="name" :disabled="disabled" :readOnly="readOnly" :required="required" autoComplete="off" part="input"></input><button $if="clearable" type="button" part="affordance">\xD7</button><button $if="help" id="help" type="button" part="affordance" :disabled="disabled"><span aria-hidden="true">?</span></button><button $if="disclosure" type="button" part="affordance" aria-controls="listbox"><span aria-hidden="true">\u2304</span></button></div><ui-tooltip $if="help" id="help-text" for="help"><template $value="help"></template></ui-tooltip><div class="popup" part="popup" :hidden="not expanded"><div id="listbox" role="listbox"></div><slot name="footer"></slot></div><div id="validation" class="message" part="validation" :hidden="not validation.issues.length"></div><div class="sr-only" role="status" aria-live="polite" aria-atomic="true"></div></div>
3366
+ <style>:scope { display: grid; gap: var(--ui-space-1); min-inline-size: 0; color: var(--ui-text-primary); font: inherit; }
3367
+ label { color: var(--ui-field-label-color, var(--ui-text-primary)); font-size: var(--ui-field-label-size, 0.875rem); font-weight: var(--ui-field-label-weight, 500); }
3368
+ .field { display: flex; min-inline-size: 0; border: 1px solid var(--ui-control-border, var(--ui-border-default)); border-radius: var(--ui-radius-2); background: var(--ui-control-surface, var(--ui-surface-default)); }
3369
+ .field:focus-within { border-color: var(--ui-control-focus, var(--ui-focus-ring)); outline: 2px solid var(--ui-control-focus, var(--ui-focus-ring)); outline-offset: 1px; }
3370
+ input { appearance: none; width: 100%; min-inline-size: 0; min-block-size: var(--ui-control-min-block-size, 2.75rem); box-sizing: border-box; border: 0; border-radius: inherit; background: transparent; color: inherit; font: inherit; line-height: var(--ui-line-height-md); padding: var(--ui-space-2) var(--ui-space-3); margin: 0; outline: none; }
3371
+ :scope[data-size='sm'] input { min-block-size: var(--ui-field-compact-size, 2rem); padding: var(--ui-space-1) var(--ui-space-2); }
3372
+ button { appearance: none; border: 0; border-radius: var(--ui-radius-2); background: transparent; color: var(--ui-field-affordance-color, var(--ui-text-secondary)); font: inherit; font-weight: var(--ui-field-affordance-weight, 400); min-inline-size: 2rem; padding: var(--ui-space-1); cursor: pointer; }
3373
+ button:hover:enabled { background: var(--ui-surface-muted); color: var(--ui-text-primary); }
3374
+ button:focus-visible { outline: 2px solid var(--ui-focus-ring); outline-offset: -3px; }
3375
+ input:disabled, button:disabled { color: var(--ui-text-muted); cursor: not-allowed; }
3376
+ .field:has(input:disabled) { background: var(--ui-control-surface-disabled, var(--ui-surface-muted)); }
3377
+ :scope[data-validation='error'] .field { border-color: var(--ui-danger-solid, var(--ui-accent-active)); }
3378
+ .popup { box-sizing: border-box; min-inline-size: 12rem; max-inline-size: calc(100vw - 1rem); max-block-size: var(--ui-combobox-max-block-size, 18rem); overflow: auto; margin: 0; padding: var(--ui-space-1); border: 1px solid var(--ui-border-default); border-radius: var(--ui-radius-2); background: var(--ui-surface-elevated); color: var(--ui-text-primary); box-shadow: var(--ui-shadow-md); }
3379
+ [hidden] { display: none !important; }
3380
+ .option { padding: var(--ui-space-2) var(--ui-space-3); border-radius: var(--ui-radius-1); cursor: pointer; overflow-wrap: anywhere; }
3381
+ .option:hover, .option[data-active] { background: var(--ui-surface-muted); outline: 1px solid var(--ui-focus-ring); outline-offset: -1px; }
3382
+ .option[aria-disabled='true'] { color: var(--ui-text-muted); cursor: not-allowed; }
3383
+ .primary { display: block; color: var(--ui-option-primary-color, var(--ui-text-primary)); font-weight: var(--ui-option-primary-weight, 500); }
3384
+ .secondary { display: block; color: var(--ui-option-secondary-color, var(--ui-text-secondary)); font-weight: var(--ui-option-secondary-weight, 400); font-size: var(--ui-font-size-sm); }
3385
+ .message, .group { color: var(--ui-field-message-color, var(--ui-text-secondary)); font-weight: var(--ui-field-message-weight, 400); font-size: var(--ui-font-size-sm); line-height: var(--ui-line-height-md); overflow-wrap: anywhere; }
3386
+ .group, .popup .message { padding: var(--ui-space-2) var(--ui-space-3); }
3387
+ .sr-only { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
3388
+ @media (pointer: coarse) { button { min-inline-size: 2.75rem; min-block-size: 2.75rem; } }
3389
+ @media (forced-colors: active) { .field, .popup { border-color: CanvasText; } .option[data-active] { outline-color: Highlight; } }
3390
+
3391
+ /* Multiple mode: chips wrap before the cursor on one flexible field line. */
3392
+ :scope[data-multiple='true'] .field { flex-wrap: wrap; align-items: center; gap: var(--ui-space-1); min-block-size: var(--ui-multi-combobox-min-block-size, 2.5rem); padding: var(--ui-space-1); }
3393
+ :scope[data-multiple='true'] input { flex: 1 0 var(--ui-multi-combobox-input-min-inline-size, 5rem); width: auto; min-block-size: 1.75rem; padding: var(--ui-space-0-5) var(--ui-space-1); }
3394
+ .items { display: contents; }
3395
+ .item {
3396
+ appearance: none;
3397
+ display: inline-flex;
3398
+ min-inline-size: 0;
3399
+ max-inline-size: min(100%, var(--ui-multi-combobox-item-max-inline-size, 12rem));
3400
+ overflow: hidden;
3401
+ padding: 0;
3402
+ border: 0;
3403
+ border-radius: var(--ui-radius-1);
3404
+ background: transparent;
3405
+ color: inherit;
3406
+ font: inherit;
3407
+ cursor: default;
3408
+ }
3409
+ .item > slot { display: block; min-inline-size: 0; max-inline-size: 100%; overflow: hidden; }
3410
+ .item > slot:slotted(*) { min-inline-size: 0; max-inline-size: 100%; }
3411
+ .item:focus-visible { outline: 2px solid var(--ui-focus-ring); outline-offset: 1px; }
3412
+ .item:disabled { opacity: .6; }
3413
+ </style>
3414
+ </template>
3415
+ `, controller: ui_combobox_exports },
3416
+ { tag: "ui-context-menu", source: `
3417
+ <template component="ui-context-menu" controller="./controllers/ui-context-menu.js" status="early" summary="Migrated Looma ui-context-menu component.">
3418
+ <defs>
3419
+ <prop name="open" type="boolean">open token.</prop>
3420
+ <prop name="defaultOpen" type="boolean" default="false">defaultOpen token.</prop>
3421
+ <prop name="for" type="string">for token.</prop>
3422
+ <state name="internalOpen" :value="false"></state>
3423
+ <state name="focusTrigger" :value="'programmatic'"></state>
3424
+ <event name="open" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>
3425
+ <event name="close" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>
3426
+ <event name="select" type="object({ value: string, trigger: keyboard | pointer | programmatic })"></event>
3427
+ </defs>
3428
+ <span :data-state-open="internalOpen"><slot name="trigger"></slot><div class="menu" :data-state-open="internalOpen"><ui-menu><slot></slot></ui-menu></div></span>
3429
+ <style>:scope {
3430
+ display: contents;
3431
+ }
3432
+
3433
+ :scope[data-focus-trigger='pointer'] :slotted(ui-menu-item:focus) {
3434
+ outline: none;
3435
+ }
3436
+
3437
+ .menu {
3438
+ position: fixed;
3439
+ inset: auto;
3440
+ margin: 0;
3441
+ z-index: var(--ui-z-overlay, 1000);
3442
+ min-width: 12rem;
3443
+ opacity: 0;
3444
+ transform: translateY(-4px) scale(0.99);
3445
+ transition:
3446
+ opacity var(--ui-motion-fast) var(--ui-motion-ease),
3447
+ transform var(--ui-motion-fast) var(--ui-motion-ease),
3448
+ display var(--ui-motion-fast) allow-discrete,
3449
+ overlay var(--ui-motion-fast) allow-discrete;
3450
+ }
3451
+
3452
+ .menu:popover-open { opacity: 1; transform: translateY(0) scale(1); }
3453
+
3454
+ @starting-style {
3455
+ .menu:popover-open { opacity: 0; transform: translateY(-4px) scale(0.99); }
3456
+ }
3457
+
3458
+ .menu[hidden] { display: none !important; }
3459
+
3460
+ @media (prefers-reduced-motion: reduce) {
3461
+ .menu { transition: none; }
3462
+ }
3463
+ </style>
3464
+ </template>
3465
+ `, controller: ui_context_menu_exports },
3466
+ { tag: "ui-dialog", source: `<template component="ui-dialog" controller="./controllers/ui-dialog.js" status="early" summary="Migrated Looma ui-dialog component.">
3467
+ <defs>
3468
+ <prop name="open" type="boolean">open token.</prop>
3469
+ <prop name="defaultOpen" type="boolean" default="false">defaultOpen token.</prop>
3470
+ <prop name="modal" type="boolean" default="true">modal token.</prop>
3471
+ <prop name="dismissible" type="boolean" default="true">dismissible token.</prop>
3472
+ <prop name="label" type="string">label token.</prop>
3473
+ <state name="internalOpen" :value="false"></state>
3474
+ <state name="accessibleLabel" :value="'Dialog'"></state>
3475
+ <event name="close" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>
3476
+ </defs>
3477
+ <div :data-state-open="internalOpen"><dialog :aria-label="accessibleLabel"><slot></slot></dialog></div>
3478
+ <style>:scope {
3479
+ display: block;
3480
+ }
3481
+
3482
+ :scope:not([data-open]) {
3483
+ display: none;
3484
+ }
3485
+
3486
+ :scope dialog {
3487
+ --ui-dialog-duration: var(--ui-motion-base);
3488
+ --ui-dialog-viewport-gap: var(--ui-space-4, 1rem);
3489
+ position: fixed;
3490
+ inset: 0;
3491
+ box-sizing: border-box;
3492
+ inline-size: min(
3493
+ calc(100% - (var(--ui-dialog-viewport-gap) * 2)),
3494
+ var(--ui-dialog-max-width, 440px)
3495
+ );
3496
+ max-inline-size: none;
3497
+ max-block-size: calc(100dvh - (var(--ui-dialog-viewport-gap) * 2));
3498
+ margin: auto;
3499
+ padding: var(--ui-space-4);
3500
+ overflow: auto;
3501
+ background: var(--ui-surface-elevated);
3502
+ border: 1px solid var(--ui-border-default);
3503
+ border-radius: var(--ui-radius-dialog);
3504
+ box-shadow: var(--ui-shadow-dialog);
3505
+ visibility: hidden;
3506
+ pointer-events: none;
3507
+ opacity: 0;
3508
+ transform: scale(0.96);
3509
+ transition:
3510
+ opacity var(--ui-dialog-duration) var(--ui-motion-ease),
3511
+ transform var(--ui-dialog-duration) var(--ui-motion-ease),
3512
+ visibility var(--ui-dialog-duration),
3513
+ display var(--ui-dialog-duration) var(--ui-motion-ease) allow-discrete,
3514
+ overlay var(--ui-dialog-duration) var(--ui-motion-ease) allow-discrete;
3515
+ }
3516
+
3517
+ :scope dialog[open] {
3518
+ visibility: visible;
3519
+ pointer-events: auto;
3520
+ opacity: 1;
3521
+ transform: scale(1);
3522
+ animation: ui-dialog-enter var(--ui-dialog-duration) var(--ui-motion-ease);
3523
+ }
3524
+
3525
+ @keyframes ui-dialog-enter {
3526
+ from {
3527
+ opacity: 0;
3528
+ transform: scale(0.96);
3529
+ }
3530
+ }
3531
+
3532
+ :scope dialog::backdrop {
3533
+ background-color: transparent;
3534
+ transition:
3535
+ background-color var(--ui-dialog-duration) var(--ui-motion-ease),
3536
+ display var(--ui-dialog-duration) var(--ui-motion-ease) allow-discrete,
3537
+ overlay var(--ui-dialog-duration) var(--ui-motion-ease) allow-discrete;
3538
+ }
3539
+
3540
+ :scope dialog[open]::backdrop {
3541
+ background-color: var(--ui-overlay-backdrop);
3542
+ animation: ui-dialog-backdrop-enter var(--ui-dialog-duration) var(--ui-motion-ease);
3543
+ }
3544
+
3545
+ @keyframes ui-dialog-backdrop-enter {
3546
+ from {
3547
+ background-color: transparent;
3548
+ }
3549
+ }
3550
+ </style>
3551
+ </template>
3552
+ `, controller: ui_dialog_exports },
3553
+ { tag: "ui-disclosure", source: `<template component="ui-disclosure" controller="./controllers/ui-disclosure.js" status="early" summary="Migrated Looma ui-disclosure component.">
3554
+ <defs>
3555
+ <prop name="open" type="boolean">open token.</prop>
3556
+ <prop name="defaultOpen" type="boolean" default="false">defaultOpen token.</prop>
3557
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3558
+ <state name="internalOpen" :value="false"></state>
3559
+ <state name="contentId" :value="''"></state>
3560
+ <event name="open" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>
3561
+ <event name="close" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>
3562
+ </defs>
3563
+ <div><slot></slot></div>
3564
+ <style>:scope {
3565
+ display: block;
3566
+ }
3567
+
3568
+ :slotted([hidden]) {
3569
+ display: none !important;
3570
+ }
3571
+ </style>
3572
+ </template>
3573
+ `, controller: ui_disclosure_exports },
3574
+ { tag: "ui-editable", source: '<template component="ui-editable" controller="./controllers/ui-editable.js" status="early" summary="Migrated Looma ui-editable component.">\n <defs>\n <prop name="edit" type="boolean">edit token.</prop>\n <prop name="defaultEdit" type="boolean" default="false">defaultEdit token.</prop>\n <prop name="disabled" type="boolean" default="false">disabled token.</prop>\n <state name="internalEdit" :value="false"></state>\n <event name="edit-change" type="object({ edit: boolean, reason: activate | light-dismiss | escape | programmatic, trigger: keyboard | pointer | programmatic })"></event>\n </defs>\n <div :data-state-edit="internalEdit" :data-disabled="disabled"><div part="preview"><slot name="preview"></slot></div><div part="edit" :hidden="not internalEdit"><slot name="edit"></slot></div></div>\n <style>:scope { display: block; min-inline-size: 0; }\n[hidden] { display: none !important; }\n</style>\n</template>\n', controller: ui_editable_exports },
3575
+ { tag: "ui-floating-action-button", source: `<template component="ui-floating-action-button" status="early" summary="Migrated Looma ui-floating-action-button component.">
3576
+ <defs>
3577
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3578
+ <prop name="mobileOnly" type="boolean" default="false">mobileOnly token.</prop>
3579
+ <prop name="label" type="string" default="">label token.</prop>
3580
+ </defs>
3581
+ <span :data-disabled="disabled"><button type="button" :aria-label="label"><slot></slot></button></span>
3582
+ <style>:scope {
3583
+ position: fixed;
3584
+ inset-block-end: calc(
3585
+ var(--ui-floating-action-button-bottom, var(--ui-space-6, 1.5rem)) + env(safe-area-inset-bottom)
3586
+ );
3587
+ inset-inline-end: max(
3588
+ var(--ui-floating-action-button-inline-end, var(--ui-space-5, 1.25rem)),
3589
+ env(safe-area-inset-right)
3590
+ );
3591
+ inline-size: var(--ui-floating-action-button-size, 56px);
3592
+ block-size: var(--ui-floating-action-button-size, 56px);
3593
+ display: inline-flex;
3594
+ z-index: var(--ui-floating-action-button-z-index, 100);
3595
+ }
3596
+
3597
+ button {
3598
+ appearance: none;
3599
+ inline-size: 100%;
3600
+ block-size: 100%;
3601
+ border: none;
3602
+ border-radius: 999px;
3603
+ margin: 0;
3604
+ padding: 0;
3605
+ display: inline-flex;
3606
+ align-items: center;
3607
+ justify-content: center;
3608
+ background: var(--ui-floating-action-button-bg, var(--ui-accent-solid));
3609
+ color: var(--ui-floating-action-button-color, var(--ui-text-on-accent));
3610
+ box-shadow: var(
3611
+ --ui-floating-action-button-shadow,
3612
+ 0 4px 12px color-mix(in srgb, var(--ui-accent-solid) 40%, transparent)
3613
+ );
3614
+ cursor: pointer;
3615
+ transition:
3616
+ background-color var(--ui-motion-fast, 160ms) var(--ui-motion-ease, ease),
3617
+ transform var(--ui-motion-fast, 160ms) var(--ui-motion-ease, ease),
3618
+ box-shadow var(--ui-motion-fast, 160ms) var(--ui-motion-ease, ease);
3619
+ }
3620
+
3621
+ button:hover:enabled {
3622
+ background: var(--ui-floating-action-button-hover-bg, var(--ui-accent-hover));
3623
+ box-shadow: var(
3624
+ --ui-floating-action-button-hover-shadow,
3625
+ 0 6px 16px color-mix(in srgb, var(--ui-accent-solid) 50%, transparent)
3626
+ );
3627
+ }
3628
+
3629
+ button:active:enabled {
3630
+ transform: scale(var(--ui-floating-action-button-active-scale, 0.94));
3631
+ }
3632
+
3633
+ button:focus-visible {
3634
+ outline: 2px solid var(--ui-focus-ring);
3635
+ outline-offset: 2px;
3636
+ }
3637
+
3638
+ button:disabled,
3639
+ :scope[data-disabled='true'] {
3640
+ opacity: 0.6;
3641
+ cursor: not-allowed;
3642
+ }
3643
+
3644
+ :slotted(svg) {
3645
+ inline-size: var(--ui-floating-action-button-icon-size, 24px);
3646
+ block-size: var(--ui-floating-action-button-icon-size, 24px);
3647
+ flex-shrink: 0;
3648
+ }
3649
+
3650
+ @media (min-width: 768px) {
3651
+ :scope[data-mobile-only='true'] {
3652
+ display: none;
3653
+ }
3654
+ }
3655
+ </style>
3656
+ </template>
3657
+ `, controller: void 0 },
3658
+ { tag: "ui-form-field", source: `<template component="ui-form-field" controller="./controllers/ui-form-field.js" status="early" summary="Migrated Looma ui-form-field component.">
3659
+ <defs>
3660
+ <prop name="invalid" type="boolean" default="false">invalid token.</prop>
3661
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3662
+ <prop name="required" type="boolean" default="false">required token.</prop>
3663
+ </defs>
3664
+ <div :data-invalid="invalid" :data-disabled="disabled" :data-required="required"><slot></slot></div>
3665
+ <style>:scope {
3666
+ display: grid;
3667
+ gap: var(--ui-space-2);
3668
+ min-inline-size: 0;
3669
+ align-content: start;
3670
+ color: var(--ui-text-primary);
3671
+ }
3672
+
3673
+ :slotted(label) {
3674
+ color: var(--ui-text-secondary);
3675
+ font-size: 0.95rem;
3676
+ }
3677
+
3678
+ :slotted([data-slot='help']) {
3679
+ min-block-size: var(--ui-form-field-help-min-block-size, 0);
3680
+ color: var(--ui-text-muted);
3681
+ font-size: 0.875rem;
3682
+ line-height: var(--ui-line-height-md);
3683
+ }
3684
+
3685
+ :slotted([data-slot='error']),
3686
+ :slotted([role='alert']) {
3687
+ color: var(--ui-accent-active);
3688
+ font-size: 0.875rem;
3689
+ }
3690
+ </style>
3691
+ </template>
3692
+ `, controller: ui_form_field_exports },
3693
+ { tag: "ui-icon-button", source: `<template component="ui-icon-button" controller="./controllers/ui-icon-button.js" status="early" summary="Migrated Looma ui-icon-button component.">
3694
+ <defs>
3695
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3696
+ <prop name="label" type="string" default="">label token.</prop>
3697
+ <prop name="size" type="sm | md | lg" default="md">size token.</prop>
3698
+ <prop name="variant" type="ghost | outline | solid" default="ghost">variant token.</prop>
3699
+ <prop name="anticipatory" type="boolean" default="false">anticipatory token.</prop>
3700
+ </defs>
3701
+ <span :data-disabled="disabled"><button type="button" :aria-label="label"><slot></slot></button></span>
3702
+ <style>:scope {
3703
+ display: inline-flex;
3704
+ color: var(--ui-text-secondary);
3705
+ }
3706
+
3707
+ :scope[data-anticipatory='true'] {
3708
+ position: relative;
3709
+ }
3710
+
3711
+ :scope[data-anticipatory='true']::before {
3712
+ content: '';
3713
+ position: absolute;
3714
+ inset: 50% auto auto 50%;
3715
+ z-index: 1;
3716
+ inline-size: var(--ui-affordance-guide-size, 0.25rem);
3717
+ block-size: var(--ui-affordance-guide-size, 0.25rem);
3718
+ border-radius: var(--ui-radius-round, 999px);
3719
+ background: var(--ui-affordance-guide-color, var(--ui-border-strong));
3720
+ opacity: var(--ui-affordance-guide-opacity, 0.42);
3721
+ transform: translate(-50%, -50%);
3722
+ transition: opacity var(--ui-affordance-motion, var(--ui-motion-fast)) var(--ui-motion-ease);
3723
+ pointer-events: none;
3724
+ }
3725
+
3726
+ :scope[data-anticipatory='true'] button {
3727
+ opacity: 0;
3728
+ transform: scale(0.72);
3729
+ pointer-events: none;
3730
+ }
3731
+
3732
+ :scope[data-anticipatory='true'][data-ui-proximity='near']::before,
3733
+ :scope[data-anticipatory='true']:focus-within::before,
3734
+ :scope[data-anticipatory='true']:hover::before,
3735
+ :scope[data-anticipatory='true'][data-variant='solid']::before {
3736
+ opacity: 0;
3737
+ }
3738
+
3739
+ :scope[data-anticipatory='true'][data-ui-proximity='near'] button,
3740
+ :scope[data-anticipatory='true']:focus-within button,
3741
+ :scope[data-anticipatory='true']:hover button,
3742
+ :scope[data-anticipatory='true'][data-variant='solid'] button {
3743
+ opacity: 1;
3744
+ transform: scale(1);
3745
+ pointer-events: auto;
3746
+ }
3747
+
3748
+ button {
3749
+ appearance: none;
3750
+ inline-size: var(--ui-icon-button-size, 2.5rem);
3751
+ block-size: var(--ui-icon-button-size, 2.5rem);
3752
+ min-inline-size: var(--ui-icon-button-size, 2.5rem);
3753
+ min-block-size: var(--ui-icon-button-size, 2.5rem);
3754
+ padding: 0;
3755
+ margin: 0;
3756
+ border: 1px solid transparent;
3757
+ border-radius: var(--ui-icon-button-radius, var(--ui-radius-2));
3758
+ background: var(--ui-icon-button-bg, transparent);
3759
+ color: inherit;
3760
+ display: inline-flex;
3761
+ align-items: center;
3762
+ justify-content: center;
3763
+ cursor: pointer;
3764
+ transition:
3765
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
3766
+ border-color var(--ui-motion-fast) var(--ui-motion-ease),
3767
+ color var(--ui-motion-fast) var(--ui-motion-ease),
3768
+ box-shadow var(--ui-motion-fast) var(--ui-motion-ease),
3769
+ transform var(--ui-motion-fast) var(--ui-motion-ease);
3770
+ }
3771
+
3772
+ @media (hover: none), (pointer: coarse) {
3773
+ :scope[data-anticipatory='true']::before {
3774
+ opacity: 0;
3775
+ }
3776
+
3777
+ :scope[data-anticipatory='true'] button {
3778
+ opacity: 1;
3779
+ transform: none;
3780
+ pointer-events: auto;
3781
+ }
3782
+ }
3783
+
3784
+ :scope[data-size='sm'] button {
3785
+ inline-size: var(--ui-icon-button-size-sm, 2rem);
3786
+ block-size: var(--ui-icon-button-size-sm, 2rem);
3787
+ min-inline-size: var(--ui-icon-button-size-sm, 2rem);
3788
+ min-block-size: var(--ui-icon-button-size-sm, 2rem);
3789
+ }
3790
+
3791
+ :scope[data-size='lg'] button {
3792
+ inline-size: var(--ui-icon-button-size-lg, 2.75rem);
3793
+ block-size: var(--ui-icon-button-size-lg, 2.75rem);
3794
+ min-inline-size: var(--ui-icon-button-size-lg, 2.75rem);
3795
+ min-block-size: var(--ui-icon-button-size-lg, 2.75rem);
3796
+ }
3797
+
3798
+ :scope[data-variant='outline'] button {
3799
+ border-color: var(--ui-icon-button-border, var(--ui-border-default));
3800
+ background: var(--ui-icon-button-outline-bg, var(--ui-surface-default));
3801
+ color: var(--ui-icon-button-outline-color, var(--ui-text-primary));
3802
+ }
3803
+
3804
+ :scope[data-variant='solid'] button {
3805
+ background: var(--ui-icon-button-solid-bg, var(--ui-accent-solid));
3806
+ color: var(--ui-icon-button-solid-color, var(--ui-text-on-accent));
3807
+ box-shadow: var(
3808
+ --ui-icon-button-solid-shadow,
3809
+ 0 1px 2px color-mix(in srgb, var(--ui-accent-solid) 18%, transparent)
3810
+ );
3811
+ }
3812
+
3813
+ button:hover:enabled {
3814
+ background: var(--ui-icon-button-hover-bg, var(--ui-surface-muted));
3815
+ color: var(--ui-icon-button-hover-color, var(--ui-text-primary));
3816
+ }
3817
+
3818
+ :scope[data-variant='outline'] button:hover:enabled {
3819
+ border-color: var(--ui-icon-button-hover-border, var(--ui-border-strong));
3820
+ }
3821
+
3822
+ :scope[data-variant='solid'] button:hover:enabled {
3823
+ background: var(--ui-icon-button-solid-hover-bg, var(--ui-accent-hover));
3824
+ }
3825
+
3826
+ button:active:enabled {
3827
+ transform: scale(var(--ui-icon-button-active-scale, 0.96));
3828
+ }
3829
+
3830
+ button:focus-visible {
3831
+ outline: 2px solid var(--ui-focus-ring);
3832
+ outline-offset: 2px;
3833
+ }
3834
+
3835
+ button:disabled,
3836
+ :scope[data-disabled='true'] {
3837
+ opacity: 0.6;
3838
+ cursor: not-allowed;
3839
+ }
3840
+
3841
+ :slotted(svg) {
3842
+ inline-size: var(--ui-icon-button-icon-size, 1.125rem);
3843
+ block-size: var(--ui-icon-button-icon-size, 1.125rem);
3844
+ flex-shrink: 0;
3845
+ stroke-width: var(--ui-icon-button-icon-stroke-width, 1.75);
3846
+ }
3847
+ </style>
3848
+ </template>
3849
+ `, controller: ui_icon_button_exports },
3850
+ { tag: "ui-input", source: `<template component="ui-input" controller="./controllers/ui-input.js" status="early" summary="Migrated Looma ui-input component.">
3851
+ <defs>
3852
+ <prop name="value" type="string">value token.</prop>
3853
+ <prop name="defaultValue" type="string" default="">defaultValue token.</prop>
3854
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3855
+ <prop name="invalid" type="boolean" default="false">invalid token.</prop>
3856
+ <prop name="readOnly" type="boolean" default="false">readOnly token.</prop>
3857
+ <state name="internalValue" :value="''"></state>
3858
+ <event name="input" type="object({ value: string, trigger: keyboard | pointer | programmatic })"></event>
3859
+ <event name="change" type="object({ value: string, trigger: keyboard | pointer | programmatic })"></event>
3860
+ </defs>
3861
+ <span :data-invalid="invalid"><slot></slot></span>
3862
+ <style>:scope {
3863
+ display: inline-flex;
3864
+ min-inline-size: 0;
3865
+ color: var(--ui-text-primary);
3866
+ }
3867
+
3868
+ :slotted(input) {
3869
+ width: 100%;
3870
+ appearance: none;
3871
+ min-block-size: var(--ui-control-min-block-size, 2.75rem);
3872
+ border: 1px solid var(--ui-control-border, var(--ui-border-default));
3873
+ border-radius: var(--ui-radius-2);
3874
+ background: var(--ui-control-surface, var(--ui-surface-default));
3875
+ color: inherit;
3876
+ font: inherit;
3877
+ line-height: var(--ui-line-height-md);
3878
+ padding: var(--ui-space-2) var(--ui-space-3);
3879
+ margin: 0;
3880
+ transition:
3881
+ border-color var(--ui-motion-fast) var(--ui-motion-ease),
3882
+ box-shadow var(--ui-motion-fast) var(--ui-motion-ease),
3883
+ background-color var(--ui-motion-fast) var(--ui-motion-ease);
3884
+ }
3885
+
3886
+ :slotted(input:hover:not(:focus):not(:disabled)) {
3887
+ border-color: var(--ui-control-border-hover, var(--ui-border-strong));
3888
+ }
3889
+
3890
+ :slotted(input:focus) {
3891
+ border-color: var(--ui-control-focus, var(--ui-focus-ring));
3892
+ box-shadow: 0 0 0 3px var(--ui-control-focus-halo, var(--ui-accent-soft));
3893
+ }
3894
+
3895
+ :scope[data-invalid='true']:slotted(input),
3896
+ :slotted(input[aria-invalid='true']) {
3897
+ border-color: var(--ui-accent-active);
3898
+ }
3899
+
3900
+ :slotted(input:disabled) {
3901
+ background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
3902
+ color: var(--ui-text-muted);
3903
+ cursor: not-allowed;
3904
+ }
3905
+
3906
+ :slotted(input:focus-visible) {
3907
+ outline: 2px solid var(--ui-focus-ring);
3908
+ outline-offset: 2px;
3909
+ }
3910
+ </style>
3911
+ </template>
3912
+ `, controller: ui_input_exports },
3913
+ { tag: "ui-menu-item", source: `<template component="ui-menu-item" status="early" summary="Migrated Looma ui-menu-item component.">
3914
+ <defs>
3915
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3916
+ <prop name="value" type="string" default="">value token.</prop>
3917
+ </defs>
3918
+ <div role="menuitem" :data-value="value"><span class="menu-item__surface"><slot></slot></span></div>
3919
+ <style>:scope {
3920
+ display: block;
3921
+ width: 100%;
3922
+ }
3923
+
3924
+ .menu-item__surface {
3925
+ display: block;
3926
+ box-sizing: border-box;
3927
+ width: 100%;
3928
+ padding: var(--ui-space-2) var(--ui-space-3);
3929
+ text-align: left;
3930
+ background: none;
3931
+ border: none;
3932
+ border-radius: var(--ui-radius-2);
3933
+ color: var(--ui-text-primary);
3934
+ font-size: var(--ui-font-size-md);
3935
+ font-weight: var(--ui-font-medium, 500);
3936
+ cursor: pointer;
3937
+ transition:
3938
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
3939
+ color var(--ui-motion-fast) var(--ui-motion-ease);
3940
+ }
3941
+
3942
+ :scope:hover:not([aria-disabled='true']):not([data-disabled='true']) .menu-item__surface {
3943
+ background: var(--ui-surface-subtle);
3944
+ }
3945
+
3946
+ :scope[aria-disabled='true'] .menu-item__surface,
3947
+ :scope[data-disabled='true'] .menu-item__surface {
3948
+ opacity: 0.6;
3949
+ cursor: not-allowed;
3950
+ }
3951
+ </style>
3952
+ </template>
3953
+ `, controller: void 0 },
3954
+ { tag: "ui-menu", source: '<template component="ui-menu" controller="./controllers/ui-menu.js" status="early" summary="Migrated Looma ui-menu component.">\n <defs>\n <prop name="open" type="boolean">open token.</prop>\n <prop name="defaultOpen" type="boolean" default="false">defaultOpen token.</prop>\n <prop name="for" type="string">for token.</prop>\n <prop name="placement" type="string" default="bottom-start">placement token.</prop>\n <state name="internalOpen" :value="false"></state>\n <event name="select" type="object({ value: string, trigger: keyboard | pointer | programmatic })"></event>\n <event name="close" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>\n </defs>\n <div role="menu" aria-orientation="vertical" :data-state-open="internalOpen"><div class="menu__surface"><slot></slot></div></div>\n <style>:scope {\n --ui-menu-viewport-gap: var(--ui-space-2, 0.5rem);\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n inline-size: max-content;\n min-inline-size: min(12rem, calc(100vw - (var(--ui-menu-viewport-gap) * 2)));\n max-inline-size: calc(100vw - (var(--ui-menu-viewport-gap) * 2));\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n box-shadow: none;\n overflow: visible;\n}\n\n.menu__surface {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n max-inline-size: inherit;\n padding: var(--ui-space-1);\n background: var(--ui-surface-elevated);\n border: 1px solid var(--ui-border-default);\n border-radius: var(--ui-radius-3);\n box-shadow: var(--ui-shadow-lg);\n max-block-size: inherit;\n overflow: auto;\n}\n\n:scope:not([data-state-open]) {\n display: none;\n}\n\n:scope[popover] {\n position: fixed;\n inset: auto;\n margin: 0;\n overflow: visible;\n max-block-size: calc(100dvh - (var(--ui-menu-viewport-gap) * 2));\n opacity: 0;\n transform: translateY(-4px) scale(0.99);\n transition:\n opacity var(--ui-motion-fast) var(--ui-motion-ease),\n transform var(--ui-motion-fast) var(--ui-motion-ease),\n display var(--ui-motion-fast) allow-discrete,\n overlay var(--ui-motion-fast) allow-discrete;\n}\n\n:scope[popover]:popover-open {\n opacity: 1;\n transform: translateY(0) scale(1);\n}\n\n@starting-style {\n :scope[popover]:popover-open {\n opacity: 0;\n transform: translateY(-4px) scale(0.99);\n }\n}\n\n:scope[hidden] {\n display: none !important;\n}\n\n@media (prefers-reduced-motion: reduce) {\n :scope[popover] { transition: none; }\n}\n\n:slotted(ui-menu-item) {\n display: block;\n width: 100%;\n}\n</style>\n</template>\n', controller: ui_menu_exports },
3955
+ { tag: "ui-popover", source: '<template component="ui-popover" controller="./controllers/ui-popover.js" status="early" summary="Migrated Looma ui-popover component.">\n <defs>\n <prop name="open" type="boolean">open token.</prop>\n <prop name="defaultOpen" type="boolean" default="false">defaultOpen token.</prop>\n <prop name="for" type="string">for token.</prop>\n <prop name="placement" type="string" default="bottom-start">placement token.</prop>\n <state name="internalOpen" :value="false"></state>\n <event name="open" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>\n <event name="close" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>\n </defs>\n <span :data-state-open="internalOpen"><div class="popover__surface"><slot></slot></div></span>\n <style>:scope {\n --ui-popover-viewport-gap: var(--ui-space-2, 0.5rem);\n box-sizing: border-box;\n max-inline-size: min(\n 20rem,\n calc(100vw - (var(--ui-popover-viewport-gap) * 2))\n );\n max-block-size: calc(100dvh - (var(--ui-popover-viewport-gap) * 2));\n overflow: visible;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n box-shadow: none;\n}\n\n.popover__surface {\n box-sizing: border-box;\n max-inline-size: inherit;\n max-block-size: inherit;\n overflow: auto;\n padding: var(--ui-space-3);\n background: var(--ui-surface-elevated);\n border: 1px solid var(--ui-border-default);\n border-radius: var(--ui-radius-3);\n box-shadow: var(--ui-shadow-lg);\n}\n\n:scope:not([data-state-open]) {\n display: none;\n}\n\n:scope[popover] {\n position: fixed;\n inset: auto;\n margin: 0;\n opacity: 0;\n transform: translateY(-4px) scale(0.99);\n transition:\n opacity var(--ui-motion-fast) var(--ui-motion-ease),\n transform var(--ui-motion-fast) var(--ui-motion-ease),\n display var(--ui-motion-fast) allow-discrete,\n overlay var(--ui-motion-fast) allow-discrete;\n}\n\n:scope[popover]:popover-open { opacity: 1; transform: translateY(0) scale(1); }\n\n@starting-style {\n :scope[popover]:popover-open { opacity: 0; transform: translateY(-4px) scale(0.99); }\n}\n\n:scope[hidden] {\n display: none !important;\n}\n\n@media (prefers-reduced-motion: reduce) {\n :scope[popover] { transition: none; }\n}\n</style>\n</template>\n', controller: ui_popover_exports },
3956
+ { tag: "ui-radio-group", source: `<template component="ui-radio-group" controller="./controllers/ui-radio-group.js" status="early" summary="Migrated Looma ui-radio-group component.">
3957
+ <defs>
3958
+ <prop name="value" type="string" default="">value token.</prop>
3959
+ <prop name="name" type="string" default="">name token.</prop>
3960
+ <prop name="orientation" type="horizontal | vertical" default="horizontal">orientation token.</prop>
3961
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3962
+ <prop name="required" type="boolean" default="false">required token.</prop>
3963
+ <state name="internalValue" :value="''"></state>
3964
+ <event name="select" type="object({ value: string, previousValue: string, trigger: keyboard | pointer | programmatic })"></event>
3965
+ <event name="change" type="object({ checked: boolean, value: string, trigger: keyboard | pointer | programmatic })"></event>
3966
+ </defs>
3967
+ <span role="radiogroup" :data-orientation="orientation" :data-disabled="disabled"><slot></slot></span>
3968
+ <style>:scope {
3969
+ display: inline-flex;
3970
+ align-items: center;
3971
+ gap: var(--ui-space-2);
3972
+ }
3973
+
3974
+ :scope[data-orientation='vertical'] {
3975
+ display: inline-grid;
3976
+ justify-items: start;
3977
+ }
3978
+ </style>
3979
+ </template>
3980
+ `, controller: ui_radio_group_exports },
3981
+ { tag: "ui-radio", source: `<template component="ui-radio" controller="./controllers/ui-radio.js" status="early" summary="Migrated Looma ui-radio component.">
3982
+ <defs>
3983
+ <prop name="checked" type="boolean">checked token.</prop>
3984
+ <prop name="defaultChecked" type="boolean" default="false">defaultChecked token.</prop>
3985
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
3986
+ <prop name="name" type="string" default="">name token.</prop>
3987
+ <prop name="required" type="boolean" default="false">required token.</prop>
3988
+ <prop name="value" type="string" default="on">value token.</prop>
3989
+ <state name="internalChecked" :value="false"></state>
3990
+ <event name="change" type="object({ checked: boolean, value: string, trigger: keyboard | pointer | programmatic })"></event>
3991
+ </defs>
3992
+ <span role="radio" :data-disabled="disabled"><slot></slot></span>
3993
+ <style>:scope {
3994
+ display: inline-flex;
3995
+ align-items: center;
3996
+ gap: var(--ui-space-2);
3997
+ color: var(--ui-text-primary);
3998
+ }
3999
+
4000
+ :scope[data-disabled='true'],
4001
+ :scope[aria-disabled='true'] {
4002
+ opacity: 0.6;
4003
+ cursor: not-allowed;
4004
+ }
4005
+
4006
+ :slotted(input[type='radio']) {
4007
+ accent-color: var(--ui-accent-solid);
4008
+ cursor: pointer;
4009
+ }
4010
+
4011
+ :slotted(input[type='radio']:focus-visible) {
4012
+ outline: 2px solid var(--ui-accent-solid);
4013
+ outline-offset: 2px;
4014
+ }
4015
+ </style>
4016
+ </template>
4017
+ `, controller: ui_radio_exports },
4018
+ { tag: "ui-search-result-row", source: `<template component="ui-search-result-row" controller="./controllers/ui-search-result-row.js" status="early" summary="Migrated Looma ui-search-result-row component.">
4019
+ <defs>
4020
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
4021
+ <prop name="selected" type="boolean" default="false">selected token.</prop>
4022
+ <state name="hasLeading" :value="false"></state>
4023
+ <state name="hasMeta" :value="false"></state>
4024
+ <state name="hasExcerpt" :value="false"></state>
4025
+ <state name="hasTrailing" :value="false"></state>
4026
+ </defs>
4027
+ <div><button class="search-result-row" type="button" :disabled="disabled" part="button"><span class="search-result-row__leading" part="leading" :hidden="not hasLeading"><slot name="leading"></slot></span><span class="search-result-row__content" part="content"><span class="search-result-row__title" part="title"><slot name="title"></slot></span><span class="search-result-row__meta" part="meta" :hidden="not hasMeta"><slot name="meta"></slot></span><span class="search-result-row__excerpt" part="excerpt" :hidden="not hasExcerpt"><slot name="excerpt"></slot></span></span><span class="search-result-row__trailing" part="trailing" :hidden="not hasTrailing"><slot name="trailing"></slot></span></button></div>
4028
+ <style>:scope {
4029
+ display: block;
4030
+ }
4031
+
4032
+ .search-result-row {
4033
+ appearance: none;
4034
+ inline-size: 100%;
4035
+ min-block-size: var(--ui-search-result-row-min-height, 56px);
4036
+ margin: 0;
4037
+ padding-block: var(--ui-search-result-row-padding-block, var(--ui-space-3, 0.75rem));
4038
+ padding-inline: var(--ui-search-result-row-padding-inline, var(--ui-space-4, 1rem));
4039
+ display: flex;
4040
+ align-items: flex-start;
4041
+ gap: var(--ui-search-result-row-gap, var(--ui-space-3, 0.75rem));
4042
+ background: var(--ui-search-result-row-bg, transparent);
4043
+ border: none;
4044
+ border-block-end: 1px solid var(--ui-search-result-row-border, var(--ui-border, #e5e7eb));
4045
+ color: inherit;
4046
+ cursor: pointer;
4047
+ text-align: left;
4048
+ transition: background-color var(--ui-motion-fast, 160ms) var(--ui-motion-ease, ease);
4049
+ }
4050
+
4051
+ :scope:last-child .search-result-row {
4052
+ border-block-end: none;
4053
+ }
4054
+
4055
+ .search-result-row:hover:enabled {
4056
+ background: var(--ui-search-result-row-hover-bg, color-mix(in srgb, var(--ui-surface, #ffffff) 85%, black 3%));
4057
+ }
4058
+
4059
+ :scope[data-selected='true'] .search-result-row {
4060
+ background: var(
4061
+ --ui-search-result-row-selected-bg,
4062
+ var(--ui-search-result-row-hover-bg, color-mix(in srgb, var(--ui-surface, #ffffff) 85%, black 3%))
4063
+ );
4064
+ }
4065
+
4066
+ .search-result-row:focus-visible {
4067
+ outline: 2px solid var(--ui-focus-ring, #2563eb);
4068
+ outline-offset: -2px;
4069
+ }
4070
+
4071
+ .search-result-row:disabled,
4072
+ :scope[data-disabled='true'] .search-result-row {
4073
+ opacity: 0.6;
4074
+ cursor: not-allowed;
4075
+ }
4076
+
4077
+ .search-result-row__leading,
4078
+ .search-result-row__trailing {
4079
+ display: inline-flex;
4080
+ align-items: flex-start;
4081
+ flex-shrink: 0;
4082
+ }
4083
+
4084
+ .search-result-row__content {
4085
+ min-inline-size: 0;
4086
+ flex: 1;
4087
+ display: flex;
4088
+ flex-direction: column;
4089
+ }
4090
+
4091
+ .search-result-row__title,
4092
+ .search-result-row__meta,
4093
+ .search-result-row__excerpt {
4094
+ display: block;
4095
+ min-inline-size: 0;
4096
+ }
4097
+
4098
+ [hidden] {
4099
+ display: none;
4100
+ }
4101
+
4102
+ :slotted([slot='title']),
4103
+ :slotted([slot='meta']),
4104
+ :slotted([slot='excerpt']) {
4105
+ display: block;
4106
+ margin: 0;
4107
+ }
4108
+ </style>
4109
+ </template>
4110
+ `, controller: ui_search_result_row_exports },
4111
+ { tag: "ui-search-shell", source: '<template component="ui-search-shell" controller="./controllers/ui-search-shell.js" status="early" summary="Migrated Looma ui-search-shell component.">\n <defs>\n <state name="hasStatus" :value="false"></state>\n <state name="hasFooter" :value="false"></state>\n </defs>\n <div><div class="search-shell" part="base"><slot name="backdrop"></slot><div class="search-shell__panel" part="panel"><div class="search-shell__search" part="search"><slot name="search"></slot></div><div class="search-shell__status" part="status" :hidden="not hasStatus"><slot name="status"></slot></div><div class="search-shell__body" part="body"><slot name="body"></slot></div><div class="search-shell__footer" part="footer" :hidden="not hasFooter"><slot name="footer"></slot></div></div></div></div>\n <style>:scope {\n position: fixed;\n inset: 0;\n z-index: var(--ui-search-shell-z-index, 400);\n display: block;\n}\n\n.search-shell {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding-block-start: var(--ui-search-shell-padding-top, 10vh);\n}\n\n.search-shell__panel {\n position: relative;\n inline-size: min(\n calc(100% - (var(--ui-search-shell-margin-inline, var(--ui-space-4, 1rem)) * 2)),\n var(--ui-search-shell-max-width, 640px)\n );\n max-block-size: var(--ui-search-shell-max-height, 80vh);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--ui-search-shell-bg, var(--ui-surface, #ffffff));\n border: 1px solid var(--ui-search-shell-border, var(--ui-border, #e5e7eb));\n border-radius: var(--ui-search-shell-radius, var(--ui-radius-xl, 1rem));\n box-shadow: var(--ui-search-shell-shadow, var(--ui-shadow-lg, 0 8px 24px rgba(0, 0, 0, 0.12)));\n}\n\n.search-shell__search,\n.search-shell__status,\n.search-shell__footer {\n flex-shrink: 0;\n}\n\n.search-shell__body {\n flex: 1;\n min-block-size: 0;\n}\n\n[hidden] {\n display: none;\n}\n\n@media (max-width: 767px) {\n .search-shell {\n padding-block-start: 0;\n align-items: stretch;\n }\n\n .search-shell__panel {\n inline-size: 100%;\n block-size: 100vh;\n block-size: 100dvh;\n max-block-size: none;\n border-radius: 0;\n border-inline: none;\n border-block-start: none;\n }\n}\n</style>\n</template>\n', controller: ui_search_shell_exports },
4112
+ { tag: "ui-select", source: `<template component="ui-select" controller="./controllers/ui-select.js" status="early" summary="Migrated Looma ui-select component.">
4113
+ <defs>
4114
+ <prop name="value" type="string">value token.</prop>
4115
+ <prop name="defaultValue" type="string">defaultValue token.</prop>
4116
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
4117
+ <prop name="invalid" type="boolean" default="false">invalid token.</prop>
4118
+ <prop name="required" type="boolean" default="false">required token.</prop>
4119
+ <state name="internalValue" :value="''"></state>
4120
+ <event name="input" type="object({ value: string, trigger: keyboard | pointer | programmatic })"></event>
4121
+ <event name="change" type="object({ value: string, trigger: keyboard | pointer | programmatic })"></event>
4122
+ </defs>
4123
+ <span :data-invalid="invalid"><slot></slot></span>
4124
+ <style>:scope {
4125
+ display: inline-flex;
4126
+ min-inline-size: 0;
4127
+ color: var(--ui-text-primary);
4128
+ }
4129
+
4130
+ :slotted(select) {
4131
+ width: 100%;
4132
+ appearance: none;
4133
+ min-block-size: var(--ui-control-min-block-size, 2.75rem);
4134
+ border: 1px solid var(--ui-control-border, var(--ui-border-default));
4135
+ border-radius: var(--ui-radius-2);
4136
+ background-color: var(--ui-control-surface, var(--ui-surface-default));
4137
+ color: inherit;
4138
+ font: inherit;
4139
+ line-height: var(--ui-line-height-md);
4140
+ padding-block: var(--ui-select-padding-block, var(--ui-space-2));
4141
+ padding-inline-start: var(--ui-select-padding-inline-start, var(--ui-space-3));
4142
+ padding-inline-end: var(--ui-select-padding-inline-end, calc(var(--ui-space-6) + var(--ui-space-3)));
4143
+ margin: 0;
4144
+ background-image:
4145
+ linear-gradient(45deg, transparent 50%, currentColor 50%),
4146
+ linear-gradient(135deg, currentColor 50%, transparent 50%);
4147
+ background-position:
4148
+ calc(100% - 1rem) calc(50% - 2px),
4149
+ calc(100% - 0.7rem) calc(50% - 2px);
4150
+ background-size: 0.35rem 0.35rem, 0.35rem 0.35rem;
4151
+ background-repeat: no-repeat;
4152
+ transition:
4153
+ border-color var(--ui-motion-fast) var(--ui-motion-ease),
4154
+ box-shadow var(--ui-motion-fast) var(--ui-motion-ease),
4155
+ background-color var(--ui-motion-fast) var(--ui-motion-ease);
4156
+ }
4157
+
4158
+ :slotted(select:hover:not(:focus):not(:disabled)) {
4159
+ border-color: var(--ui-control-border-hover, var(--ui-border-strong));
4160
+ }
4161
+
4162
+ :slotted(select:focus) {
4163
+ border-color: var(--ui-control-focus, var(--ui-focus-ring));
4164
+ box-shadow: 0 0 0 3px var(--ui-control-focus-halo, var(--ui-accent-soft));
4165
+ }
4166
+
4167
+ :scope[data-invalid='true']:slotted(select),
4168
+ :slotted(select[aria-invalid='true']) {
4169
+ border-color: var(--ui-accent-active);
4170
+ }
4171
+
4172
+ :slotted(select:disabled) {
4173
+ background-color: var(--ui-control-surface-disabled, var(--ui-surface-muted));
4174
+ color: var(--ui-text-muted);
4175
+ cursor: not-allowed;
4176
+ }
4177
+
4178
+ :slotted(select:focus-visible) {
4179
+ outline: 2px solid var(--ui-focus-ring);
4180
+ outline-offset: 2px;
4181
+ }
4182
+
4183
+ :slotted(select[multiple]),
4184
+ :slotted(select[size]:not([size='1'])) {
4185
+ background-image: none;
4186
+ padding-inline-end: var(--ui-select-padding-inline-start, var(--ui-space-3));
4187
+ }
4188
+ </style>
4189
+ </template>
4190
+ `, controller: ui_select_exports },
4191
+ { tag: "ui-switch", source: `<template component="ui-switch" controller="./controllers/ui-switch.js" status="early" summary="Migrated Looma ui-switch component.">
4192
+ <defs>
4193
+ <prop name="checked" type="boolean">checked token.</prop>
4194
+ <prop name="defaultChecked" type="boolean" default="false">defaultChecked token.</prop>
4195
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
4196
+ <prop name="required" type="boolean" default="false">required token.</prop>
4197
+ <prop name="value" type="string" default="on">value token.</prop>
4198
+ <state name="internalChecked" :value="false"></state>
4199
+ <event name="change" type="object({ checked: boolean, value: string, trigger: keyboard | pointer | programmatic })"></event>
4200
+ </defs>
4201
+ <span role="switch" :data-disabled="disabled"><input type="checkbox" :checked="internalChecked" :required="required" :value="value" aria-hidden="true"></input><slot></slot></span>
4202
+ <style>:scope {
4203
+ display: inline-flex;
4204
+ align-items: center;
4205
+ gap: var(--ui-space-2);
4206
+ color: var(--ui-text-primary);
4207
+ }
4208
+
4209
+ :scope[aria-disabled='true'],
4210
+ :scope[data-disabled='true'] {
4211
+ opacity: 0.6;
4212
+ cursor: not-allowed;
4213
+ }
4214
+
4215
+ :scope[role='switch'] {
4216
+ cursor: pointer;
4217
+ }
4218
+
4219
+ :scope input[type='checkbox'] {
4220
+ appearance: none;
4221
+ -webkit-appearance: none;
4222
+ display: block;
4223
+ position: relative;
4224
+ width: 2.25rem;
4225
+ height: 1.25rem;
4226
+ padding: 0;
4227
+ border: 1px solid var(--ui-border-default);
4228
+ border-radius: 999px;
4229
+ background: var(--ui-surface-muted);
4230
+ cursor: pointer;
4231
+ transition:
4232
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
4233
+ border-color var(--ui-motion-fast) var(--ui-motion-ease);
4234
+ margin: 0;
4235
+ }
4236
+
4237
+ :scope input[type='checkbox']::after {
4238
+ content: '';
4239
+ position: absolute;
4240
+ top: 2px;
4241
+ left: 2px;
4242
+ width: 0.875rem;
4243
+ height: 0.875rem;
4244
+ border-radius: 999px;
4245
+ background: var(--ui-surface-default);
4246
+ border: 1px solid var(--ui-border-default);
4247
+ transition: transform var(--ui-motion-fast) var(--ui-motion-ease);
4248
+ }
4249
+
4250
+ :scope input[type='checkbox']:checked {
4251
+ background: var(--ui-accent-solid);
4252
+ border-color: var(--ui-accent-solid);
4253
+ }
4254
+
4255
+ :scope input[type='checkbox']:checked::after {
4256
+ transform: translateX(calc(2.25rem - 0.875rem - 4px));
4257
+ background: var(--ui-text-on-accent);
4258
+ border-color: var(--ui-text-on-accent);
4259
+ }
4260
+
4261
+ :scope input[type='checkbox']:focus-visible {
4262
+ outline: 2px solid var(--ui-accent-solid);
4263
+ outline-offset: 2px;
4264
+ }
4265
+ </style>
4266
+ </template>
4267
+ `, controller: ui_switch_exports },
4268
+ { tag: "ui-tabs", source: `<template component="ui-tabs" controller="./controllers/ui-tabs.js" status="early" summary="Migrated Looma ui-tabs component.">
4269
+ <defs>
4270
+ <prop name="value" type="string">value token.</prop>
4271
+ <prop name="defaultValue" type="string" default="">defaultValue token.</prop>
4272
+ <prop name="orientation" type="horizontal | vertical" default="horizontal">orientation token.</prop>
4273
+ <state name="internalValue" :value="''"></state>
4274
+ <event name="select" type="object({ value: string, previousValue: string, trigger: keyboard | pointer | programmatic })"></event>
4275
+ </defs>
4276
+ <div :data-orientation="orientation"><slot></slot></div>
4277
+ <style>:scope {
4278
+ display: flex;
4279
+ flex-direction: column;
4280
+ gap: 0;
4281
+ }
4282
+
4283
+ :scope[data-orientation='vertical'] {
4284
+ flex-direction: row;
4285
+ }
4286
+
4287
+ :slotted([role='tablist']) {
4288
+ display: flex;
4289
+ gap: 0;
4290
+ max-inline-size: 100%;
4291
+ overflow-x: auto;
4292
+ overscroll-behavior-inline: contain;
4293
+ border-bottom: 1px solid var(--ui-border-default);
4294
+ }
4295
+
4296
+ :scope[data-orientation='vertical'] :slotted([role='tablist']) {
4297
+ flex-direction: column;
4298
+ border-bottom: none;
4299
+ border-inline-end: 1px solid var(--ui-border-default);
4300
+ }
4301
+
4302
+ :slotted(button[role='tab']),
4303
+ :slotted([role='tab']),
4304
+ :slotted(ui-button) button[role='tab'] {
4305
+ padding: var(--ui-space-2) var(--ui-space-3);
4306
+ font-size: var(--ui-font-size-sm);
4307
+ font-weight: var(--ui-font-medium, 500);
4308
+ color: var(--ui-text-secondary);
4309
+ background: none;
4310
+ border: none;
4311
+ border-bottom: 2px solid transparent;
4312
+ margin-bottom: -1px;
4313
+ cursor: pointer;
4314
+ transition: color var(--ui-motion-fast) var(--ui-motion-ease);
4315
+ box-shadow: none;
4316
+ }
4317
+
4318
+ :slotted(button[role='tab']:hover),
4319
+ :slotted([role='tab']:hover) {
4320
+ color: var(--ui-text-primary);
4321
+ }
4322
+
4323
+ :slotted(button[role='tab'][aria-selected='true']),
4324
+ :slotted([role='tab'][aria-selected='true']) {
4325
+ color: var(--ui-accent-solid);
4326
+ border-bottom-color: var(--ui-accent-solid);
4327
+ }
4328
+
4329
+ :scope[data-orientation='vertical'] :slotted(button[role='tab']),
4330
+ :scope[data-orientation='vertical'] :slotted([role='tab']) {
4331
+ border-bottom: none;
4332
+ border-inline-end: 2px solid transparent;
4333
+ margin-bottom: 0;
4334
+ margin-inline-end: -1px;
4335
+ }
4336
+
4337
+ :scope[data-orientation='vertical'] :slotted(button[role='tab'][aria-selected='true']),
4338
+ :scope[data-orientation='vertical'] :slotted([role='tab'][aria-selected='true']) {
4339
+ border-inline-end-color: var(--ui-accent-solid);
4340
+ }
4341
+
4342
+ :slotted([role='tabpanel']) {
4343
+ padding: var(--ui-space-4);
4344
+ }
4345
+ </style>
4346
+ </template>
4347
+ `, controller: ui_tabs_exports },
4348
+ { tag: "ui-textarea", source: `<template component="ui-textarea" controller="./controllers/ui-textarea.js" status="early" summary="Migrated Looma ui-textarea component.">
4349
+ <defs>
4350
+ <prop name="value" type="string">value token.</prop>
4351
+ <prop name="defaultValue" type="string" default="">defaultValue token.</prop>
4352
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
4353
+ <prop name="invalid" type="boolean" default="false">invalid token.</prop>
4354
+ <prop name="readOnly" type="boolean" default="false">readOnly token.</prop>
4355
+ <prop name="rows" type="number" default="4">rows token.</prop>
4356
+ <state name="internalValue" :value="''"></state>
4357
+ <event name="input" type="object({ value: string, trigger: keyboard | pointer | programmatic })"></event>
4358
+ <event name="change" type="object({ value: string, trigger: keyboard | pointer | programmatic })"></event>
4359
+ </defs>
4360
+ <span :data-invalid="invalid"><slot></slot></span>
4361
+ <style>:scope {
4362
+ display: inline-flex;
4363
+ min-inline-size: 0;
4364
+ color: var(--ui-text-primary);
4365
+ }
4366
+
4367
+ :slotted(textarea) {
4368
+ width: 100%;
4369
+ appearance: none;
4370
+ border: 1px solid var(--ui-control-border, var(--ui-border-default));
4371
+ border-radius: var(--ui-radius-2);
4372
+ background: var(--ui-control-surface, var(--ui-surface-default));
4373
+ color: inherit;
4374
+ font: inherit;
4375
+ line-height: var(--ui-line-height-md);
4376
+ min-block-size: calc(var(--ui-space-12, 3rem) * 2);
4377
+ padding: var(--ui-space-2) var(--ui-space-3);
4378
+ margin: 0;
4379
+ resize: vertical;
4380
+ transition:
4381
+ border-color var(--ui-motion-fast) var(--ui-motion-ease),
4382
+ box-shadow var(--ui-motion-fast) var(--ui-motion-ease),
4383
+ background-color var(--ui-motion-fast) var(--ui-motion-ease);
4384
+ }
4385
+
4386
+ :slotted(textarea:hover:not(:focus):not(:disabled)) {
4387
+ border-color: var(--ui-control-border-hover, var(--ui-border-strong));
4388
+ }
4389
+
4390
+ :slotted(textarea:focus) {
4391
+ border-color: var(--ui-control-focus, var(--ui-focus-ring));
4392
+ box-shadow: 0 0 0 3px var(--ui-control-focus-halo, var(--ui-accent-soft));
4393
+ }
4394
+
4395
+ :scope[data-invalid='true']:slotted(textarea),
4396
+ :slotted(textarea[aria-invalid='true']) {
4397
+ border-color: var(--ui-accent-active);
4398
+ }
4399
+
4400
+ :slotted(textarea:disabled) {
4401
+ background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
4402
+ color: var(--ui-text-muted);
4403
+ cursor: not-allowed;
4404
+ }
4405
+
4406
+ :slotted(textarea:focus-visible) {
4407
+ outline: 2px solid var(--ui-focus-ring);
4408
+ outline-offset: 2px;
4409
+ }
4410
+ </style>
4411
+ </template>
4412
+ `, controller: ui_textarea_exports },
4413
+ { tag: "ui-toast-region", source: `<template component="ui-toast-region" controller="./controllers/ui-toast-region.js" status="early" summary="Migrated Looma ui-toast-region component.">
4414
+ <defs>
4415
+ <prop name="open" type="boolean" default="true">open token.</prop>
4416
+ <state name="internalOpen" :value="false"></state>
4417
+ <event name="close" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>
4418
+ <event name="dismiss" type="object({ id: string, reason: action, trigger: keyboard | pointer | programmatic })"></event>
4419
+ </defs>
4420
+ <div role="region" aria-label="Notifications" aria-live="polite" :data-state-open="internalOpen"><slot></slot></div>
4421
+ <style>:scope {
4422
+ position: fixed;
4423
+ top: calc(var(--ui-space-4) + env(safe-area-inset-top));
4424
+ left: 50%;
4425
+ transform: translateX(-50%);
4426
+ z-index: 9999;
4427
+ display: grid;
4428
+ gap: var(--ui-space-2);
4429
+ inline-size: min(24rem, calc(100vw - (var(--ui-space-4) * 2)));
4430
+ max-inline-size: 100%;
4431
+ pointer-events: none;
4432
+ }
4433
+
4434
+ :scope[popover] {
4435
+ right: auto;
4436
+ bottom: auto;
4437
+ margin: 0;
4438
+ }
4439
+
4440
+ :scope > * {
4441
+ pointer-events: auto;
4442
+ }
4443
+
4444
+ :slotted([data-ui-toast]) {
4445
+ display: grid;
4446
+ grid-template-columns: 1fr auto;
4447
+ gap: var(--ui-space-2);
4448
+ align-items: start;
4449
+ border: 1px solid var(--ui-border-default);
4450
+ border-radius: var(--ui-radius-3);
4451
+ padding: var(--ui-space-3) var(--ui-space-4);
4452
+ background: var(--ui-surface-elevated);
4453
+ color: var(--ui-text-primary);
4454
+ box-shadow: var(--ui-shadow-lg);
4455
+ animation: ui-toast-enter 0.25s var(--ui-motion-ease) forwards;
4456
+ }
4457
+
4458
+ @keyframes ui-toast-enter {
4459
+ from {
4460
+ opacity: 0;
4461
+ transform: translateY(-0.5rem);
4462
+ }
4463
+ to {
4464
+ opacity: 1;
4465
+ transform: translateY(0);
4466
+ }
4467
+ }
4468
+
4469
+ :slotted([data-ui-toast][aria-hidden='true']) {
4470
+ display: none;
4471
+ }
4472
+
4473
+ :slotted([data-ui-toast-dismiss]) {
4474
+ border: 0;
4475
+ background: transparent;
4476
+ color: var(--ui-text-secondary);
4477
+ cursor: pointer;
4478
+ font: inherit;
4479
+ }
4480
+ </style>
4481
+ </template>
4482
+ `, controller: ui_toast_region_exports },
4483
+ { tag: "ui-tooltip", source: '<template component="ui-tooltip" controller="./controllers/ui-tooltip.js" status="early" summary="Migrated Looma ui-tooltip component.">\n <defs>\n <prop name="for" type="string" default="">for token.</prop>\n <prop name="open" type="boolean">open token.</prop>\n <prop name="defaultOpen" type="boolean" default="false">defaultOpen token.</prop>\n <prop name="placement" type="string" default="top-start">placement token.</prop>\n <prop name="showDelay" type="number" default="500">showDelay token.</prop>\n <prop name="hideDelay" type="number" default="100">hideDelay token.</prop>\n <prop name="toggleOnClick" type="boolean" default="false">toggleOnClick token.</prop>\n <state name="internalOpen" :value="false"></state>\n <event name="open" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>\n <event name="close" type="object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"></event>\n </defs>\n <span role="tooltip" :hidden="not internalOpen" :data-state-open="internalOpen"><div class="tooltip__surface"><slot></slot></div></span>\n <style>:scope {\n position: fixed;\n inset: auto;\n margin: 0;\n display: inline-block;\n box-sizing: border-box;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n opacity: 0;\n transform: translateY(4px);\n transition:\n opacity var(--ui-motion-fast) var(--ui-motion-ease),\n transform var(--ui-motion-fast) var(--ui-motion-ease),\n display var(--ui-motion-fast) allow-discrete,\n overlay var(--ui-motion-fast) allow-discrete;\n}\n\n.tooltip__surface {\n box-sizing: border-box;\n border: 1px solid var(--ui-border-default);\n border-radius: var(--ui-radius-2);\n background: var(--ui-surface-elevated);\n color: var(--ui-text-primary);\n padding: var(--ui-space-2) var(--ui-space-3);\n font-size: var(--ui-font-size-sm);\n box-shadow: var(--ui-shadow-md);\n}\n\n:scope:popover-open { opacity: 1; transform: translateY(0); }\n\n@starting-style {\n :scope:popover-open { opacity: 0; transform: translateY(4px); }\n}\n\n:scope[hidden] {\n display: none !important;\n}\n\n@media (prefers-reduced-motion: reduce) {\n :scope { transition: none; }\n}\n</style>\n</template>\n', controller: ui_tooltip_exports },
4484
+ { tag: "ui-top-bar", source: '<template component="ui-top-bar" controller="./controllers/ui-top-bar.js" status="early" summary="Migrated Looma ui-top-bar component.">\n <defs>\n <state name="hasLeading" :value="false"></state>\n <state name="hasSearch" :value="false"></state>\n <state name="hasActions" :value="false"></state>\n </defs>\n <div><header class="top-bar" part="base"><div class="top-bar__leading" :hidden="not hasLeading"><slot name="leading"></slot></div><div class="top-bar__title"><slot></slot></div><div class="top-bar__search" :hidden="not hasSearch"><slot name="search"></slot></div><div class="top-bar__actions" :hidden="not hasActions"><slot name="actions"></slot></div></header></div>\n <style>:scope {\n position: sticky;\n inset-block-start: 0;\n z-index: var(--ui-top-bar-z-index, 100);\n display: block;\n}\n\n.top-bar {\n min-block-size: calc(var(--ui-top-bar-height, 56px) + env(safe-area-inset-top));\n display: flex;\n align-items: center;\n gap: var(--ui-top-bar-gap, var(--ui-space-3, 0.75rem));\n padding-block-start: env(safe-area-inset-top);\n padding-inline-start: max(\n var(--ui-top-bar-padding-inline, var(--ui-space-4, 1rem)),\n env(safe-area-inset-left)\n );\n padding-inline-end: max(\n var(--ui-top-bar-padding-inline, var(--ui-space-4, 1rem)),\n env(safe-area-inset-right)\n );\n background: var(--ui-top-bar-bg, var(--ui-surface, #ffffff));\n border-block-end: 1px solid var(--ui-top-bar-border, var(--ui-border, #e5e7eb));\n}\n\n.top-bar__leading,\n.top-bar__search,\n.top-bar__actions {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n.top-bar__actions {\n gap: var(--ui-top-bar-actions-gap, var(--ui-space-1, 0.25rem));\n}\n\n.top-bar__title {\n min-inline-size: 0;\n flex: 1;\n}\n\n[hidden] {\n display: none;\n}\n\n@media (min-width: 768px) {\n :scope {\n display: none;\n }\n}\n</style>\n</template>\n', controller: ui_top_bar_exports },
4485
+ { tag: "ui-tree-item", source: `<template component="ui-tree-item" controller="./controllers/ui-tree-item.js" status="early" summary="Migrated Looma ui-tree-item component.">
4486
+ <defs>
4487
+ <prop name="itemId" type="string" default="">itemId token.</prop>
4488
+ <prop name="label" type="string" default="">label token.</prop>
4489
+ <prop name="dropDepth" type="number">dropDepth token.</prop>
4490
+ <prop name="subtreeDepth" type="number">subtreeDepth token.</prop>
4491
+ <prop name="container" type="boolean" default="false">container token.</prop>
4492
+ <prop name="sortable" type="boolean" default="false">sortable token.</prop>
4493
+ <prop name="dragType" type="string" default="item">dragType token.</prop>
4494
+ <prop name="dropScope" type="string" default="">dropScope token.</prop>
4495
+ <prop name="accepts" type="string" default="">accepts token.</prop>
4496
+ <prop name="expanded" type="boolean">expanded token.</prop>
4497
+ <prop name="defaultExpanded" type="boolean" default="false">defaultExpanded token.</prop>
4498
+ <prop name="selected" type="boolean" default="false">selected token.</prop>
4499
+ <prop name="disabled" type="boolean" default="false">disabled token.</prop>
4500
+ <state name="internalExpanded" :value="false"></state>
4501
+ <state name="structuralLevel" :value="1"></state>
4502
+ <state name="tabStop" :value="false"></state>
4503
+ <event name="expand" type="object({ id: string, expanded: boolean, trigger: keyboard | pointer | programmatic })"></event>
4504
+ </defs>
4505
+ <div role="treeitem" :aria-label="label" :data-container="container" :data-selected="selected" :data-disabled="disabled" :data-drop-scope="dropScope" :data-accepts="accepts"><div class="row" part="row"><button $if="sortable and not disabled" class="drag-handle" part="drag-handle" type="button"><span></span></button><template $match><button $when="container" class="disclosure" part="disclosure" type="button"><span></span></button><span $else class="disclosure-spacer" aria-hidden="true"></span></template><span class="leading" part="leading"><slot name="leading"></slot></span><span class="label" part="label"><slot></slot></span><span class="actions" part="actions"><slot name="actions"></slot></span><span class="drop-indicator row-drop-indicator" part="drop-indicator" aria-hidden="true"></span></div><div $if="container" class="children" part="children" role="group"><slot name="children"></slot></div><span class="drop-indicator subtree-drop-indicator" part="drop-indicator" aria-hidden="true"></span></div>
4506
+ <style>:scope {
4507
+ --ui-tree-indent: 16px;
4508
+ --ui-tree-row-min-height: 32px;
4509
+ --ui-tree-drop-color: var(--ui-accent-solid);
4510
+
4511
+ position: relative;
4512
+ display: block;
4513
+ min-inline-size: 0;
4514
+ margin-inline-start: calc(var(--ui-tree-item-depth, 0) * var(--ui-tree-indent));
4515
+ }
4516
+
4517
+ .row {
4518
+ position: relative;
4519
+ display: grid;
4520
+ grid-template-columns: 20px auto minmax(0, 1fr) auto;
4521
+ align-items: center;
4522
+ min-block-size: var(--ui-tree-row-min-height);
4523
+ min-inline-size: 0;
4524
+ font-size: var(--ui-tree-font-size, var(--ui-font-size-ui, 0.9375rem));
4525
+ border-radius: var(--ui-radius-md);
4526
+ color: var(--ui-text-secondary);
4527
+ transition:
4528
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
4529
+ color var(--ui-motion-fast) var(--ui-motion-ease),
4530
+ opacity var(--ui-motion-fast) var(--ui-motion-ease),
4531
+ box-shadow var(--ui-motion-fast) var(--ui-motion-ease),
4532
+ min-block-size var(--ui-motion-base) var(--ui-motion-ease);
4533
+ }
4534
+
4535
+ .row:hover,
4536
+ :scope[data-selected] .row,
4537
+ .row:focus-within {
4538
+ color: var(--ui-text-primary);
4539
+ background: var(--ui-surface-muted);
4540
+ }
4541
+
4542
+ :scope[data-disabled] .row {
4543
+ opacity: 0.55;
4544
+ }
4545
+
4546
+ :scope[data-dragging] .row {
4547
+ opacity: 0.42;
4548
+ }
4549
+
4550
+ :scope:focus {
4551
+ outline: none;
4552
+ }
4553
+
4554
+ :scope:focus-visible .row {
4555
+ box-shadow: 0 0 0 2px var(--ui-focus-ring);
4556
+ }
4557
+
4558
+ :scope[data-drop-position='inside'] .row {
4559
+ background: var(--ui-accent-subtle);
4560
+ box-shadow: inset 0 0 0 1px var(--ui-tree-drop-color);
4561
+ }
4562
+
4563
+ .disclosure,
4564
+ .disclosure-spacer {
4565
+ grid-column: 1;
4566
+ grid-row: 1;
4567
+ inline-size: 20px;
4568
+ block-size: 28px;
4569
+ }
4570
+
4571
+ .disclosure {
4572
+ display: grid;
4573
+ place-items: center;
4574
+ padding: 0;
4575
+ color: var(--ui-text-muted);
4576
+ background: transparent;
4577
+ border: 0;
4578
+ border-radius: var(--ui-radius-sm);
4579
+ cursor: pointer;
4580
+ }
4581
+
4582
+ .disclosure:hover {
4583
+ color: var(--ui-text-primary);
4584
+ background: var(--ui-surface-elevated);
4585
+ }
4586
+
4587
+ .disclosure-icon {
4588
+ display: block;
4589
+ inline-size: 14px;
4590
+ block-size: 14px;
4591
+ transform: rotate(-90deg);
4592
+ transition: transform var(--ui-motion-fast) var(--ui-motion-ease);
4593
+ }
4594
+
4595
+ .disclosure-icon--expanded {
4596
+ transform: rotate(0deg);
4597
+ }
4598
+
4599
+ .disclosure-icon :is(svg),
4600
+ .drag-handle :is(svg) {
4601
+ display: block;
4602
+ inline-size: 100%;
4603
+ block-size: 100%;
4604
+ }
4605
+
4606
+ .leading {
4607
+ display: none;
4608
+ }
4609
+
4610
+ .leading:has(*) {
4611
+ display: inline-grid;
4612
+ place-items: center;
4613
+ grid-column: 2;
4614
+ grid-row: 1;
4615
+ inline-size: 16px;
4616
+ block-size: 16px;
4617
+ margin-inline-start: var(--ui-space-1);
4618
+ }
4619
+
4620
+ .label {
4621
+ grid-column: 3;
4622
+ grid-row: 1;
4623
+ min-inline-size: 0;
4624
+ padding: var(--ui-space-1) var(--ui-space-2);
4625
+ }
4626
+
4627
+ .actions {
4628
+ grid-column: 4;
4629
+ grid-row: 1;
4630
+ display: inline-flex;
4631
+ align-items: center;
4632
+ min-inline-size: 0;
4633
+ }
4634
+
4635
+ .drag-handle {
4636
+ position: absolute;
4637
+ z-index: 2;
4638
+ inset-block-start: 50%;
4639
+ inset-inline-start: -22px;
4640
+ inline-size: 20px;
4641
+ block-size: 32px;
4642
+ display: grid;
4643
+ place-items: center;
4644
+ padding: 7px 3px;
4645
+ color: var(--ui-text-muted);
4646
+ background: var(--ui-surface-elevated);
4647
+ border: 1px solid transparent;
4648
+ border-radius: var(--ui-radius-sm);
4649
+ cursor: grab;
4650
+ opacity: 0;
4651
+ pointer-events: none;
4652
+ transform: translateY(-50%);
4653
+ transition: opacity var(--ui-motion-fast) var(--ui-motion-ease);
4654
+ }
4655
+
4656
+ .row:hover .drag-handle,
4657
+ .drag-handle:focus-visible,
4658
+ :scope[data-dragging] .drag-handle {
4659
+ opacity: 1;
4660
+ pointer-events: auto;
4661
+ }
4662
+
4663
+ .drag-handle:active {
4664
+ cursor: grabbing;
4665
+ }
4666
+
4667
+ .drop-indicator {
4668
+ position: absolute;
4669
+ z-index: 3;
4670
+ inset-inline: 1px;
4671
+ display: none;
4672
+ block-size: 2px;
4673
+ border-radius: 999px;
4674
+ background: var(--ui-tree-drop-color);
4675
+ pointer-events: none;
4676
+ }
4677
+
4678
+ .drop-indicator::before,
4679
+ .drop-indicator::after {
4680
+ content: '';
4681
+ position: absolute;
4682
+ inset-block-start: 50%;
4683
+ inline-size: 7px;
4684
+ block-size: 7px;
4685
+ border: 2px solid var(--ui-tree-drop-color);
4686
+ border-radius: 999px;
4687
+ background: var(--ui-surface-elevated);
4688
+ transform: translateY(-50%);
4689
+ }
4690
+
4691
+ .drop-indicator::before { inset-inline-start: -1px; }
4692
+ .drop-indicator::after { inset-inline-end: -1px; }
4693
+
4694
+ :scope[data-drop-position='before'] .row-drop-indicator {
4695
+ display: block;
4696
+ inset-block-start: -1px;
4697
+ }
4698
+
4699
+ :scope[data-drop-position='after'] .subtree-drop-indicator {
4700
+ display: block;
4701
+ inset-block-end: -1px;
4702
+ }
4703
+
4704
+ .children[hidden] {
4705
+ display: none;
4706
+ }
4707
+
4708
+ html[data-ui-input-modality='touch'] :scope {
4709
+ --ui-tree-row-min-height: 44px;
4710
+ }
4711
+
4712
+ html[data-ui-input-modality='touch'] :scope .drag-handle {
4713
+ display: none;
4714
+ }
4715
+
4716
+ @media (prefers-reduced-motion: reduce) {
4717
+ .row,
4718
+ .disclosure-icon,
4719
+ .drag-handle {
4720
+ transition: none;
4721
+ }
4722
+ }
4723
+ </style>
4724
+ </template>
4725
+ `, controller: ui_tree_item_exports },
4726
+ { tag: "ui-tree", source: '\n<template component="ui-tree" controller="./controllers/ui-tree.js" status="early" summary="Migrated Looma ui-tree component.">\n <defs>\n <prop name="label" type="string" default="Tree">label token.</prop>\n <prop name="hoverExpandDelay" type="number" default="700">hoverExpandDelay token.</prop>\n <prop name="maxDepth" type="number" default="0">maxDepth token.</prop>\n <event name="reorder" type="object({ sourceId: string, targetId: string, position: before | inside | after, sourceType: string, targetType: string, sourceScope: string, targetScope: string, trigger: keyboard | pointer | programmatic })"></event>\n <event name="reorder-rejected" type="object({ sourceId: string, targetId: string, position: before | inside | after, reason: max-depth, maxDepth: integer, resultingDepth: integer, trigger: keyboard | pointer | programmatic })"></event>\n </defs>\n <div role="tree"><slot></slot></div>\n <style>:scope {\n --ui-tree-indent: 16px;\n --ui-tree-gutter: 0px;\n\n display: block;\n min-inline-size: 0;\n padding-inline-start: var(--ui-tree-gutter);\n}\n\n:slotted(ui-tree-item) {\n --ui-tree-indent: inherit;\n}\n</style>\n</template>\n', controller: ui_tree_exports }
4727
+ ];
4728
+ var styles = "";
4729
+
4730
+ export {
4731
+ records,
4732
+ styles
4733
+ };