@threadlabs/looma 0.2.4 → 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 (428) 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/styles.css +8 -8
  41. package/vue/chunk-4DPYH3IT.js +3538 -0
  42. package/vue/editor/index.d.ts +17 -7
  43. package/vue/editor/index.js +53 -35
  44. package/vue/index.d.ts +48 -31
  45. package/vue/index.js +1 -1
  46. package/dist/chunk-24OTMNIU.js +0 -1617
  47. package/dist/chunk-D5WRORG6.js +0 -366
  48. package/dist/chunk-HNFCGIBP.js +0 -8
  49. package/dist/chunk-NB6DBRXQ.js +0 -323
  50. package/dist/chunk-OF57X5AR.js +0 -10
  51. package/dist/chunk-TL4FIE7X.js +0 -93
  52. package/dist/chunk-UL7UIUJZ.js +0 -20
  53. package/dist/cjs/app-globals-V2Kpy_OQ.js +0 -5
  54. package/dist/cjs/controlled-state-BFya8rAX.js +0 -9
  55. package/dist/cjs/events-TcQIzpNv.js +0 -19
  56. package/dist/cjs/icons-BAdjrnhS.js +0 -680
  57. package/dist/cjs/id-CYbKpaYr.js +0 -9
  58. package/dist/cjs/index-BHG9Rpil.js +0 -1602
  59. package/dist/cjs/index.cjs.js +0 -2
  60. package/dist/cjs/loader.cjs.js +0 -13
  61. package/dist/cjs/looma.cjs.js +0 -25
  62. package/dist/cjs/manager-Ce25WRtl.js +0 -95
  63. package/dist/cjs/positioning-CCR6ifPj.js +0 -426
  64. package/dist/cjs/ui-affordance-scope.cjs.entry.js +0 -43
  65. package/dist/cjs/ui-avatar-group.cjs.entry.js +0 -43
  66. package/dist/cjs/ui-avatar.cjs.entry.js +0 -50
  67. package/dist/cjs/ui-badge.cjs.entry.js +0 -19
  68. package/dist/cjs/ui-button.cjs.entry.js +0 -75
  69. package/dist/cjs/ui-callout.cjs.entry.js +0 -27
  70. package/dist/cjs/ui-checkbox.cjs.entry.js +0 -97
  71. package/dist/cjs/ui-chip_2.cjs.entry.js +0 -258
  72. package/dist/cjs/ui-combobox.cjs.entry.js +0 -708
  73. package/dist/cjs/ui-context-menu.cjs.entry.js +0 -239
  74. package/dist/cjs/ui-dialog.cjs.entry.js +0 -131
  75. package/dist/cjs/ui-disclosure.cjs.entry.js +0 -112
  76. package/dist/cjs/ui-editable.cjs.entry.js +0 -100
  77. package/dist/cjs/ui-floating-action-button.cjs.entry.js +0 -20
  78. package/dist/cjs/ui-form-field.cjs.entry.js +0 -114
  79. package/dist/cjs/ui-icon-button.cjs.entry.js +0 -23
  80. package/dist/cjs/ui-input.cjs.entry.js +0 -106
  81. package/dist/cjs/ui-menu-item.cjs.entry.js +0 -19
  82. package/dist/cjs/ui-menu.cjs.entry.js +0 -182
  83. package/dist/cjs/ui-popover.cjs.entry.js +0 -135
  84. package/dist/cjs/ui-radio-group.cjs.entry.js +0 -134
  85. package/dist/cjs/ui-radio.cjs.entry.js +0 -94
  86. package/dist/cjs/ui-search-result-row.cjs.entry.js +0 -47
  87. package/dist/cjs/ui-search-shell.cjs.entry.js +0 -39
  88. package/dist/cjs/ui-select.cjs.entry.js +0 -108
  89. package/dist/cjs/ui-switch.cjs.entry.js +0 -74
  90. package/dist/cjs/ui-tabs.cjs.entry.js +0 -118
  91. package/dist/cjs/ui-textarea.cjs.entry.js +0 -110
  92. package/dist/cjs/ui-toast-region.cjs.entry.js +0 -93
  93. package/dist/cjs/ui-top-bar.cjs.entry.js +0 -43
  94. package/dist/cjs/ui-tree-item.cjs.entry.js +0 -135
  95. package/dist/cjs/ui-tree.cjs.entry.js +0 -500
  96. package/dist/collection/collection-manifest.json +0 -45
  97. package/dist/collection/components/ui-affordance-scope/ui-affordance-scope.css +0 -8
  98. package/dist/collection/components/ui-affordance-scope/ui-affordance-scope.js +0 -70
  99. package/dist/collection/components/ui-avatar/ui-avatar.css +0 -35
  100. package/dist/collection/components/ui-avatar/ui-avatar.js +0 -130
  101. package/dist/collection/components/ui-avatar-group/ui-avatar-group.css +0 -32
  102. package/dist/collection/components/ui-avatar-group/ui-avatar-group.js +0 -95
  103. package/dist/collection/components/ui-badge/ui-badge.css +0 -90
  104. package/dist/collection/components/ui-badge/ui-badge.js +0 -62
  105. package/dist/collection/components/ui-button/ui-button.css +0 -121
  106. package/dist/collection/components/ui-button/ui-button.js +0 -141
  107. package/dist/collection/components/ui-callout/ui-callout.css +0 -74
  108. package/dist/collection/components/ui-callout/ui-callout.js +0 -59
  109. package/dist/collection/components/ui-checkbox/ui-checkbox.css +0 -24
  110. package/dist/collection/components/ui-checkbox/ui-checkbox.js +0 -228
  111. package/dist/collection/components/ui-chip/ui-chip.css +0 -57
  112. package/dist/collection/components/ui-chip/ui-chip.js +0 -67
  113. package/dist/collection/components/ui-combobox/ui-combobox.css +0 -47
  114. package/dist/collection/components/ui-combobox/ui-combobox.js +0 -1295
  115. package/dist/collection/components/ui-context-menu/ui-context-menu.css +0 -34
  116. package/dist/collection/components/ui-context-menu/ui-context-menu.js +0 -311
  117. package/dist/collection/components/ui-dialog/ui-dialog.css +0 -72
  118. package/dist/collection/components/ui-dialog/ui-dialog.js +0 -242
  119. package/dist/collection/components/ui-disclosure/ui-disclosure.css +0 -7
  120. package/dist/collection/components/ui-disclosure/ui-disclosure.js +0 -184
  121. package/dist/collection/components/ui-editable/ui-editable.css +0 -2
  122. package/dist/collection/components/ui-editable/ui-editable.js +0 -196
  123. package/dist/collection/components/ui-floating-action-button/ui-floating-action-button.css +0 -73
  124. package/dist/collection/components/ui-floating-action-button/ui-floating-action-button.js +0 -85
  125. package/dist/collection/components/ui-form-field/ui-form-field.css +0 -25
  126. package/dist/collection/components/ui-form-field/ui-form-field.js +0 -180
  127. package/dist/collection/components/ui-icon-button/ui-icon-button.css +0 -145
  128. package/dist/collection/components/ui-icon-button/ui-icon-button.js +0 -128
  129. package/dist/collection/components/ui-input/ui-input.css +0 -48
  130. package/dist/collection/components/ui-input/ui-input.js +0 -217
  131. package/dist/collection/components/ui-menu/ui-menu.css +0 -73
  132. package/dist/collection/components/ui-menu/ui-menu.js +0 -280
  133. package/dist/collection/components/ui-menu-item/ui-menu-item.css +0 -32
  134. package/dist/collection/components/ui-menu-item/ui-menu-item.js +0 -64
  135. package/dist/collection/components/ui-popover/ui-popover.css +0 -58
  136. package/dist/collection/components/ui-popover/ui-popover.js +0 -232
  137. package/dist/collection/components/ui-radio/ui-radio.css +0 -22
  138. package/dist/collection/components/ui-radio/ui-radio.js +0 -226
  139. package/dist/collection/components/ui-radio-group/ui-radio-group.css +0 -10
  140. package/dist/collection/components/ui-radio-group/ui-radio-group.js +0 -247
  141. package/dist/collection/components/ui-search-result-row/ui-search-result-row.css +0 -80
  142. package/dist/collection/components/ui-search-result-row/ui-search-result-row.js +0 -100
  143. package/dist/collection/components/ui-search-shell/ui-search-shell.css +0 -63
  144. package/dist/collection/components/ui-search-shell/ui-search-shell.js +0 -46
  145. package/dist/collection/components/ui-select/ui-select.css +0 -64
  146. package/dist/collection/components/ui-select/ui-select.js +0 -218
  147. package/dist/collection/components/ui-switch/ui-switch.css +0 -63
  148. package/dist/collection/components/ui-switch/ui-switch.js +0 -185
  149. package/dist/collection/components/ui-tabs/ui-tabs.css +0 -68
  150. package/dist/collection/components/ui-tabs/ui-tabs.js +0 -190
  151. package/dist/collection/components/ui-textarea/ui-textarea.css +0 -49
  152. package/dist/collection/components/ui-textarea/ui-textarea.js +0 -241
  153. package/dist/collection/components/ui-toast-region/ui-toast-region.css +0 -59
  154. package/dist/collection/components/ui-toast-region/ui-toast-region.js +0 -126
  155. package/dist/collection/components/ui-tooltip/ui-tooltip.css +0 -43
  156. package/dist/collection/components/ui-tooltip/ui-tooltip.js +0 -430
  157. package/dist/collection/components/ui-top-bar/ui-top-bar.css +0 -51
  158. package/dist/collection/components/ui-top-bar/ui-top-bar.js +0 -52
  159. package/dist/collection/components/ui-tree/ui-tree.css +0 -12
  160. package/dist/collection/components/ui-tree/ui-tree.js +0 -515
  161. package/dist/collection/components/ui-tree-item/ui-tree-item.css +0 -217
  162. package/dist/collection/components/ui-tree-item/ui-tree-item.js +0 -406
  163. package/dist/collection/field/combobox.js +0 -4
  164. package/dist/collection/field/editable.js +0 -1
  165. package/dist/collection/field/multi-combobox.js +0 -1
  166. package/dist/collection/field/valibot.js +0 -5
  167. package/dist/collection/field/validation.js +0 -62
  168. package/dist/collection/icons.js +0 -71
  169. package/dist/collection/input-modality.js +0 -24
  170. package/dist/collection/overlay/manager.js +0 -92
  171. package/dist/collection/overlay/positioning.js +0 -424
  172. package/dist/collection/utils/controlled-state.js +0 -4
  173. package/dist/collection/utils/drag-drop.js +0 -51
  174. package/dist/collection/utils/events.js +0 -13
  175. package/dist/collection/utils/id.js +0 -5
  176. package/dist/collection/utils/initials.js +0 -11
  177. package/dist/components/index.d.ts +0 -102
  178. package/dist/components/index.js +0 -1
  179. package/dist/components/p-6SWSrfmW.js +0 -1
  180. package/dist/components/p-B_DaIVEY.js +0 -1
  181. package/dist/components/p-Bh_1GxOD.js +0 -1
  182. package/dist/components/p-BnGhGgTH.js +0 -1
  183. package/dist/components/p-BzaB_bXo.js +0 -1
  184. package/dist/components/p-C-0syqXZ.js +0 -1
  185. package/dist/components/p-CoFximGM.js +0 -13
  186. package/dist/components/p-JwSoedEO.js +0 -1
  187. package/dist/components/p-Vc4ExHFc.js +0 -1
  188. package/dist/components/p-hgBUJRDa.js +0 -1
  189. package/dist/components/ui-affordance-scope.d.ts +0 -11
  190. package/dist/components/ui-affordance-scope.js +0 -1
  191. package/dist/components/ui-avatar-group.d.ts +0 -11
  192. package/dist/components/ui-avatar-group.js +0 -1
  193. package/dist/components/ui-avatar.d.ts +0 -11
  194. package/dist/components/ui-avatar.js +0 -1
  195. package/dist/components/ui-badge.d.ts +0 -11
  196. package/dist/components/ui-badge.js +0 -1
  197. package/dist/components/ui-button.d.ts +0 -11
  198. package/dist/components/ui-button.js +0 -1
  199. package/dist/components/ui-callout.d.ts +0 -11
  200. package/dist/components/ui-callout.js +0 -1
  201. package/dist/components/ui-checkbox.d.ts +0 -11
  202. package/dist/components/ui-checkbox.js +0 -1
  203. package/dist/components/ui-chip.d.ts +0 -11
  204. package/dist/components/ui-chip.js +0 -1
  205. package/dist/components/ui-combobox.d.ts +0 -11
  206. package/dist/components/ui-combobox.js +0 -1
  207. package/dist/components/ui-context-menu.d.ts +0 -11
  208. package/dist/components/ui-context-menu.js +0 -1
  209. package/dist/components/ui-dialog.d.ts +0 -11
  210. package/dist/components/ui-dialog.js +0 -1
  211. package/dist/components/ui-disclosure.d.ts +0 -11
  212. package/dist/components/ui-disclosure.js +0 -1
  213. package/dist/components/ui-editable.d.ts +0 -11
  214. package/dist/components/ui-editable.js +0 -1
  215. package/dist/components/ui-floating-action-button.d.ts +0 -11
  216. package/dist/components/ui-floating-action-button.js +0 -1
  217. package/dist/components/ui-form-field.d.ts +0 -11
  218. package/dist/components/ui-form-field.js +0 -1
  219. package/dist/components/ui-icon-button.d.ts +0 -11
  220. package/dist/components/ui-icon-button.js +0 -1
  221. package/dist/components/ui-input.d.ts +0 -11
  222. package/dist/components/ui-input.js +0 -1
  223. package/dist/components/ui-menu-item.d.ts +0 -11
  224. package/dist/components/ui-menu-item.js +0 -1
  225. package/dist/components/ui-menu.d.ts +0 -11
  226. package/dist/components/ui-menu.js +0 -1
  227. package/dist/components/ui-popover.d.ts +0 -11
  228. package/dist/components/ui-popover.js +0 -1
  229. package/dist/components/ui-radio-group.d.ts +0 -11
  230. package/dist/components/ui-radio-group.js +0 -1
  231. package/dist/components/ui-radio.d.ts +0 -11
  232. package/dist/components/ui-radio.js +0 -1
  233. package/dist/components/ui-search-result-row.d.ts +0 -11
  234. package/dist/components/ui-search-result-row.js +0 -1
  235. package/dist/components/ui-search-shell.d.ts +0 -11
  236. package/dist/components/ui-search-shell.js +0 -1
  237. package/dist/components/ui-select.d.ts +0 -11
  238. package/dist/components/ui-select.js +0 -1
  239. package/dist/components/ui-switch.d.ts +0 -11
  240. package/dist/components/ui-switch.js +0 -1
  241. package/dist/components/ui-tabs.d.ts +0 -11
  242. package/dist/components/ui-tabs.js +0 -1
  243. package/dist/components/ui-textarea.d.ts +0 -11
  244. package/dist/components/ui-textarea.js +0 -1
  245. package/dist/components/ui-toast-region.d.ts +0 -11
  246. package/dist/components/ui-toast-region.js +0 -1
  247. package/dist/components/ui-tooltip.d.ts +0 -11
  248. package/dist/components/ui-tooltip.js +0 -1
  249. package/dist/components/ui-top-bar.d.ts +0 -11
  250. package/dist/components/ui-top-bar.js +0 -1
  251. package/dist/components/ui-tree-item.d.ts +0 -11
  252. package/dist/components/ui-tree-item.js +0 -1
  253. package/dist/components/ui-tree.d.ts +0 -11
  254. package/dist/components/ui-tree.js +0 -1
  255. package/dist/esm/app-globals-DQuL1Twl.js +0 -3
  256. package/dist/esm/controlled-state-BnGhGgTH.js +0 -6
  257. package/dist/esm/events-JwSoedEO.js +0 -15
  258. package/dist/esm/icons-CoFximGM.js +0 -678
  259. package/dist/esm/id-hgBUJRDa.js +0 -7
  260. package/dist/esm/index-8BGiMGQ0.js +0 -1593
  261. package/dist/esm/index.js +0 -1
  262. package/dist/esm/loader.js +0 -11
  263. package/dist/esm/looma.js +0 -21
  264. package/dist/esm/manager-C-0syqXZ.js +0 -91
  265. package/dist/esm/positioning-ZOr-2PSe.js +0 -421
  266. package/dist/esm/ui-affordance-scope.entry.js +0 -41
  267. package/dist/esm/ui-avatar-group.entry.js +0 -41
  268. package/dist/esm/ui-avatar.entry.js +0 -48
  269. package/dist/esm/ui-badge.entry.js +0 -17
  270. package/dist/esm/ui-button.entry.js +0 -73
  271. package/dist/esm/ui-callout.entry.js +0 -25
  272. package/dist/esm/ui-checkbox.entry.js +0 -95
  273. package/dist/esm/ui-chip_2.entry.js +0 -255
  274. package/dist/esm/ui-combobox.entry.js +0 -706
  275. package/dist/esm/ui-context-menu.entry.js +0 -237
  276. package/dist/esm/ui-dialog.entry.js +0 -129
  277. package/dist/esm/ui-disclosure.entry.js +0 -110
  278. package/dist/esm/ui-editable.entry.js +0 -98
  279. package/dist/esm/ui-floating-action-button.entry.js +0 -18
  280. package/dist/esm/ui-form-field.entry.js +0 -112
  281. package/dist/esm/ui-icon-button.entry.js +0 -21
  282. package/dist/esm/ui-input.entry.js +0 -104
  283. package/dist/esm/ui-menu-item.entry.js +0 -17
  284. package/dist/esm/ui-menu.entry.js +0 -180
  285. package/dist/esm/ui-popover.entry.js +0 -133
  286. package/dist/esm/ui-radio-group.entry.js +0 -132
  287. package/dist/esm/ui-radio.entry.js +0 -92
  288. package/dist/esm/ui-search-result-row.entry.js +0 -45
  289. package/dist/esm/ui-search-shell.entry.js +0 -37
  290. package/dist/esm/ui-select.entry.js +0 -106
  291. package/dist/esm/ui-switch.entry.js +0 -72
  292. package/dist/esm/ui-tabs.entry.js +0 -116
  293. package/dist/esm/ui-textarea.entry.js +0 -108
  294. package/dist/esm/ui-toast-region.entry.js +0 -91
  295. package/dist/esm/ui-top-bar.entry.js +0 -41
  296. package/dist/esm/ui-tree-item.entry.js +0 -133
  297. package/dist/esm/ui-tree.entry.js +0 -498
  298. package/dist/index.cjs.js +0 -1
  299. package/dist/looma/index.esm.js +0 -0
  300. package/dist/looma/looma.esm.js +0 -1
  301. package/dist/looma/p-08f80207.entry.js +0 -1
  302. package/dist/looma/p-0b5b8d9e.entry.js +0 -1
  303. package/dist/looma/p-1249a806.entry.js +0 -1
  304. package/dist/looma/p-16e0669d.entry.js +0 -1
  305. package/dist/looma/p-1c00670f.entry.js +0 -1
  306. package/dist/looma/p-1c5a7522.entry.js +0 -1
  307. package/dist/looma/p-22842f8c.entry.js +0 -1
  308. package/dist/looma/p-2915d5c0.entry.js +0 -1
  309. package/dist/looma/p-3b2961a6.entry.js +0 -1
  310. package/dist/looma/p-3f60f4c8.entry.js +0 -1
  311. package/dist/looma/p-424d6719.entry.js +0 -1
  312. package/dist/looma/p-4caccfce.entry.js +0 -1
  313. package/dist/looma/p-5fdcee1d.entry.js +0 -1
  314. package/dist/looma/p-6d8b99ee.entry.js +0 -1
  315. package/dist/looma/p-6f20d470.entry.js +0 -1
  316. package/dist/looma/p-7c0b5364.entry.js +0 -1
  317. package/dist/looma/p-8BGiMGQ0.js +0 -2
  318. package/dist/looma/p-8bdd9495.entry.js +0 -1
  319. package/dist/looma/p-99116a72.entry.js +0 -1
  320. package/dist/looma/p-9cfbf722.entry.js +0 -1
  321. package/dist/looma/p-9d2662ca.entry.js +0 -1
  322. package/dist/looma/p-9ff2fa19.entry.js +0 -1
  323. package/dist/looma/p-BnGhGgTH.js +0 -1
  324. package/dist/looma/p-C-0syqXZ.js +0 -1
  325. package/dist/looma/p-CoFximGM.js +0 -13
  326. package/dist/looma/p-DQuL1Twl.js +0 -1
  327. package/dist/looma/p-JwSoedEO.js +0 -1
  328. package/dist/looma/p-ZOr-2PSe.js +0 -1
  329. package/dist/looma/p-a2dd4c6c.entry.js +0 -1
  330. package/dist/looma/p-add67e4c.entry.js +0 -1
  331. package/dist/looma/p-b6ede6bb.entry.js +0 -1
  332. package/dist/looma/p-b76e2111.entry.js +0 -1
  333. package/dist/looma/p-ca2a54fd.entry.js +0 -1
  334. package/dist/looma/p-d372b0db.entry.js +0 -1
  335. package/dist/looma/p-d4825822.entry.js +0 -1
  336. package/dist/looma/p-d56571a2.entry.js +0 -1
  337. package/dist/looma/p-d5c3954f.entry.js +0 -1
  338. package/dist/looma/p-e604e906.entry.js +0 -1
  339. package/dist/looma/p-f1f7c5cb.entry.js +0 -1
  340. package/dist/looma/p-hgBUJRDa.js +0 -1
  341. package/dist/types/components/ui-affordance-scope/ui-affordance-scope.d.ts +0 -11
  342. package/dist/types/components/ui-avatar/ui-avatar.d.ts +0 -11
  343. package/dist/types/components/ui-avatar-group/ui-avatar-group.d.ts +0 -11
  344. package/dist/types/components/ui-badge/ui-badge.d.ts +0 -5
  345. package/dist/types/components/ui-button/ui-button.d.ts +0 -13
  346. package/dist/types/components/ui-callout/ui-callout.d.ts +0 -6
  347. package/dist/types/components/ui-checkbox/ui-checkbox.d.ts +0 -20
  348. package/dist/types/components/ui-chip/ui-chip.d.ts +0 -8
  349. package/dist/types/components/ui-combobox/ui-combobox.d.ts +0 -128
  350. package/dist/types/components/ui-context-menu/ui-context-menu.d.ts +0 -43
  351. package/dist/types/components/ui-dialog/ui-dialog.d.ts +0 -27
  352. package/dist/types/components/ui-disclosure/ui-disclosure.d.ts +0 -21
  353. package/dist/types/components/ui-editable/ui-editable.d.ts +0 -24
  354. package/dist/types/components/ui-floating-action-button/ui-floating-action-button.d.ts +0 -6
  355. package/dist/types/components/ui-form-field/ui-form-field.d.ts +0 -18
  356. package/dist/types/components/ui-icon-button/ui-icon-button.d.ts +0 -9
  357. package/dist/types/components/ui-input/ui-input.d.ts +0 -19
  358. package/dist/types/components/ui-menu/ui-menu.d.ts +0 -28
  359. package/dist/types/components/ui-menu-item/ui-menu-item.d.ts +0 -5
  360. package/dist/types/components/ui-popover/ui-popover.d.ts +0 -26
  361. package/dist/types/components/ui-radio/ui-radio.d.ts +0 -20
  362. package/dist/types/components/ui-radio-group/ui-radio-group.d.ts +0 -21
  363. package/dist/types/components/ui-search-result-row/ui-search-result-row.d.ts +0 -15
  364. package/dist/types/components/ui-search-shell/ui-search-shell.d.ts +0 -9
  365. package/dist/types/components/ui-select/ui-select.d.ts +0 -20
  366. package/dist/types/components/ui-switch/ui-switch.d.ts +0 -16
  367. package/dist/types/components/ui-tabs/ui-tabs.d.ts +0 -18
  368. package/dist/types/components/ui-textarea/ui-textarea.d.ts +0 -20
  369. package/dist/types/components/ui-toast-region/ui-toast-region.d.ts +0 -16
  370. package/dist/types/components/ui-tooltip/ui-tooltip.d.ts +0 -57
  371. package/dist/types/components/ui-top-bar/ui-top-bar.d.ts +0 -12
  372. package/dist/types/components/ui-tree/ui-tree.d.ts +0 -53
  373. package/dist/types/components/ui-tree-item/ui-tree-item.d.ts +0 -44
  374. package/dist/types/components.d.ts +0 -1889
  375. package/dist/types/field/combobox.d.ts +0 -46
  376. package/dist/types/field/editable.d.ts +0 -5
  377. package/dist/types/field/multi-combobox.d.ts +0 -11
  378. package/dist/types/field/valibot.d.ts +0 -7
  379. package/dist/types/icons.d.ts +0 -53
  380. package/dist/types/input-modality.d.ts +0 -6
  381. package/dist/types/overlay/manager.d.ts +0 -17
  382. package/dist/types/overlay/positioning.d.ts +0 -74
  383. package/dist/types/stencil-public-runtime.d.ts +0 -1860
  384. package/dist/types/utils/controlled-state.d.ts +0 -4
  385. package/dist/types/utils/drag-drop.d.ts +0 -15
  386. package/dist/types/utils/events.d.ts +0 -4
  387. package/dist/types/utils/id.d.ts +0 -1
  388. package/dist/types/utils/initials.d.ts +0 -1
  389. package/dist/ui-affordance-scope.entry-L6TIXYOP.js +0 -54
  390. package/dist/ui-avatar-group.entry-TCAA6P72.js +0 -51
  391. package/dist/ui-avatar.entry-52DQ7VXA.js +0 -51
  392. package/dist/ui-badge.entry-2XCAA6LL.js +0 -22
  393. package/dist/ui-button.entry-MNFBMNSX.js +0 -83
  394. package/dist/ui-callout.entry-SSHT5TH2.js +0 -32
  395. package/dist/ui-checkbox.entry-LOWIWIWI.js +0 -111
  396. package/dist/ui-chip_2.entry-BIMTSF6C.js +0 -272
  397. package/dist/ui-combobox.entry-25Z4MN7N.js +0 -717
  398. package/dist/ui-context-menu.entry-YZDL5Y4M.js +0 -248
  399. package/dist/ui-dialog.entry-HIXZX5AB.js +0 -146
  400. package/dist/ui-disclosure.entry-2JZHZNDQ.js +0 -126
  401. package/dist/ui-editable.entry-U3VR3XPT.js +0 -110
  402. package/dist/ui-floating-action-button.entry-6S3QN3KJ.js +0 -23
  403. package/dist/ui-form-field.entry-GQOSMLHT.js +0 -120
  404. package/dist/ui-icon-button.entry-QJXKVDM6.js +0 -26
  405. package/dist/ui-input.entry-UWMQ6JMP.js +0 -114
  406. package/dist/ui-menu-item.entry-NHNZKKJS.js +0 -22
  407. package/dist/ui-menu.entry-D53RUJND.js +0 -192
  408. package/dist/ui-popover.entry-7ZSIWCFQ.js +0 -152
  409. package/dist/ui-radio-group.entry-37MSYIH4.js +0 -142
  410. package/dist/ui-radio.entry-7YGCDHXT.js +0 -108
  411. package/dist/ui-search-result-row.entry-6FCCLGAS.js +0 -50
  412. package/dist/ui-search-shell.entry-HSBEXPER.js +0 -41
  413. package/dist/ui-select.entry-GIDIAYRD.js +0 -117
  414. package/dist/ui-switch.entry-MYAL6XPC.js +0 -87
  415. package/dist/ui-tabs.entry-R4TEXQSD.js +0 -128
  416. package/dist/ui-textarea.entry-FW32JNDV.js +0 -119
  417. package/dist/ui-toast-region.entry-BTMFPKZF.js +0 -104
  418. package/dist/ui-top-bar.entry-5DQGJF3B.js +0 -49
  419. package/dist/ui-tree-item.entry-ADT7DSOS.js +0 -145
  420. package/dist/ui-tree.entry-7PYQ5RIN.js +0 -470
  421. package/editor/chunk-64GLF274.js +0 -1271
  422. package/layout/index.css +0 -387
  423. package/loader/cdn.js +0 -1
  424. package/loader/index.cjs.js +0 -1
  425. package/loader/index.d.ts +0 -24
  426. package/loader/index.es2017.js +0 -1
  427. package/loader/index.js +0 -2
  428. 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
+ };