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,562 @@
1
+ /**
2
+ * @fileoverview MuElement - Base Web Component Class (Optimized)
3
+ *
4
+ * 2025/2026 Best Practices Applied:
5
+ * - Proper disconnectedCallback for memory safety
6
+ * - Event listener tracking and cleanup
7
+ * - AbortController for efficient listener removal
8
+ * - CSS containment hints
9
+ * - No memory leaks guaranteed
10
+ *
11
+ * Performance optimizations:
12
+ * - No Shadow DOM overhead
13
+ * - Efficient attribute observation
14
+ * - DOM updates via mutation, not recreation
15
+ * - content-visibility auto for off-screen elements
16
+ */
17
+
18
+ export class MuElement extends HTMLElement {
19
+ /** @type {string[]} Attributes to observe for changes */
20
+ static observedAttributes = [];
21
+
22
+ /** @type {string} Base CSS class for the component */
23
+ static baseClass = '';
24
+
25
+ /** @type {string|null} CSS file name for lazy loading (e.g., 'button' loads components/button.css) */
26
+ static cssFile = null;
27
+
28
+ /** @type {Set} Track loaded CSS files globally to prevent duplicates */
29
+ static _loadedCSS = new Set();
30
+
31
+ /** @type {boolean} Apply CSS containment for perf */
32
+ static useContainment = true;
33
+
34
+ /** @type {boolean} Track if initial render has occurred */
35
+ _rendered = false;
36
+
37
+ /** @type {AbortController} For cleaning up event listeners */
38
+ _abortController = null;
39
+
40
+ /** @type {Set} Track timers for cleanup */
41
+ _timers = new Set();
42
+
43
+ /** @type {Set} Track intervals for cleanup */
44
+ _intervals = new Set();
45
+
46
+ constructor() {
47
+ super();
48
+ this._initAgentLogger();
49
+ }
50
+
51
+ _initAgentLogger() {
52
+ if (!window.__MICROUI_ERRORS__) {
53
+ window.__MICROUI_ERRORS__ = [];
54
+ }
55
+
56
+ // Agent Help Utilities
57
+ if (!window.microUIAgent) {
58
+ window.microUIAgent = {
59
+ // Clear errors for a fresh test
60
+ reset: () => {
61
+ window.__MICROUI_ERRORS__ = [];
62
+ console.log('[microUIAgent] Errors cleared');
63
+ },
64
+ // Get all errors
65
+ getErrors: () => window.__MICROUI_ERRORS__,
66
+ // Check if component has error
67
+ hasError: (tagName, code) => {
68
+ return window.__MICROUI_ERRORS__.some(e =>
69
+ e.component === tagName.toLowerCase() && e.code === code
70
+ );
71
+ }
72
+ };
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Log error for Agent Debugging (Puppeteer/Playwright access)
78
+ * @param {string} code - Error code (e.g. 'A11Y_MISSING_LABEL')
79
+ * @param {string} message - Human readable message
80
+ */
81
+ logError(code, message) {
82
+ const error = {
83
+ component: this.tagName.toLowerCase(),
84
+ code,
85
+ message,
86
+ element: this, // Reference leak only if used in dev tools, should be safe for tests
87
+ timestamp: Date.now()
88
+ };
89
+ window.__MICROUI_ERRORS__.push(error);
90
+ console.warn(`[microUI] ${code}: ${message}`, this);
91
+ }
92
+
93
+ /**
94
+ * Called when element is added to DOM.
95
+ * Sets up base class, containment, and triggers initial render.
96
+ */
97
+ connectedCallback() {
98
+ // Reuse existing AbortController to prevent duplicate event listeners
99
+ // when element is moved in DOM (connectedCallback called multiple times)
100
+ if (!this._abortController) {
101
+ this._abortController = new AbortController();
102
+ }
103
+
104
+ // Add base class
105
+ if (this.constructor.baseClass) {
106
+ this.classList.add(this.constructor.baseClass);
107
+ }
108
+
109
+ // Apply CSS containment for rendering performance
110
+ if (this.constructor.useContainment && !this.style.contain) {
111
+ this.style.contain = 'layout style';
112
+ }
113
+
114
+ // SOTA 2026: Automatic event delegation on component root
115
+ // Single listener handles all [data-action] clicks - no timing issues
116
+ // Attached BEFORE render so it catches events on dynamically created elements
117
+ this.#setupEventDelegation();
118
+
119
+ // Initial render
120
+ if (!this._rendered) {
121
+ this.render();
122
+ this._rendered = true;
123
+ }
124
+
125
+ // Lazy load component CSS
126
+ this._loadComponentCSS();
127
+
128
+ // 2026 Agent Optimization: Auto-infer semantic action attributes
129
+ this._inferSemanticAttributes();
130
+ }
131
+
132
+ /**
133
+ * SOTA 2026: Centralized event delegation pattern.
134
+ * Single click listener on component root that delegates to [data-action] elements.
135
+ * Components implement handleAction(action, target, event) to handle actions.
136
+ * @private
137
+ */
138
+ #setupEventDelegation() {
139
+ this.listen(this, 'click', (e) => {
140
+ const actionEl = e.target.closest('[data-action]');
141
+ if (!actionEl || !this.contains(actionEl)) return;
142
+
143
+ const action = actionEl.dataset.action;
144
+ if (this.handleAction) {
145
+ this.handleAction(action, actionEl, e);
146
+ }
147
+ });
148
+ }
149
+
150
+ /**
151
+ * Lazy load component-specific CSS file.
152
+ * Only loads once per CSS file across all instances.
153
+ * @private
154
+ */
155
+ _loadComponentCSS() {
156
+ const cssFile = this.constructor.cssFile;
157
+ if (!cssFile) return;
158
+
159
+ // Check if already loaded (global static Set)
160
+ if (MuElement._loadedCSS.has(cssFile)) return;
161
+ MuElement._loadedCSS.add(cssFile);
162
+
163
+ // Create and append link element
164
+ const link = document.createElement('link');
165
+ link.id = `mu-css-${cssFile}`;
166
+ link.rel = 'stylesheet';
167
+
168
+ // Determine base path - check multiple sources
169
+ let basePath = '/styles/';
170
+
171
+ // 1. Check for existing styles/ link (direct styles loading)
172
+ const stylesLink = document.querySelector('link[href*="/styles/"]');
173
+ if (stylesLink) {
174
+ const match = stylesLink.href.match(/(.*\/(?:src\/|dist\/)?styles\/)/);
175
+ if (match) basePath = match[1];
176
+ }
177
+ // 2. Check for dist/microui.css (shell.html pattern) -> use dist/styles/
178
+ else {
179
+ const distLink = document.querySelector('link[href*="/dist/"]');
180
+ if (distLink) {
181
+ const match = distLink.href.match(/(.*\/dist\/)/);
182
+ if (match) basePath = match[1] + 'styles/';
183
+ }
184
+ // 3. Check for src/ pattern in scripts (dev mode)
185
+ else {
186
+ const srcScript = document.querySelector('script[src*="/src/"]');
187
+ if (srcScript) {
188
+ const match = srcScript.src.match(/(.*\/src\/)/);
189
+ if (match) basePath = match[1] + 'styles/';
190
+ }
191
+ }
192
+ }
193
+
194
+ link.href = `${basePath}components/${cssFile}.css`;
195
+ document.head.appendChild(link);
196
+ }
197
+
198
+ /**
199
+ * Infer and set data-mu-action and data-mu-role attributes for AI agents.
200
+ * Based on 2026 Agentic Web research - semantic attributes reduce task failure.
201
+ * @private
202
+ */
203
+ _inferSemanticAttributes() {
204
+ const tag = this.tagName.toLowerCase();
205
+
206
+ // Skip if already has explicit action
207
+ if (this.hasAttribute('data-mu-action')) return;
208
+
209
+ // Infer action based on component type
210
+ let action = '';
211
+ let role = '';
212
+
213
+ switch (tag) {
214
+ case 'mu-button':
215
+ action = this._inferButtonAction();
216
+ role = this._inferButtonRole();
217
+ break;
218
+ case 'mu-input':
219
+ case 'mu-textarea':
220
+ action = 'input';
221
+ role = 'text-field';
222
+ break;
223
+ case 'mu-checkbox':
224
+ case 'mu-switch':
225
+ action = 'toggle';
226
+ role = 'control';
227
+ break;
228
+ case 'mu-dropdown':
229
+ action = 'select';
230
+ role = 'selector';
231
+ break;
232
+ case 'mu-modal':
233
+ action = 'dialog';
234
+ role = 'overlay';
235
+ break;
236
+ case 'mu-tabs':
237
+ action = 'navigate';
238
+ role = 'navigation';
239
+ break;
240
+ case 'mu-card':
241
+ role = 'container';
242
+ break;
243
+ }
244
+
245
+ if (action) this.setAttribute('data-mu-action', action);
246
+ if (role) this.setAttribute('data-mu-role', role);
247
+ }
248
+
249
+ /**
250
+ * Infer button action from text content
251
+ * @private
252
+ */
253
+ _inferButtonAction() {
254
+ const text = this.textContent?.toLowerCase().trim() || '';
255
+
256
+ // Submit/Save patterns
257
+ if (/^(save|submit|confirm|send|create|add|apply|ok|yes)$/.test(text)) {
258
+ return 'submit';
259
+ }
260
+ // Cancel/Close patterns
261
+ if (/^(cancel|close|dismiss|no|nevermind)$/.test(text)) {
262
+ return 'cancel';
263
+ }
264
+ // Delete/Remove patterns
265
+ if (/^(delete|remove|clear|trash)$/.test(text)) {
266
+ return 'delete';
267
+ }
268
+ // Navigation patterns
269
+ if (/^(back|next|previous|forward|continue)$/.test(text)) {
270
+ return 'navigate';
271
+ }
272
+ // Default
273
+ return 'click';
274
+ }
275
+
276
+ /**
277
+ * Infer button role from context
278
+ * @private
279
+ */
280
+ _inferButtonRole() {
281
+ const variant = this.getAttribute('variant');
282
+
283
+ // Primary action buttons
284
+ if (variant === 'filled' || variant === 'elevated') {
285
+ return 'primary-action';
286
+ }
287
+ // Secondary actions
288
+ if (variant === 'tonal' || variant === 'outlined') {
289
+ return 'secondary-action';
290
+ }
291
+ // Tertiary/dismiss
292
+ if (variant === 'text') {
293
+ return 'tertiary-action';
294
+ }
295
+ // Danger
296
+ if (variant === 'danger') {
297
+ return 'destructive-action';
298
+ }
299
+ return 'action';
300
+ }
301
+
302
+ /**
303
+ * Called when element is removed from DOM.
304
+ * CRITICAL: Clean up all event listeners and timers to prevent memory leaks.
305
+ */
306
+ disconnectedCallback() {
307
+ // Abort all event listeners registered with signal
308
+ if (this._abortController) {
309
+ this._abortController.abort();
310
+ this._abortController = null;
311
+ }
312
+
313
+ // Clear all timers
314
+ for (const timer of this._timers) {
315
+ clearTimeout(timer);
316
+ }
317
+ this._timers.clear();
318
+
319
+ // Clear all intervals
320
+ for (const interval of this._intervals) {
321
+ clearInterval(interval);
322
+ }
323
+ this._intervals.clear();
324
+
325
+ // Call subclass cleanup
326
+ this.cleanup();
327
+ }
328
+
329
+ /**
330
+ * Override in subclass for custom cleanup logic.
331
+ * Called when component is removed from DOM.
332
+ */
333
+ cleanup() {
334
+ // Override in subclass
335
+ }
336
+
337
+ /**
338
+ * Called when observed attribute changes.
339
+ * Triggers efficient update, not full re-render.
340
+ */
341
+ attributeChangedCallback(name, oldValue, newValue) {
342
+ if (oldValue !== newValue && this._rendered) {
343
+ this.update(name, newValue, oldValue);
344
+ }
345
+ }
346
+
347
+ /**
348
+ * Initial render - override in subclass.
349
+ */
350
+ render() {
351
+ // Override in subclass
352
+ }
353
+
354
+ /**
355
+ * Efficient update - override in subclass.
356
+ * Modifies existing DOM, never recreates.
357
+ */
358
+ update(attr, newValue, oldValue) {
359
+ // Override in subclass
360
+ }
361
+
362
+ /**
363
+ * SOTA 2026: Deferred event setup - override in subclass.
364
+ * Called via queueMicrotask AFTER render() completes.
365
+ * Guarantees DOM is stable before attaching listeners.
366
+ * Use this.listen() for automatic cleanup on disconnect.
367
+ *
368
+ * @example
369
+ * setupEvents() {
370
+ * this.listen(this.button, 'click', () => this.handleClick());
371
+ * }
372
+ */
373
+ setupEvents() {
374
+ // Override in subclass
375
+ }
376
+
377
+ /**
378
+ * Helper: Get attribute with default
379
+ */
380
+ attr(name, defaultValue = '') {
381
+ return this.getAttribute(name) ?? defaultValue;
382
+ }
383
+
384
+ /**
385
+ * Helper: Check if attribute exists
386
+ */
387
+ has(name) {
388
+ return this.hasAttribute(name);
389
+ }
390
+
391
+ /**
392
+ * Helper: Emit a custom event
393
+ */
394
+ emit(name, detail = {}) {
395
+ this.dispatchEvent(new CustomEvent(name, {
396
+ bubbles: true,
397
+ composed: true,
398
+ detail
399
+ }));
400
+ }
401
+
402
+ /**
403
+ * Safe addEventListener with automatic cleanup on disconnect.
404
+ * Uses AbortController signal for efficient removal.
405
+ *
406
+ * @param {string} type - Event type
407
+ * @param {EventListener} listener - Event handler
408
+ * @param {AddEventListenerOptions} options - Event options
409
+ */
410
+ listen(target, type, listener, options = {}) {
411
+ if (!this._abortController) {
412
+ this._abortController = new AbortController();
413
+ }
414
+
415
+ const opts = {
416
+ ...options,
417
+ signal: this._abortController.signal
418
+ };
419
+
420
+ target.addEventListener(type, listener, opts);
421
+ }
422
+
423
+ /**
424
+ * Safe setTimeout with automatic cleanup on disconnect.
425
+ * @param {Function} fn - Callback
426
+ * @param {number} delay - Delay in ms
427
+ * @returns {number} Timer ID
428
+ */
429
+ setTimeout(fn, delay) {
430
+ let id;
431
+ id = setTimeout(() => {
432
+ this._timers.delete(id);
433
+ fn();
434
+ }, delay);
435
+ this._timers.add(id);
436
+ return id;
437
+ }
438
+
439
+ /**
440
+ * Safe setInterval with automatic cleanup on disconnect.
441
+ * @param {Function} fn - Callback
442
+ * @param {number} delay - Interval in ms
443
+ * @returns {number} Interval ID
444
+ */
445
+ setInterval(fn, delay) {
446
+ const id = setInterval(fn, delay);
447
+ this._intervals.add(id);
448
+ return id;
449
+ }
450
+
451
+ /**
452
+ * Helper: Setup keyboard activation (Enter/Space triggers callback).
453
+ * Also sets up tabindex based on disabled state.
454
+ * Consolidates repeated pattern across interactive components.
455
+ *
456
+ * @param {Function} callback - Function to call on activation
457
+ */
458
+ setupActivation(callback) {
459
+ this.updateTabindex();
460
+ this.addEventListener('keydown', (e) => {
461
+ if ((e.key === 'Enter' || e.key === ' ') && !this.has('disabled')) {
462
+ e.preventDefault();
463
+ callback();
464
+ }
465
+ });
466
+ }
467
+
468
+ /**
469
+ * Helper: Update tabindex based on disabled state.
470
+ * Interactive elements should be focusable unless disabled.
471
+ */
472
+ updateTabindex() {
473
+ this.setAttribute('tabindex', this.has('disabled') ? '-1' : '0');
474
+ }
475
+
476
+ /**
477
+ * Helper: Set display style consistently.
478
+ * @param {string} value - CSS display value (flex, block, inline-flex, etc.)
479
+ */
480
+ setDisplay(value) {
481
+ this.style.display = value;
482
+ }
483
+
484
+ /**
485
+ * Helper: Check if component is disabled.
486
+ * @returns {boolean}
487
+ */
488
+ get isDisabled() {
489
+ return this.has('disabled');
490
+ }
491
+ }
492
+
493
+ /**
494
+ * SOTA 2026: Scheduler API-enhanced component registration.
495
+ * Yields to main thread between registrations to prevent long tasks (>50ms).
496
+ * Uses scheduler.yield() on Chrome 129+, falls back to setTimeout(0).
497
+ *
498
+ * @param {string} tagName - Custom element tag name
499
+ * @param {typeof HTMLElement} ComponentClass - Component class to register
500
+ * @param {Object} options - Registration options
501
+ * @param {string} options.priority - 'user-blocking' (default) | 'user-visible' | 'background'
502
+ */
503
+ export function define(tagName, ComponentClass, options = {}) {
504
+ if (customElements.get(tagName)) return;
505
+
506
+ const priority = options.priority || 'user-blocking';
507
+
508
+ // SOTA 2026: Use Scheduler API for prioritized registration
509
+ if (typeof scheduler !== 'undefined' && scheduler.postTask) {
510
+ scheduler.postTask(() => {
511
+ if (!customElements.get(tagName)) {
512
+ customElements.define(tagName, ComponentClass);
513
+ }
514
+ }, { priority });
515
+ } else {
516
+ // Fallback: immediate registration for older browsers
517
+ customElements.define(tagName, ComponentClass);
518
+ }
519
+ }
520
+
521
+ /**
522
+ * SOTA 2026: Batch component registration with yielding.
523
+ * Registers multiple components while yielding to main thread between each.
524
+ * Prevents long tasks and keeps UI responsive during initial load.
525
+ *
526
+ * @param {Array<[string, typeof HTMLElement]>} components - Array of [tagName, Class] pairs
527
+ * @param {Object} options - Registration options
528
+ * @param {number} options.batchSize - Components per batch before yield (default: 3)
529
+ * @returns {Promise<void>} Resolves when all components are registered
530
+ */
531
+ export async function defineAll(components, options = {}) {
532
+ const batchSize = options.batchSize || 3;
533
+ const yieldToMain = getYieldFunction();
534
+
535
+ for (let i = 0; i < components.length; i++) {
536
+ const [tagName, ComponentClass] = components[i];
537
+
538
+ if (!customElements.get(tagName)) {
539
+ customElements.define(tagName, ComponentClass);
540
+ }
541
+
542
+ // Yield to main thread after each batch to prevent long tasks
543
+ if ((i + 1) % batchSize === 0 && i < components.length - 1) {
544
+ await yieldToMain();
545
+ }
546
+ }
547
+ }
548
+
549
+ /**
550
+ * Get the best yield function available.
551
+ * SOTA 2026: scheduler.yield() > setTimeout(0)
552
+ * @returns {Function} Async yield function
553
+ */
554
+ function getYieldFunction() {
555
+ // Chrome 129+: scheduler.yield() is the most efficient
556
+ if (typeof scheduler !== 'undefined' && scheduler.yield) {
557
+ return () => scheduler.yield();
558
+ }
559
+
560
+ // Fallback: setTimeout(0) yields to event loop
561
+ return () => new Promise(resolve => setTimeout(resolve, 0));
562
+ }