microui-wc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (609) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +33 -0
  3. package/.github/PULL_REQUEST_TEMPLATE.md +28 -0
  4. package/.github/workflows/ci.yml +42 -0
  5. package/.github/workflows/deploy-pages.yml +112 -0
  6. package/AGENTS.md +2366 -0
  7. package/CHANGELOG.md +47 -0
  8. package/CODE_OF_CONDUCT.md +59 -0
  9. package/CONTRIBUTING.md +156 -0
  10. package/LICENSE +190 -0
  11. package/README.md +254 -0
  12. package/SECURITY.md +58 -0
  13. package/app/.generated/routes/alerts.js +8 -0
  14. package/app/.generated/routes/avatars.js +8 -0
  15. package/app/.generated/routes/badges.js +8 -0
  16. package/app/.generated/routes/buttons.js +10 -0
  17. package/app/.generated/routes/cards.js +10 -0
  18. package/app/.generated/routes/checkboxes.js +9 -0
  19. package/app/.generated/routes/chips.js +8 -0
  20. package/app/.generated/routes/dropdowns.js +9 -0
  21. package/app/.generated/routes/home.js +7 -0
  22. package/app/.generated/routes/icons.js +9 -0
  23. package/app/.generated/routes/inputs.js +10 -0
  24. package/app/.generated/routes/installation.js +7 -0
  25. package/app/.generated/routes/layout.js +9 -0
  26. package/app/.generated/routes/modals.js +9 -0
  27. package/app/.generated/routes/navbar.js +7 -0
  28. package/app/.generated/routes/progress.js +9 -0
  29. package/app/.generated/routes/radios.js +9 -0
  30. package/app/.generated/routes/switches.js +9 -0
  31. package/app/.generated/routes/tabs.js +8 -0
  32. package/app/.generated/routes/toasts.js +9 -0
  33. package/app/index.html +67 -0
  34. package/app/pages/alerts.html +23 -0
  35. package/app/pages/avatars.html +22 -0
  36. package/app/pages/badges.html +22 -0
  37. package/app/pages/buttons.html +71 -0
  38. package/app/pages/cards.html +54 -0
  39. package/app/pages/checkboxes.html +39 -0
  40. package/app/pages/chips.html +23 -0
  41. package/app/pages/dropdowns.html +41 -0
  42. package/app/pages/home.html +59 -0
  43. package/app/pages/icons.html +29 -0
  44. package/app/pages/inputs.html +66 -0
  45. package/app/pages/installation.html +34 -0
  46. package/app/pages/layout.html +30 -0
  47. package/app/pages/modals.html +21 -0
  48. package/app/pages/navbar.html +22 -0
  49. package/app/pages/progress.html +35 -0
  50. package/app/pages/radios.html +40 -0
  51. package/app/pages/switches.html +39 -0
  52. package/app/pages/tabs.html +30 -0
  53. package/app/pages/toasts.html +22 -0
  54. package/app-dist/index.html +67 -0
  55. package/app-dist/pages/alerts.html +23 -0
  56. package/app-dist/pages/avatars.html +22 -0
  57. package/app-dist/pages/badges.html +22 -0
  58. package/app-dist/pages/buttons.html +71 -0
  59. package/app-dist/pages/cards.html +54 -0
  60. package/app-dist/pages/checkboxes.html +39 -0
  61. package/app-dist/pages/chips.html +23 -0
  62. package/app-dist/pages/dropdowns.html +41 -0
  63. package/app-dist/pages/home.html +59 -0
  64. package/app-dist/pages/icons.html +29 -0
  65. package/app-dist/pages/inputs.html +66 -0
  66. package/app-dist/pages/installation.html +34 -0
  67. package/app-dist/pages/layout.html +30 -0
  68. package/app-dist/pages/modals.html +21 -0
  69. package/app-dist/pages/navbar.html +22 -0
  70. package/app-dist/pages/progress.html +35 -0
  71. package/app-dist/pages/radios.html +40 -0
  72. package/app-dist/pages/switches.html +39 -0
  73. package/app-dist/pages/tabs.html +30 -0
  74. package/app-dist/pages/toasts.html +22 -0
  75. package/app-dist/pages.json +217 -0
  76. package/app-dist/routes/alerts.js +5 -0
  77. package/app-dist/routes/avatars.js +1 -0
  78. package/app-dist/routes/badges.js +1 -0
  79. package/app-dist/routes/buttons.js +1 -0
  80. package/app-dist/routes/cards.js +1 -0
  81. package/app-dist/routes/checkboxes.js +9 -0
  82. package/app-dist/routes/chips.js +4 -0
  83. package/app-dist/routes/chunk-019e5e2f.js +5 -0
  84. package/app-dist/routes/chunk-0m4j19yd.js +2 -0
  85. package/app-dist/routes/chunk-0tmmp5q0.js +1 -0
  86. package/app-dist/routes/chunk-10xn709r.js +1 -0
  87. package/app-dist/routes/chunk-15m2qcda.js +2 -0
  88. package/app-dist/routes/chunk-1bh8g23n.js +1 -0
  89. package/app-dist/routes/chunk-1vg0v937.js +1 -0
  90. package/app-dist/routes/chunk-1zvcgy3j.js +1 -0
  91. package/app-dist/routes/chunk-2afb0861.js +1 -0
  92. package/app-dist/routes/chunk-2c6ttpzt.js +5 -0
  93. package/app-dist/routes/chunk-3dy30fhs.js +1 -0
  94. package/app-dist/routes/chunk-426dnces.js +13 -0
  95. package/app-dist/routes/chunk-44kgxery.js +1 -0
  96. package/app-dist/routes/chunk-47fdnejd.js +33 -0
  97. package/app-dist/routes/chunk-49a6t2vq.js +1 -0
  98. package/app-dist/routes/chunk-4fe1rm5b.js +1 -0
  99. package/app-dist/routes/chunk-4ggmvkta.js +33 -0
  100. package/app-dist/routes/chunk-4vkz81q7.js +33 -0
  101. package/app-dist/routes/chunk-4w4tmj8f.js +31 -0
  102. package/app-dist/routes/chunk-532s62kr.js +31 -0
  103. package/app-dist/routes/chunk-5hm3bssy.js +33 -0
  104. package/app-dist/routes/chunk-5vrh24hc.js +1 -0
  105. package/app-dist/routes/chunk-61pcg25a.js +1 -0
  106. package/app-dist/routes/chunk-6nfhygvf.js +1 -0
  107. package/app-dist/routes/chunk-700e7je6.js +33 -0
  108. package/app-dist/routes/chunk-7fsn17kg.js +1 -0
  109. package/app-dist/routes/chunk-7k789b32.js +1 -0
  110. package/app-dist/routes/chunk-7r46q0ys.js +36 -0
  111. package/app-dist/routes/chunk-86fmc1fr.js +5 -0
  112. package/app-dist/routes/chunk-8qth37vw.js +1 -0
  113. package/app-dist/routes/chunk-924wv8n0.js +1 -0
  114. package/app-dist/routes/chunk-9mbhgxk9.js +1 -0
  115. package/app-dist/routes/chunk-a216hyd9.js +1 -0
  116. package/app-dist/routes/chunk-akzxykh9.js +33 -0
  117. package/app-dist/routes/chunk-b3dcvy8c.js +1 -0
  118. package/app-dist/routes/chunk-b74zahz5.js +31 -0
  119. package/app-dist/routes/chunk-bftj53p2.js +5 -0
  120. package/app-dist/routes/chunk-c01hnz3e.js +1 -0
  121. package/app-dist/routes/chunk-d8pvv5km.js +1 -0
  122. package/app-dist/routes/chunk-dev0aezr.js +2 -0
  123. package/app-dist/routes/chunk-dh6vnv0e.js +1 -0
  124. package/app-dist/routes/chunk-dn2cbpva.js +36 -0
  125. package/app-dist/routes/chunk-dvn0my90.js +1 -0
  126. package/app-dist/routes/chunk-dvq8mnve.js +36 -0
  127. package/app-dist/routes/chunk-e8c2gc4d.js +5 -0
  128. package/app-dist/routes/chunk-ejf9ak2x.js +1 -0
  129. package/app-dist/routes/chunk-f083m55s.js +1 -0
  130. package/app-dist/routes/chunk-fnrj28s1.js +31 -0
  131. package/app-dist/routes/chunk-fvg3yjdp.js +31 -0
  132. package/app-dist/routes/chunk-g7k381n1.js +1 -0
  133. package/app-dist/routes/chunk-h01kq2ae.js +13 -0
  134. package/app-dist/routes/chunk-h4dk761v.js +5 -0
  135. package/app-dist/routes/chunk-hmx91z2x.js +5 -0
  136. package/app-dist/routes/chunk-hxbg4m42.js +36 -0
  137. package/app-dist/routes/chunk-jbjnfp2b.js +2 -0
  138. package/app-dist/routes/chunk-jxtz5vv6.js +36 -0
  139. package/app-dist/routes/chunk-jxzcs0ey.js +36 -0
  140. package/app-dist/routes/chunk-kt7wwhcx.js +1 -0
  141. package/app-dist/routes/chunk-kzptszyc.js +33 -0
  142. package/app-dist/routes/chunk-mhgca4w4.js +2 -0
  143. package/app-dist/routes/chunk-mhswxa20.js +1 -0
  144. package/app-dist/routes/chunk-n8zfeex6.js +1 -0
  145. package/app-dist/routes/chunk-pee47b2r.js +1 -0
  146. package/app-dist/routes/chunk-pesmw829.js +1 -0
  147. package/app-dist/routes/chunk-pgc4c6f3.js +36 -0
  148. package/app-dist/routes/chunk-q8egegm1.js +1 -0
  149. package/app-dist/routes/chunk-q9mn2qyq.js +36 -0
  150. package/app-dist/routes/chunk-qh0rtaf3.js +5 -0
  151. package/app-dist/routes/chunk-qqhmk6ye.js +2 -0
  152. package/app-dist/routes/chunk-qrxygmf7.js +33 -0
  153. package/app-dist/routes/chunk-r46yzksx.js +36 -0
  154. package/app-dist/routes/chunk-rgpbw2w0.js +5 -0
  155. package/app-dist/routes/chunk-rnpzv3d8.js +2 -0
  156. package/app-dist/routes/chunk-s5v8cv05.js +2 -0
  157. package/app-dist/routes/chunk-sbwn5bpc.js +1 -0
  158. package/app-dist/routes/chunk-sqbg8jbt.js +33 -0
  159. package/app-dist/routes/chunk-sv8dqnf7.js +1 -0
  160. package/app-dist/routes/chunk-t67sw3za.js +1 -0
  161. package/app-dist/routes/chunk-tjdpqwdf.js +31 -0
  162. package/app-dist/routes/chunk-tq2mfghg.js +1 -0
  163. package/app-dist/routes/chunk-ttn10vt6.js +1 -0
  164. package/app-dist/routes/chunk-v2hzpjxr.js +1 -0
  165. package/app-dist/routes/chunk-wfjjkw9y.js +1 -0
  166. package/app-dist/routes/chunk-wt8cxzmf.js +31 -0
  167. package/app-dist/routes/chunk-x45d372k.js +5 -0
  168. package/app-dist/routes/chunk-y3wsazkt.js +1 -0
  169. package/app-dist/routes/chunk-y7pmgc7t.js +33 -0
  170. package/app-dist/routes/chunk-zefdt2q3.js +31 -0
  171. package/app-dist/routes/dropdowns.js +6 -0
  172. package/app-dist/routes/home.js +1 -0
  173. package/app-dist/routes/icons.js +1 -0
  174. package/app-dist/routes/inputs.js +12 -0
  175. package/app-dist/routes/installation.js +1 -0
  176. package/app-dist/routes/layout.js +1 -0
  177. package/app-dist/routes/modals.js +7 -0
  178. package/app-dist/routes/navbar.js +1 -0
  179. package/app-dist/routes/progress.js +1 -0
  180. package/app-dist/routes/radios.js +6 -0
  181. package/app-dist/routes/switches.js +6 -0
  182. package/app-dist/routes/tabs.js +1 -0
  183. package/app-dist/routes/toasts.js +16 -0
  184. package/assets/fonts/material-symbols-mini.woff2 +0 -0
  185. package/assets/fonts/material-symbols.woff2 +0 -0
  186. package/assets/fonts/roboto-400.woff2 +0 -0
  187. package/assets/fonts/roboto-500.woff2 +0 -0
  188. package/assets/fonts/roboto-700.woff2 +0 -0
  189. package/assets/logo-banner-400.jpg +0 -0
  190. package/assets/logo-banner-400.webp +0 -0
  191. package/assets/logo-banner-800.webp +0 -0
  192. package/assets/logo-banner.jpg +0 -0
  193. package/assets/logo-icon-64.jpg +0 -0
  194. package/assets/logo-icon-64.webp +0 -0
  195. package/assets/logo-icon.jpg +0 -0
  196. package/assets/logo-square.jpg +0 -0
  197. package/bun.lock +312 -0
  198. package/bunfig.toml +4 -0
  199. package/custom-elements.json +1916 -0
  200. package/demo/api/sample-data.json +38 -0
  201. package/demo/content/alerts.html +115 -0
  202. package/demo/content/avatars.html +70 -0
  203. package/demo/content/badges.html +65 -0
  204. package/demo/content/buttons.html +188 -0
  205. package/demo/content/callouts.html +91 -0
  206. package/demo/content/cards.html +121 -0
  207. package/demo/content/checkboxes.html +178 -0
  208. package/demo/content/chips.html +67 -0
  209. package/demo/content/codeblocks.html +101 -0
  210. package/demo/content/confirms.html +115 -0
  211. package/demo/content/datatables.html +149 -0
  212. package/demo/content/dividers.html +119 -0
  213. package/demo/content/dropdowns.html +89 -0
  214. package/demo/content/enterprise.html +252 -0
  215. package/demo/content/home.html +149 -0
  216. package/demo/content/icons.html +89 -0
  217. package/demo/content/inputs.html +135 -0
  218. package/demo/content/installation.html +16 -0
  219. package/demo/content/layout.html +136 -0
  220. package/demo/content/modals.html +141 -0
  221. package/demo/content/navbar.html +70 -0
  222. package/demo/content/progress.html +119 -0
  223. package/demo/content/radios.html +88 -0
  224. package/demo/content/skeletons.html +109 -0
  225. package/demo/content/spinners.html +96 -0
  226. package/demo/content/switches.html +84 -0
  227. package/demo/content/tables.html +124 -0
  228. package/demo/content/tabs.html +85 -0
  229. package/demo/content/toasts.html +116 -0
  230. package/demo/content/tooltips.html +107 -0
  231. package/demo/content/virtual-lists.html +233 -0
  232. package/demo/favicon.ico +0 -0
  233. package/demo/favicon.png +0 -0
  234. package/demo/full.html +52 -0
  235. package/demo/iife.html +46 -0
  236. package/demo/manifest.json +34 -0
  237. package/demo/pages/datatable-demo.html +237 -0
  238. package/demo/pages/prompt-ui-demo.html +218 -0
  239. package/demo/pages/responsive-demo.html +122 -0
  240. package/demo/pages/schema-form-demo.html +270 -0
  241. package/demo/robots.txt +6 -0
  242. package/demo/shell.html +712 -0
  243. package/demo/sw.js +387 -0
  244. package/dist/AGENTS.md +2366 -0
  245. package/dist/README.md +254 -0
  246. package/dist/chunks/advanced.js +174 -0
  247. package/dist/chunks/chunk-1nhr1wrq.js +14 -0
  248. package/dist/chunks/chunk-hssyjbr0.js +2 -0
  249. package/dist/chunks/chunk-k8etzx0z.js +2 -0
  250. package/dist/chunks/chunk-rr1et8fg.js +2 -0
  251. package/dist/chunks/chunk-sjcx4fd5.js +6 -0
  252. package/dist/chunks/chunk-v1c777xh.js +5 -0
  253. package/dist/chunks/chunk-w5k5vwjd.js +13 -0
  254. package/dist/chunks/core.js +10 -0
  255. package/dist/chunks/display.js +17 -0
  256. package/dist/chunks/feedback.js +15 -0
  257. package/dist/chunks/forms.js +48 -0
  258. package/dist/chunks/layout.js +9 -0
  259. package/dist/components/chunk-4tezav8r.js +2 -0
  260. package/dist/components/chunk-fqyb2pms.js +2 -0
  261. package/dist/components/chunk-h7cdbhxw.js +13 -0
  262. package/dist/components/chunk-mzd8jwrs.js +2 -0
  263. package/dist/components/chunk-qwmxyn8e.js +2 -0
  264. package/dist/components/chunk-redtk47a.js +14 -0
  265. package/dist/components/mu-alert.js +5 -0
  266. package/dist/components/mu-api-table.js +33 -0
  267. package/dist/components/mu-avatar.js +1 -0
  268. package/dist/components/mu-badge.js +1 -0
  269. package/dist/components/mu-bottom-nav.js +1 -0
  270. package/dist/components/mu-button.js +1 -0
  271. package/dist/components/mu-callout.js +1 -0
  272. package/dist/components/mu-card.js +1 -0
  273. package/dist/components/mu-checkbox.js +9 -0
  274. package/dist/components/mu-chip.js +4 -0
  275. package/dist/components/mu-code.js +48 -0
  276. package/dist/components/mu-confirm.js +10 -0
  277. package/dist/components/mu-container.js +1 -0
  278. package/dist/components/mu-datatable.js +96 -0
  279. package/dist/components/mu-divider.js +1 -0
  280. package/dist/components/mu-doc-page.js +26 -0
  281. package/dist/components/mu-drawer-item.js +9 -0
  282. package/dist/components/mu-drawer.js +1 -0
  283. package/dist/components/mu-dropdown.js +6 -0
  284. package/dist/components/mu-error-boundary.js +10 -0
  285. package/dist/components/mu-example.js +38 -0
  286. package/dist/components/mu-fetch.js +1 -0
  287. package/dist/components/mu-form.js +1 -0
  288. package/dist/components/mu-grid.js +1 -0
  289. package/dist/components/mu-icon.js +5 -0
  290. package/dist/components/mu-input.js +12 -0
  291. package/dist/components/mu-layout.js +1 -0
  292. package/dist/components/mu-lazy.js +1 -0
  293. package/dist/components/mu-modal.js +7 -0
  294. package/dist/components/mu-navbar.js +1 -0
  295. package/dist/components/mu-page.js +1 -0
  296. package/dist/components/mu-progress.js +1 -0
  297. package/dist/components/mu-prompt-ui.js +20 -0
  298. package/dist/components/mu-radio.js +6 -0
  299. package/dist/components/mu-repeat.js +1 -0
  300. package/dist/components/mu-router.js +6 -0
  301. package/dist/components/mu-schema-form.js +76 -0
  302. package/dist/components/mu-sidebar.js +1 -0
  303. package/dist/components/mu-skeleton.js +13 -0
  304. package/dist/components/mu-spinner.js +1 -0
  305. package/dist/components/mu-stack.js +1 -0
  306. package/dist/components/mu-switch.js +6 -0
  307. package/dist/components/mu-table.js +1 -0
  308. package/dist/components/mu-tabs.js +1 -0
  309. package/dist/components/mu-textarea.js +11 -0
  310. package/dist/components/mu-theme-toggle.js +5 -0
  311. package/dist/components/mu-toast.js +4 -0
  312. package/dist/components/mu-tooltip.js +10 -0
  313. package/dist/components/mu-virtual-list.js +33 -0
  314. package/dist/components.css +1 -0
  315. package/dist/microui.css +1 -0
  316. package/dist/microui.d.ts +234 -0
  317. package/dist/microui.esm.js +549 -0
  318. package/dist/microui.esm.js.map +79 -0
  319. package/dist/microui.min.js +549 -0
  320. package/dist/microui.min.js.map +79 -0
  321. package/dist/routes/alerts.js +1 -0
  322. package/dist/routes/avatars.js +1 -0
  323. package/dist/routes/badges.js +1 -0
  324. package/dist/routes/buttons.js +1 -0
  325. package/dist/routes/callouts.js +1 -0
  326. package/dist/routes/cards.js +1 -0
  327. package/dist/routes/checkboxes.js +9 -0
  328. package/dist/routes/chips.js +4 -0
  329. package/dist/routes/chunk-19wgcncm.js +2 -0
  330. package/dist/routes/chunk-1khyr3v1.js +33 -0
  331. package/dist/routes/chunk-4rhxe97g.js +1 -0
  332. package/dist/routes/chunk-5qah04bh.js +2 -0
  333. package/dist/routes/chunk-7gfxy70n.js +5 -0
  334. package/dist/routes/chunk-e86zbeta.js +1 -0
  335. package/dist/routes/chunk-fagt36h6.js +2 -0
  336. package/dist/routes/chunk-fed7zr7m.js +1 -0
  337. package/dist/routes/chunk-hwj7pfwp.js +1 -0
  338. package/dist/routes/chunk-mhvcs2f8.js +5 -0
  339. package/dist/routes/chunk-nv3bddmj.js +13 -0
  340. package/dist/routes/chunk-q3f2aeqe.js +7 -0
  341. package/dist/routes/chunk-qxxa8trk.js +1 -0
  342. package/dist/routes/chunk-rw15y9zh.js +1 -0
  343. package/dist/routes/chunk-sfb7x11v.js +5 -0
  344. package/dist/routes/chunk-swyhghrm.js +48 -0
  345. package/dist/routes/chunk-sxddjs2d.js +2 -0
  346. package/dist/routes/chunk-vby0zg5w.js +17 -0
  347. package/dist/routes/chunk-w6zqjqqs.js +9 -0
  348. package/dist/routes/chunk-z960rexd.js +38 -0
  349. package/dist/routes/codeblocks.js +1 -0
  350. package/dist/routes/confirms.js +10 -0
  351. package/dist/routes/datatables.js +96 -0
  352. package/dist/routes/dividers.js +1 -0
  353. package/dist/routes/dropdowns.js +6 -0
  354. package/dist/routes/enterprise.js +15 -0
  355. package/dist/routes/home.js +1 -0
  356. package/dist/routes/icons.js +1 -0
  357. package/dist/routes/inputs.js +22 -0
  358. package/dist/routes/installation.js +1 -0
  359. package/dist/routes/layout.js +1 -0
  360. package/dist/routes/modals.js +1 -0
  361. package/dist/routes/navbar.js +1 -0
  362. package/dist/routes/page-components.json +316 -0
  363. package/dist/routes/progress.js +1 -0
  364. package/dist/routes/radios.js +6 -0
  365. package/dist/routes/route-deps.json +156 -0
  366. package/dist/routes/shell-critical.js +1 -0
  367. package/dist/routes/shell-deferred.js +1 -0
  368. package/dist/routes/shell.js +20 -0
  369. package/dist/routes/skeletons.js +13 -0
  370. package/dist/routes/spinners.js +1 -0
  371. package/dist/routes/src/chunks/core.js +36 -0
  372. package/dist/routes/switches.js +6 -0
  373. package/dist/routes/tables.js +1 -0
  374. package/dist/routes/tabs.js +1 -0
  375. package/dist/routes/toasts.js +1 -0
  376. package/dist/routes/tooltips.js +10 -0
  377. package/dist/routes/virtual-lists.js +33 -0
  378. package/dist/styles/common.css +1 -0
  379. package/dist/styles/components/animations.css +1 -0
  380. package/dist/styles/components/avatar.css +1 -0
  381. package/dist/styles/components/badge.css +1 -0
  382. package/dist/styles/components/bottom-nav.css +1 -0
  383. package/dist/styles/components/button.css +1 -0
  384. package/dist/styles/components/card.css +1 -0
  385. package/dist/styles/components/checkbox.css +1 -0
  386. package/dist/styles/components/chip.css +1 -0
  387. package/dist/styles/components/datatable.css +1 -0
  388. package/dist/styles/components/divider.css +1 -0
  389. package/dist/styles/components/drawer-item.css +1 -0
  390. package/dist/styles/components/drawer.css +1 -0
  391. package/dist/styles/components/grid.css +1 -0
  392. package/dist/styles/components/icon.css +1 -0
  393. package/dist/styles/components/input.css +1 -0
  394. package/dist/styles/components/layout.css +1 -0
  395. package/dist/styles/components/navbar.css +1 -0
  396. package/dist/styles/components/overlays.css +1 -0
  397. package/dist/styles/components/progress.css +1 -0
  398. package/dist/styles/components/prompt-ui.css +1 -0
  399. package/dist/styles/components/radio.css +1 -0
  400. package/dist/styles/components/schema-form.css +1 -0
  401. package/dist/styles/components/switch.css +1 -0
  402. package/dist/styles/components/tabs.css +1 -0
  403. package/dist/styles/components/tooltip.css +1 -0
  404. package/dist/styles/components/virtual-list.css +1 -0
  405. package/dist/tokens.css +1 -0
  406. package/docs/api-reference.md +175 -0
  407. package/docs/component-schema.md +231 -0
  408. package/docs/components.md +269 -0
  409. package/docs/design-system.md +183 -0
  410. package/docs/getting-started.md +198 -0
  411. package/docs/message-protocol.md +262 -0
  412. package/docs/utility-classes.md +205 -0
  413. package/lighthouse-audit.mjs +113 -0
  414. package/package.json +45 -0
  415. package/scripts/analyze-components.js +105 -0
  416. package/scripts/build-app.js +193 -0
  417. package/scripts/build-framework.js +444 -0
  418. package/scripts/build-utils.js +101 -0
  419. package/scripts/test-isolated.js +151 -0
  420. package/server.js +256 -0
  421. package/src/chunks/advanced.js +27 -0
  422. package/src/chunks/core.js +61 -0
  423. package/src/chunks/display.js +25 -0
  424. package/src/chunks/feedback.js +15 -0
  425. package/src/chunks/forms.js +25 -0
  426. package/src/chunks/layout.js +27 -0
  427. package/src/components/mu-alert.js +96 -0
  428. package/src/components/mu-api-table.js +167 -0
  429. package/src/components/mu-avatar.js +94 -0
  430. package/src/components/mu-badge.js +32 -0
  431. package/src/components/mu-bottom-nav.js +115 -0
  432. package/src/components/mu-button.js +61 -0
  433. package/src/components/mu-callout.js +71 -0
  434. package/src/components/mu-card.js +36 -0
  435. package/src/components/mu-checkbox.js +186 -0
  436. package/src/components/mu-chip.js +125 -0
  437. package/src/components/mu-code.js +534 -0
  438. package/src/components/mu-confirm.js +268 -0
  439. package/src/components/mu-container.js +53 -0
  440. package/src/components/mu-datatable.js +517 -0
  441. package/src/components/mu-divider.js +40 -0
  442. package/src/components/mu-doc-page.js +100 -0
  443. package/src/components/mu-drawer-item.js +158 -0
  444. package/src/components/mu-drawer.js +305 -0
  445. package/src/components/mu-dropdown.js +239 -0
  446. package/src/components/mu-error-boundary.js +191 -0
  447. package/src/components/mu-example.js +335 -0
  448. package/src/components/mu-fetch.js +256 -0
  449. package/src/components/mu-form.js +133 -0
  450. package/src/components/mu-grid.js +63 -0
  451. package/src/components/mu-icon.js +211 -0
  452. package/src/components/mu-input.js +142 -0
  453. package/src/components/mu-layout.js +129 -0
  454. package/src/components/mu-lazy.js +94 -0
  455. package/src/components/mu-modal.js +160 -0
  456. package/src/components/mu-navbar.js +71 -0
  457. package/src/components/mu-page.js +77 -0
  458. package/src/components/mu-progress.js +54 -0
  459. package/src/components/mu-prompt-ui.js +382 -0
  460. package/src/components/mu-radio.js +200 -0
  461. package/src/components/mu-repeat.js +135 -0
  462. package/src/components/mu-router.js +169 -0
  463. package/src/components/mu-schema-form.js +441 -0
  464. package/src/components/mu-sidebar.js +81 -0
  465. package/src/components/mu-skeleton.js +69 -0
  466. package/src/components/mu-spinner.js +30 -0
  467. package/src/components/mu-stack.js +59 -0
  468. package/src/components/mu-switch.js +150 -0
  469. package/src/components/mu-table.js +80 -0
  470. package/src/components/mu-tabs.js +112 -0
  471. package/src/components/mu-textarea.js +96 -0
  472. package/src/components/mu-theme-toggle.js +52 -0
  473. package/src/components/mu-toast.js +151 -0
  474. package/src/components/mu-tooltip.js +182 -0
  475. package/src/components/mu-virtual-list.js +184 -0
  476. package/src/core/MuElement.js +562 -0
  477. package/src/core/agent-api.js +771 -0
  478. package/src/core/breakpoints.js +195 -0
  479. package/src/core/bus.js +378 -0
  480. package/src/core/component-schema.js +287 -0
  481. package/src/core/feature-registry.js +241 -0
  482. package/src/core/form-state.js +252 -0
  483. package/src/core/http.js +104 -0
  484. package/src/core/keyboard.js +105 -0
  485. package/src/core/layers.js +71 -0
  486. package/src/core/render.js +201 -0
  487. package/src/core/ripple.js +158 -0
  488. package/src/core/router.js +100 -0
  489. package/src/core/scheduler.js +109 -0
  490. package/src/core/signals.js +164 -0
  491. package/src/core/store.js +268 -0
  492. package/src/core/theme.js +68 -0
  493. package/src/core/transitions.js +72 -0
  494. package/src/core/utils.js +30 -0
  495. package/src/index.d.ts +234 -0
  496. package/src/index.js +308 -0
  497. package/src/styles/animations.css +252 -0
  498. package/src/styles/common.css +82 -0
  499. package/src/styles/components/animations.css +129 -0
  500. package/src/styles/components/avatar.css +83 -0
  501. package/src/styles/components/badge.css +80 -0
  502. package/src/styles/components/bottom-nav.css +37 -0
  503. package/src/styles/components/button.css +348 -0
  504. package/src/styles/components/card.css +138 -0
  505. package/src/styles/components/checkbox.css +201 -0
  506. package/src/styles/components/chip.css +93 -0
  507. package/src/styles/components/datatable.css +180 -0
  508. package/src/styles/components/divider.css +49 -0
  509. package/src/styles/components/drawer-item.css +123 -0
  510. package/src/styles/components/drawer.css +273 -0
  511. package/src/styles/components/grid.css +189 -0
  512. package/src/styles/components/icon.css +40 -0
  513. package/src/styles/components/input.css +203 -0
  514. package/src/styles/components/layout.css +121 -0
  515. package/src/styles/components/navbar.css +91 -0
  516. package/src/styles/components/overlays.css +329 -0
  517. package/src/styles/components/progress.css +79 -0
  518. package/src/styles/components/prompt-ui.css +286 -0
  519. package/src/styles/components/radio.css +17 -0
  520. package/src/styles/components/schema-form.css +85 -0
  521. package/src/styles/components/switch.css +69 -0
  522. package/src/styles/components/tabs.css +145 -0
  523. package/src/styles/components/tooltip.css +93 -0
  524. package/src/styles/components/virtual-list.css +36 -0
  525. package/src/styles/components.css +3677 -0
  526. package/src/styles/routes/home.css +97 -0
  527. package/src/styles/tokens.css +675 -0
  528. package/tests/agents/agent-integration.test.js +76 -0
  529. package/tests/benchmark.html +296 -0
  530. package/tests/build/scan-components.test.js +173 -0
  531. package/tests/components/all-components.test.js +245 -0
  532. package/tests/components/all-missing-components.test.js +574 -0
  533. package/tests/components/mu-alert.test.js +113 -0
  534. package/tests/components/mu-avatar.test.js +148 -0
  535. package/tests/components/mu-badge.test.js +92 -0
  536. package/tests/components/mu-button.test.js +112 -0
  537. package/tests/components/mu-card.test.js +89 -0
  538. package/tests/components/mu-checkbox.test.js +158 -0
  539. package/tests/components/mu-chip.test.js +118 -0
  540. package/tests/components/mu-container.test.js +120 -0
  541. package/tests/components/mu-divider.test.js +98 -0
  542. package/tests/components/mu-drawer-item.test.js +199 -0
  543. package/tests/components/mu-drawer.test.js +96 -0
  544. package/tests/components/mu-dropdown.test.js +125 -0
  545. package/tests/components/mu-form.test.js +138 -0
  546. package/tests/components/mu-grid.test.js +135 -0
  547. package/tests/components/mu-icon.test.js +110 -0
  548. package/tests/components/mu-input.test.js +131 -0
  549. package/tests/components/mu-lazy.test.js +103 -0
  550. package/tests/components/mu-modal.test.js +275 -0
  551. package/tests/components/mu-navbar.test.js +101 -0
  552. package/tests/components/mu-progress.test.js +115 -0
  553. package/tests/components/mu-radio.test.js +114 -0
  554. package/tests/components/mu-repeat.test.js +106 -0
  555. package/tests/components/mu-sidebar.test.js +126 -0
  556. package/tests/components/mu-skeleton.test.js +162 -0
  557. package/tests/components/mu-stack.test.js +143 -0
  558. package/tests/components/mu-switch.test.js +292 -0
  559. package/tests/components/mu-table.test.js +124 -0
  560. package/tests/components/mu-tabs.test.js +104 -0
  561. package/tests/components/mu-textarea.test.js +115 -0
  562. package/tests/components/mu-toast.test.js +321 -0
  563. package/tests/components/mu-tooltip.test.js +133 -0
  564. package/tests/components/mu-virtual-list.test.js +109 -0
  565. package/tests/core/MuElement.test.js +120 -0
  566. package/tests/core/agent-api.test.js +125 -0
  567. package/tests/core/all-core-modules.test.js +442 -0
  568. package/tests/core/bus.test.js +364 -0
  569. package/tests/core/component-schema.test.js +160 -0
  570. package/tests/core/feature-registry.test.js +198 -0
  571. package/tests/core/form-state.test.js +167 -0
  572. package/tests/core/http.test.js +119 -0
  573. package/tests/core/keyboard.test.js +319 -0
  574. package/tests/core/layers.test.js +129 -0
  575. package/tests/core/namespaced-stores.test.js +114 -0
  576. package/tests/core/render.test.js +121 -0
  577. package/tests/core/ripple.test.js +131 -0
  578. package/tests/core/router.test.js +89 -0
  579. package/tests/core/scheduler.test.js +121 -0
  580. package/tests/core/signals.test.js +128 -0
  581. package/tests/core/store.test.js +171 -0
  582. package/tests/core/transitions.test.js +82 -0
  583. package/tests/e2e/accessibility-harness.html +58 -0
  584. package/tests/e2e/accessibility.test.js +401 -0
  585. package/tests/e2e/agent-features.test.js +372 -0
  586. package/tests/e2e/card-spacing.test.js +287 -0
  587. package/tests/e2e/components.test.js +439 -0
  588. package/tests/e2e/demo-routes.test.js +478 -0
  589. package/tests/e2e/layout-css-fallback.test.js +334 -0
  590. package/tests/e2e/mu-alert.e2e.test.js +111 -0
  591. package/tests/e2e/mu-checkbox.test.js +489 -0
  592. package/tests/e2e/mu-chip.test.js +347 -0
  593. package/tests/e2e/mu-form.test.js +499 -0
  594. package/tests/e2e/mu-icon.test.js +114 -0
  595. package/tests/e2e/mu-radio.test.js +113 -0
  596. package/tests/e2e/mu-skeleton.test.js +140 -0
  597. package/tests/e2e/mu-switch.test.js +415 -0
  598. package/tests/e2e/mu-tabs.test.js +494 -0
  599. package/tests/e2e/mu-textarea.test.js +242 -0
  600. package/tests/e2e/mu-virtual-list.test.js +427 -0
  601. package/tests/e2e/perf-memory.test.js +161 -0
  602. package/tests/e2e/puppeteer-helper.js +137 -0
  603. package/tests/e2e/puppeteer.test.js +226 -0
  604. package/tests/e2e/pwa.test.js +261 -0
  605. package/tests/e2e/test-harness.html +319 -0
  606. package/tests/manual/test-components.html +120 -0
  607. package/tests/memory-test.html +309 -0
  608. package/tests/setup-dom.js +93 -0
  609. package/tests/visual-test.html +301 -0
@@ -0,0 +1,771 @@
1
+ /**
2
+ * @fileoverview Agent-Friendly APIs for microUI
3
+ *
4
+ * Provides structured component tree access and natural language descriptions
5
+ * for LLM agents interacting with microUI components.
6
+ *
7
+ * Based on research from Agent-E (2024), WebVoyager benchmark, and
8
+ * DOM distillation techniques for AI browser automation.
9
+ *
10
+ * @module core/agent-api
11
+ */
12
+
13
+ /**
14
+ * @typedef {Object} MuComponentInfo
15
+ * @property {string} tag - Component tag name (e.g., 'mu-button')
16
+ * @property {string|null} id - Element ID if present
17
+ * @property {string} label - Accessible name/label for the component
18
+ * @property {string} description - Human-readable description of component purpose
19
+ * @property {Object} state - Current component state
20
+ * @property {string[]} actions - Available actions (e.g., ['click', 'toggle'])
21
+ * @property {Object} rect - Bounding client rect {top, left, width, height}
22
+ * @property {boolean} interactive - Whether component accepts user input
23
+ * @property {boolean} visible - Whether component is in viewport
24
+ */
25
+
26
+ /**
27
+ * Get the accessible name of an element following ARIA naming conventions
28
+ * @param {HTMLElement} el - Element to get name from
29
+ * @returns {string} Accessible name
30
+ */
31
+ function getAccessibleName(el) {
32
+ // Priority order per ARIA spec:
33
+ // 1. aria-labelledby
34
+ // 2. aria-label
35
+ // 3. associated label element
36
+ // 4. title attribute
37
+ // 5. text content (for certain roles)
38
+ // 6. placeholder (for inputs)
39
+
40
+ // aria-labelledby
41
+ const labelledBy = el.getAttribute('aria-labelledby');
42
+ if (labelledBy) {
43
+ const labels = labelledBy.split(' ')
44
+ .map(id => document.getElementById(id)?.textContent)
45
+ .filter(Boolean)
46
+ .join(' ');
47
+ if (labels) return labels;
48
+ }
49
+
50
+ // aria-label
51
+ const ariaLabel = el.getAttribute('aria-label');
52
+ if (ariaLabel) return ariaLabel;
53
+
54
+ // Associated label element
55
+ if (el.id) {
56
+ const label = document.querySelector(`label[for="${el.id}"]`);
57
+ if (label) return label.textContent.trim();
58
+ }
59
+
60
+ // title attribute
61
+ const title = el.getAttribute('title');
62
+ if (title) return title;
63
+
64
+ // Text content for buttons, links, etc.
65
+ const role = el.getAttribute('role') || el.tagName.toLowerCase();
66
+ const textRoles = ['button', 'link', 'tab', 'menuitem', 'option', 'radio', 'checkbox'];
67
+ if (textRoles.some(r => role.includes(r))) {
68
+ const text = el.textContent?.trim();
69
+ if (text && text.length < 100) return text;
70
+ }
71
+
72
+ // Placeholder for inputs
73
+ const placeholder = el.getAttribute('placeholder');
74
+ if (placeholder) return placeholder;
75
+
76
+ // Value for inputs with value
77
+ const value = el.getAttribute('value');
78
+ if (value && el.tagName.includes('INPUT')) return `Input: ${value}`;
79
+
80
+ // Fallback to tag name
81
+ return el.tagName.toLowerCase().replace('mu-', '');
82
+ }
83
+
84
+ /**
85
+ * Get available actions for a component based on its type and state
86
+ * @param {HTMLElement} el - Component element
87
+ * @returns {string[]} List of available actions
88
+ */
89
+ function getAvailableActions(el) {
90
+ const actions = [];
91
+ const tag = el.tagName.toLowerCase();
92
+ const disabled = el.hasAttribute('disabled');
93
+
94
+ if (disabled) return ['none (disabled)'];
95
+
96
+ // Common interactive actions
97
+ if (el.onclick || el.hasAttribute('onclick')) {
98
+ actions.push('click');
99
+ }
100
+
101
+ // Component-specific actions
102
+ switch (tag) {
103
+ case 'mu-button':
104
+ actions.push('click');
105
+ break;
106
+ case 'mu-checkbox':
107
+ case 'mu-switch':
108
+ actions.push('toggle', 'check', 'uncheck');
109
+ break;
110
+ case 'mu-input':
111
+ case 'mu-textarea':
112
+ actions.push('type', 'clear', 'focus');
113
+ break;
114
+ case 'mu-dropdown':
115
+ actions.push('open', 'select', 'close');
116
+ break;
117
+ case 'mu-modal':
118
+ actions.push('open', 'close');
119
+ break;
120
+ case 'mu-tabs':
121
+ actions.push('select-tab');
122
+ break;
123
+ case 'mu-radio':
124
+ actions.push('select');
125
+ break;
126
+ case 'mu-chip':
127
+ actions.push('toggle', 'click');
128
+ break;
129
+ case 'mu-confirm':
130
+ actions.push('confirm', 'cancel');
131
+ break;
132
+ default:
133
+ if (el.classList.contains('mu-button') || el.getAttribute('role') === 'button') {
134
+ actions.push('click');
135
+ }
136
+ }
137
+
138
+ return actions.length ? actions : ['focus'];
139
+ }
140
+
141
+ /**
142
+ * Get component state as a plain object
143
+ * @param {HTMLElement} el - Component element
144
+ * @returns {Object} Component state
145
+ */
146
+ function getComponentState(el) {
147
+ const state = {};
148
+ const tag = el.tagName.toLowerCase();
149
+
150
+ // Common state attributes
151
+ if (el.hasAttribute('checked')) state.checked = true;
152
+ if (el.hasAttribute('disabled')) state.disabled = true;
153
+ if (el.hasAttribute('open')) state.open = true;
154
+ if (el.hasAttribute('selected')) state.selected = true;
155
+ if (el.hasAttribute('active')) state.active = true;
156
+ if (el.hasAttribute('loading')) state.loading = true;
157
+ if (el.hasAttribute('value')) state.value = el.getAttribute('value');
158
+
159
+ // ARIA state
160
+ const ariaChecked = el.getAttribute('aria-checked');
161
+ if (ariaChecked) state.ariaChecked = ariaChecked === 'true';
162
+
163
+ const ariaExpanded = el.getAttribute('aria-expanded');
164
+ if (ariaExpanded) state.expanded = ariaExpanded === 'true';
165
+
166
+ const ariaSelected = el.getAttribute('aria-selected');
167
+ if (ariaSelected) state.selected = ariaSelected === 'true';
168
+
169
+ // Component-specific state
170
+ switch (tag) {
171
+ case 'mu-input':
172
+ case 'mu-textarea':
173
+ const input = el.querySelector('input, textarea');
174
+ if (input) {
175
+ state.value = input.value;
176
+ state.placeholder = input.placeholder;
177
+ }
178
+ break;
179
+ case 'mu-progress':
180
+ state.value = parseFloat(el.getAttribute('value') || '0');
181
+ state.max = parseFloat(el.getAttribute('max') || '100');
182
+ state.percentage = (state.value / state.max) * 100;
183
+ break;
184
+ case 'mu-dropdown':
185
+ state.value = el.getAttribute('value');
186
+ state.open = el.classList.contains('is-open');
187
+ break;
188
+ }
189
+
190
+ return state;
191
+ }
192
+
193
+ /**
194
+ * Generate a natural language description of a component
195
+ * @param {HTMLElement} el - Component element
196
+ * @returns {string} Human-readable description
197
+ */
198
+ function describeComponent(el) {
199
+ const tag = el.tagName.toLowerCase().replace('mu-', '');
200
+ const label = getAccessibleName(el);
201
+ const state = getComponentState(el);
202
+ const disabled = state.disabled ? ' (disabled)' : '';
203
+
204
+ const descriptions = {
205
+ 'button': () => `Button "${label}"${disabled}. ${state.loading ? 'Currently loading.' : 'Click to activate.'}`,
206
+ 'checkbox': () => `Checkbox "${label}"${disabled}. Currently ${state.ariaChecked || state.checked ? 'checked' : 'unchecked'}.`,
207
+ 'switch': () => `Toggle switch "${label}"${disabled}. Currently ${state.ariaChecked || state.checked ? 'on' : 'off'}.`,
208
+ 'input': () => `Text input "${label}"${disabled}. ${state.value ? `Current value: "${state.value}"` : 'Empty.'} ${state.placeholder ? `Placeholder: "${state.placeholder}"` : ''}`,
209
+ 'textarea': () => `Text area "${label}"${disabled}. ${state.value ? `Contains: "${state.value.slice(0, 50)}${state.value.length > 50 ? '...' : ''}"` : 'Empty.'}`,
210
+ 'dropdown': () => `Dropdown "${label}"${disabled}. ${state.value ? `Selected: "${state.value}"` : 'No selection.'} ${state.open ? 'Menu is open.' : 'Menu is closed.'}`,
211
+ 'modal': () => `Modal dialog${state.open ? ' (currently open)' : ' (currently closed)'}. ${label !== 'modal' ? `Title: "${label}"` : ''}`,
212
+ 'tabs': () => `Tab navigation with ${el.querySelectorAll('mu-tab').length} tabs.`,
213
+ 'tab': () => `Tab "${label}". ${state.active ? 'Currently active.' : 'Inactive.'}`,
214
+ 'progress': () => `Progress bar at ${Math.round(state.percentage || 0)}%.`,
215
+ 'spinner': () => 'Loading spinner indicating operation in progress.',
216
+ 'alert': () => `Alert message: "${el.textContent?.trim().slice(0, 100) || label}"`,
217
+ 'card': () => `Card container${label !== 'card' ? ` titled "${label}"` : ''}.`,
218
+ 'chip': () => `Chip "${label}"${disabled}. ${state.selected ? 'Selected.' : 'Not selected.'}`,
219
+ 'badge': () => `Badge showing "${el.textContent?.trim() || 'notification'}"`,
220
+ 'avatar': () => `User avatar${el.getAttribute('name') ? ` for "${el.getAttribute('name')}"` : ''}`,
221
+ 'icon': () => `Icon: ${el.getAttribute('name') || 'decorative'}`,
222
+ 'confirm': () => `Confirmation dialog. ${state.open ? 'Waiting for user response.' : 'Hidden.'}`,
223
+ 'fetch': () => `Data fetcher${state.loading ? ' (loading)' : ''}. URL: ${el.getAttribute('url') || 'not set'}`
224
+ };
225
+
226
+ const describer = descriptions[tag];
227
+ if (describer) return describer();
228
+
229
+ // Generic fallback
230
+ return `${tag} component${label ? ` "${label}"` : ''}${disabled}.`;
231
+ }
232
+
233
+ /**
234
+ * Check if element is visible in viewport
235
+ * @param {HTMLElement} el
236
+ * @returns {boolean}
237
+ */
238
+ function isInViewport(el) {
239
+ const rect = el.getBoundingClientRect();
240
+ return (
241
+ rect.top < window.innerHeight &&
242
+ rect.bottom > 0 &&
243
+ rect.left < window.innerWidth &&
244
+ rect.right > 0 &&
245
+ rect.width > 0 &&
246
+ rect.height > 0
247
+ );
248
+ }
249
+
250
+ /**
251
+ * Get a simplified component tree for agent parsing
252
+ * Implements DOM distillation as per Agent-E (2024) research
253
+ *
254
+ * @param {HTMLElement} [root=document.body] - Root element to scan
255
+ * @param {Object} [options] - Options
256
+ * @param {boolean} [options.visibleOnly=false] - Only include visible components
257
+ * @param {boolean} [options.interactiveOnly=false] - Only include interactive components
258
+ * @param {string[]} [options.types] - Filter to specific component types
259
+ * @returns {MuComponentInfo[]} Array of component info objects
260
+ *
261
+ * @example
262
+ * // Get all components
263
+ * const tree = getMuComponentTree();
264
+ *
265
+ * // Get only visible interactive components
266
+ * const interactive = getMuComponentTree(document.body, {
267
+ * visibleOnly: true,
268
+ * interactiveOnly: true
269
+ * });
270
+ *
271
+ * // Get only buttons and inputs
272
+ * const forms = getMuComponentTree(document.body, {
273
+ * types: ['mu-button', 'mu-input', 'mu-checkbox']
274
+ * });
275
+ */
276
+ export function getMuComponentTree(root = document.body, options = {}) {
277
+ const { visibleOnly = false, interactiveOnly = false, types = null } = options;
278
+
279
+ // Find all mu-* components
280
+ const selector = types
281
+ ? types.join(',')
282
+ : '[class^="mu-"]:not(.mu-ripple-wave)';
283
+
284
+ const elements = root.querySelectorAll(selector);
285
+ const results = [];
286
+
287
+ const interactiveTags = new Set([
288
+ 'mu-button', 'mu-checkbox', 'mu-switch', 'mu-input', 'mu-textarea',
289
+ 'mu-dropdown', 'mu-radio', 'mu-tab', 'mu-chip', 'mu-modal', 'mu-confirm'
290
+ ]);
291
+
292
+ for (const el of elements) {
293
+ const tag = el.tagName.toLowerCase();
294
+
295
+ // Skip non-mu elements that happen to match selector
296
+ if (!tag.startsWith('mu-')) continue;
297
+
298
+ const isInteractive = interactiveTags.has(tag);
299
+ const visible = isInViewport(el);
300
+
301
+ // Apply filters
302
+ if (visibleOnly && !visible) continue;
303
+ if (interactiveOnly && !isInteractive) continue;
304
+
305
+ const rect = el.getBoundingClientRect();
306
+
307
+ results.push({
308
+ tag,
309
+ id: el.id || null,
310
+ label: getAccessibleName(el),
311
+ description: describeComponent(el),
312
+ state: getComponentState(el),
313
+ actions: getAvailableActions(el),
314
+ rect: {
315
+ top: Math.round(rect.top),
316
+ left: Math.round(rect.left),
317
+ width: Math.round(rect.width),
318
+ height: Math.round(rect.height)
319
+ },
320
+ interactive: isInteractive,
321
+ visible
322
+ });
323
+ }
324
+
325
+ return results;
326
+ }
327
+
328
+ /**
329
+ * Describe a single component in natural language
330
+ * @param {HTMLElement|string} component - Element or CSS selector
331
+ * @returns {string|null} Natural language description or null if not found
332
+ */
333
+ export function describe(component) {
334
+ const el = typeof component === 'string'
335
+ ? document.querySelector(component)
336
+ : component;
337
+
338
+ if (!el) return null;
339
+ return describeComponent(el);
340
+ }
341
+
342
+ /**
343
+ * Get a map of all registered microUI custom elements
344
+ * @returns {Map<string, typeof HTMLElement>} Map of tag names to constructors
345
+ */
346
+ export function getRegisteredComponents() {
347
+ const components = new Map();
348
+ const possibleTags = [
349
+ 'mu-button', 'mu-input', 'mu-textarea', 'mu-checkbox', 'mu-switch',
350
+ 'mu-dropdown', 'mu-option', 'mu-radio', 'mu-radio-group', 'mu-chip',
351
+ 'mu-card', 'mu-tabs', 'mu-tab', 'mu-alert', 'mu-badge', 'mu-progress',
352
+ 'mu-avatar', 'mu-skeleton', 'mu-spinner', 'mu-modal', 'mu-toast',
353
+ 'mu-tooltip', 'mu-icon', 'mu-stack', 'mu-grid', 'mu-container',
354
+ 'mu-navbar', 'mu-sidebar', 'mu-divider', 'mu-theme-toggle',
355
+ 'mu-virtual-list', 'mu-lazy', 'mu-repeat', 'mu-form', 'mu-table',
356
+ 'mu-confirm', 'mu-fetch'
357
+ ];
358
+
359
+ for (const tag of possibleTags) {
360
+ const constructor = customElements.get(tag);
361
+ if (constructor) {
362
+ components.set(tag, constructor);
363
+ }
364
+ }
365
+
366
+ return components;
367
+ }
368
+
369
+ /**
370
+ * Find components by their accessible label (fuzzy match)
371
+ * @param {string} labelQuery - Label text to search for
372
+ * @param {HTMLElement} [root=document.body] - Root to search within
373
+ * @returns {HTMLElement[]} Matching components
374
+ */
375
+ export function findByLabel(labelQuery, root = document.body) {
376
+ const query = labelQuery.toLowerCase();
377
+ const tree = getMuComponentTree(root);
378
+
379
+ return tree
380
+ .filter(info => info.label.toLowerCase().includes(query))
381
+ .map(info => {
382
+ const selector = info.id
383
+ ? `#${info.id}`
384
+ : `${info.tag}`;
385
+ return root.querySelector(selector);
386
+ })
387
+ .filter(Boolean);
388
+ }
389
+
390
+ // ============================================
391
+ // 2026 VISUAL MARKERS (UI-TARS Research)
392
+ // ============================================
393
+
394
+ let markersEnabled = false;
395
+ let markerContainer = null;
396
+ const markerMap = new Map(); // element -> marker element
397
+
398
+ /**
399
+ * Enable visual markers on interactive elements for screenshot-based AI agents.
400
+ * Based on UI-TARS (2025) hybrid DOM+Vision research.
401
+ *
402
+ * Adds overlay labels like [B1], [I1], [C1] to each interactive element.
403
+ *
404
+ * @param {Object} [options] - Options
405
+ * @param {boolean} [options.showLabels=true] - Show text labels ([B1], etc.)
406
+ * @param {boolean} [options.showBoxes=true] - Show bounding boxes
407
+ * @param {string} [options.markerStyle='badge'] - Style: 'badge' | 'corner' | 'outline'
408
+ * @returns {Map<string, HTMLElement>} Map of marker IDs to elements
409
+ *
410
+ * @example
411
+ * const markers = microUI.enableVisualMarkers();
412
+ * // Take screenshot
413
+ * // Agent sees: [B1] Save, [B2] Cancel, [I1] Email input
414
+ */
415
+ export function enableVisualMarkers(options = {}) {
416
+ const { showLabels = true, showBoxes = true, markerStyle = 'badge' } = options;
417
+
418
+ // Disable first if already enabled
419
+ if (markersEnabled) disableVisualMarkers();
420
+
421
+ // Create container
422
+ markerContainer = document.createElement('div');
423
+ markerContainer.id = 'mu-visual-markers';
424
+ markerContainer.style.cssText = `
425
+ position: fixed;
426
+ inset: 0;
427
+ pointer-events: none;
428
+ z-index: 999999;
429
+ `;
430
+ document.body.appendChild(markerContainer);
431
+
432
+ // Counter prefixes by type
433
+ const counters = { B: 0, I: 0, C: 0, S: 0, D: 0, M: 0, T: 0, R: 0, O: 0 };
434
+
435
+ // Get type prefix
436
+ const getPrefix = (tag) => {
437
+ const prefixes = {
438
+ 'mu-button': 'B',
439
+ 'mu-input': 'I',
440
+ 'mu-textarea': 'I',
441
+ 'mu-checkbox': 'C',
442
+ 'mu-switch': 'S',
443
+ 'mu-dropdown': 'D',
444
+ 'mu-modal': 'M',
445
+ 'mu-tabs': 'T',
446
+ 'mu-tab': 'T',
447
+ 'mu-radio': 'R',
448
+ 'mu-chip': 'C',
449
+ 'mu-confirm': 'M'
450
+ };
451
+ return prefixes[tag] || 'O';
452
+ };
453
+
454
+ // Get interactive components
455
+ const tree = getMuComponentTree(document.body, { interactiveOnly: true, visibleOnly: true });
456
+
457
+ for (const info of tree) {
458
+ const prefix = getPrefix(info.tag);
459
+ counters[prefix]++;
460
+ const markerId = `${prefix}${counters[prefix]}`;
461
+
462
+ const el = document.querySelector(
463
+ info.id ? `#${info.id}` : `${info.tag}[data-mu-action="${info.state.action || ''}"]`
464
+ ) || document.querySelector(info.tag);
465
+
466
+ if (!el) continue;
467
+
468
+ const rect = el.getBoundingClientRect();
469
+
470
+ // Create marker
471
+ const marker = document.createElement('div');
472
+ marker.className = 'mu-visual-marker';
473
+ marker.dataset.markerId = markerId;
474
+ marker.dataset.tag = info.tag;
475
+ marker.dataset.label = info.label;
476
+
477
+ const bgColor = {
478
+ 'B': '#7C4DFF', // Buttons - purple
479
+ 'I': '#00BCD4', // Inputs - cyan
480
+ 'C': '#4CAF50', // Checkboxes - green
481
+ 'S': '#FF9800', // Switches - orange
482
+ 'D': '#2196F3', // Dropdowns - blue
483
+ 'M': '#E91E63', // Modals - pink
484
+ 'T': '#9C27B0', // Tabs - deep purple
485
+ 'R': '#795548', // Radio - brown
486
+ 'O': '#607D8B' // Other - grey
487
+ }[prefix];
488
+
489
+ if (markerStyle === 'badge') {
490
+ marker.style.cssText = `
491
+ position: fixed;
492
+ top: ${rect.top - 8}px;
493
+ left: ${rect.left - 8}px;
494
+ background: ${bgColor};
495
+ color: white;
496
+ font: bold 11px system-ui;
497
+ padding: 2px 6px;
498
+ border-radius: 4px;
499
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3);
500
+ white-space: nowrap;
501
+ `;
502
+ marker.textContent = showLabels ? `${markerId}` : '';
503
+ } else if (markerStyle === 'outline') {
504
+ marker.style.cssText = `
505
+ position: fixed;
506
+ top: ${rect.top}px;
507
+ left: ${rect.left}px;
508
+ width: ${rect.width}px;
509
+ height: ${rect.height}px;
510
+ border: 2px solid ${bgColor};
511
+ border-radius: 4px;
512
+ box-shadow: 0 0 0 1px rgba(255,255,255,0.5);
513
+ `;
514
+ if (showLabels) {
515
+ const label = document.createElement('span');
516
+ label.style.cssText = `
517
+ position: absolute;
518
+ top: -18px;
519
+ left: -2px;
520
+ background: ${bgColor};
521
+ color: white;
522
+ font: bold 10px system-ui;
523
+ padding: 1px 4px;
524
+ border-radius: 2px;
525
+ `;
526
+ label.textContent = markerId;
527
+ marker.appendChild(label);
528
+ }
529
+ }
530
+
531
+ markerContainer.appendChild(marker);
532
+ markerMap.set(markerId, el);
533
+ }
534
+
535
+ markersEnabled = true;
536
+ return markerMap;
537
+ }
538
+
539
+ /**
540
+ * Disable visual markers
541
+ */
542
+ export function disableVisualMarkers() {
543
+ if (markerContainer) {
544
+ markerContainer.remove();
545
+ markerContainer = null;
546
+ }
547
+ markerMap.clear();
548
+ markersEnabled = false;
549
+ }
550
+
551
+ /**
552
+ * Get element by visual marker ID
553
+ * @param {string} markerId - Marker ID (e.g., 'B1', 'I2')
554
+ * @returns {HTMLElement|null}
555
+ */
556
+ export function getMarkerElement(markerId) {
557
+ return markerMap.get(markerId) || null;
558
+ }
559
+
560
+ /**
561
+ * Get all current marker mappings
562
+ * @returns {Object} Object mapping marker IDs to element info
563
+ */
564
+ export function getMarkerMap() {
565
+ const result = {};
566
+ for (const [id, el] of markerMap) {
567
+ result[id] = {
568
+ tag: el.tagName.toLowerCase(),
569
+ label: getAccessibleName(el),
570
+ actions: getAvailableActions(el)
571
+ };
572
+ }
573
+ return result;
574
+ }
575
+
576
+ // ============================================
577
+ // 2026 MCP ACTIONS (Anthropic/Google Standard)
578
+ // ============================================
579
+
580
+ /**
581
+ * Get available actions in MCP (Model Context Protocol) compatible format.
582
+ * This is the emerging standard for agent-tool communication in 2026.
583
+ *
584
+ * @returns {Object} MCP-compatible action schema
585
+ *
586
+ * @example
587
+ * const actions = microUI.getMCPActions();
588
+ * // Returns:
589
+ * // {
590
+ * // name: "microui",
591
+ * // description: "Interact with microUI web components",
592
+ * // actions: [
593
+ * // { name: "click_button", parameters: { selector: {...} } },
594
+ * // { name: "fill_input", parameters: { selector: {...}, value: {...} } }
595
+ * // ]
596
+ * // }
597
+ */
598
+ export function getMCPActions() {
599
+ return {
600
+ name: 'microui',
601
+ version: '3.4.0',
602
+ description: 'Interact with microUI Material Design 3 web components',
603
+ actions: [
604
+ {
605
+ name: 'click_button',
606
+ description: 'Click a button element',
607
+ parameters: {
608
+ selector: {
609
+ type: 'string',
610
+ description: 'CSS selector, marker ID (e.g., "B1"), or label text',
611
+ required: true
612
+ }
613
+ }
614
+ },
615
+ {
616
+ name: 'fill_input',
617
+ description: 'Fill an input or textarea with text',
618
+ parameters: {
619
+ selector: {
620
+ type: 'string',
621
+ description: 'CSS selector, marker ID (e.g., "I1"), or label text',
622
+ required: true
623
+ },
624
+ value: {
625
+ type: 'string',
626
+ description: 'Text to enter',
627
+ required: true
628
+ },
629
+ clear: {
630
+ type: 'boolean',
631
+ description: 'Clear existing content first',
632
+ default: true
633
+ }
634
+ }
635
+ },
636
+ {
637
+ name: 'toggle_checkbox',
638
+ description: 'Toggle a checkbox or switch',
639
+ parameters: {
640
+ selector: {
641
+ type: 'string',
642
+ description: 'CSS selector, marker ID, or label text',
643
+ required: true
644
+ },
645
+ checked: {
646
+ type: 'boolean',
647
+ description: 'Target state (true=checked, false=unchecked)',
648
+ required: false
649
+ }
650
+ }
651
+ },
652
+ {
653
+ name: 'select_option',
654
+ description: 'Select an option in a dropdown',
655
+ parameters: {
656
+ selector: {
657
+ type: 'string',
658
+ description: 'CSS selector for dropdown',
659
+ required: true
660
+ },
661
+ value: {
662
+ type: 'string',
663
+ description: 'Option value or text to select',
664
+ required: true
665
+ }
666
+ }
667
+ },
668
+ {
669
+ name: 'open_modal',
670
+ description: 'Open a modal dialog',
671
+ parameters: {
672
+ selector: {
673
+ type: 'string',
674
+ description: 'CSS selector for modal',
675
+ required: true
676
+ }
677
+ }
678
+ },
679
+ {
680
+ name: 'close_modal',
681
+ description: 'Close a modal dialog',
682
+ parameters: {
683
+ selector: {
684
+ type: 'string',
685
+ description: 'CSS selector for modal',
686
+ required: true
687
+ }
688
+ }
689
+ },
690
+ {
691
+ name: 'select_tab',
692
+ description: 'Select a tab by index or label',
693
+ parameters: {
694
+ tabs_selector: {
695
+ type: 'string',
696
+ description: 'CSS selector for mu-tabs container',
697
+ required: true
698
+ },
699
+ index: {
700
+ type: 'number',
701
+ description: 'Tab index (0-based)',
702
+ required: false
703
+ },
704
+ label: {
705
+ type: 'string',
706
+ description: 'Tab label text',
707
+ required: false
708
+ }
709
+ }
710
+ },
711
+ {
712
+ name: 'get_component_tree',
713
+ description: 'Get structured tree of all microUI components',
714
+ parameters: {
715
+ visible_only: {
716
+ type: 'boolean',
717
+ description: 'Only include visible components',
718
+ default: true
719
+ },
720
+ interactive_only: {
721
+ type: 'boolean',
722
+ description: 'Only include interactive components',
723
+ default: false
724
+ }
725
+ }
726
+ },
727
+ {
728
+ name: 'enable_visual_markers',
729
+ description: 'Enable visual markers for screenshot parsing',
730
+ parameters: {
731
+ style: {
732
+ type: 'string',
733
+ enum: ['badge', 'outline'],
734
+ description: 'Marker visual style',
735
+ default: 'badge'
736
+ }
737
+ }
738
+ },
739
+ {
740
+ name: 'confirm_dialog',
741
+ description: 'Respond to a confirmation dialog',
742
+ parameters: {
743
+ action: {
744
+ type: 'string',
745
+ enum: ['confirm', 'cancel'],
746
+ description: 'Whether to confirm or cancel',
747
+ required: true
748
+ }
749
+ }
750
+ }
751
+ ]
752
+ };
753
+ }
754
+
755
+ // Export for global access
756
+ export const AgentAPI = {
757
+ getMuComponentTree,
758
+ describe,
759
+ getRegisteredComponents,
760
+ findByLabel,
761
+ getAccessibleName,
762
+ getAvailableActions,
763
+ getComponentState,
764
+ // 2026 Visual Markers
765
+ enableVisualMarkers,
766
+ disableVisualMarkers,
767
+ getMarkerElement,
768
+ getMarkerMap,
769
+ // 2026 MCP Actions
770
+ getMCPActions
771
+ };