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,161 @@
1
+ /**
2
+ * @fileoverview Performance and Memory Tests
3
+ *
4
+ * Uses test-harness.html which has microUI properly loaded.
5
+ */
6
+
7
+ import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
8
+ import { launchBrowser, puppeteer } from './puppeteer-helper.js';
9
+ import { fileURLToPath } from 'url';
10
+ import { dirname, join } from 'path';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+
15
+ describe('Performance & Memory Tests', () => {
16
+ let browser;
17
+ let page;
18
+ let server;
19
+
20
+ beforeAll(async () => {
21
+ const projectRoot = join(__dirname, '../..');
22
+
23
+ server = Bun.serve({
24
+ port: 0,
25
+ async fetch(req) {
26
+ const url = new URL(req.url);
27
+ let filePath = join(projectRoot, url.pathname);
28
+
29
+ if (url.pathname === '/') {
30
+ filePath = join(__dirname, 'test-harness.html');
31
+ }
32
+
33
+ try {
34
+ const file = Bun.file(filePath);
35
+ if (!await file.exists()) {
36
+ return new Response('Not Found', { status: 404 });
37
+ }
38
+
39
+ const content = await file.text();
40
+ const ext = filePath.split('.').pop();
41
+ const mimeTypes = {
42
+ 'html': 'text/html',
43
+ 'js': 'text/javascript',
44
+ 'css': 'text/css'
45
+ };
46
+
47
+ return new Response(content, {
48
+ headers: { 'Content-Type': mimeTypes[ext] || 'text/plain' }
49
+ });
50
+ } catch (e) {
51
+ return new Response('Error', { status: 500 });
52
+ }
53
+ }
54
+ });
55
+
56
+ browser = await puppeteer.launch({
57
+ headless: true,
58
+ executablePath: '/tmp/puppeteer/chrome-headless-shell/mac_arm-144.0.7559.96/chrome-headless-shell-mac-arm64/chrome-headless-shell',
59
+ args: ['--no-sandbox', '--disable-setuid-sandbox'],
60
+ userDataDir: `./.tmp/puppeteer-perf_memory-${Date.now()}-${Math.random().toString(36).slice(2)}`
61
+ });
62
+ page = await browser.newPage();
63
+
64
+ // Navigate to test harness first
65
+ await page.goto(`http://localhost:${server.port}`, { waitUntil: 'networkidle0' });
66
+ await page.waitForFunction(() => window.testsComplete === true, { timeout: 30000 });
67
+ }, 60000);
68
+
69
+ afterAll(async () => {
70
+ if (browser) await browser.close();
71
+ if (server) server.stop();
72
+ });
73
+
74
+ describe('Performance', () => {
75
+ test('component creation: 500 components < 300ms', async () => {
76
+ const result = await page.evaluate(() => {
77
+ const testArea = document.getElementById('test-area');
78
+ testArea.innerHTML = '';
79
+
80
+ const start = performance.now();
81
+ for (let i = 0; i < 500; i++) {
82
+ const btn = document.createElement('mu-button');
83
+ btn.textContent = `B${i}`;
84
+ testArea.appendChild(btn);
85
+ }
86
+ const end = performance.now();
87
+
88
+ testArea.innerHTML = '';
89
+ return { total: end - start };
90
+ });
91
+
92
+ expect(result.total).toBeLessThan(300);
93
+ });
94
+
95
+ test('DOM updates: 500 updates < 50ms', async () => {
96
+ const result = await page.evaluate(() => {
97
+ const testArea = document.getElementById('test-area');
98
+ testArea.innerHTML = '';
99
+
100
+ const buttons = [];
101
+ for (let i = 0; i < 50; i++) {
102
+ const btn = document.createElement('mu-button');
103
+ testArea.appendChild(btn);
104
+ buttons.push(btn);
105
+ }
106
+
107
+ const start = performance.now();
108
+ for (let i = 0; i < 500; i++) {
109
+ buttons[i % 50].setAttribute('variant', i % 2 === 0 ? 'filled' : 'outlined');
110
+ }
111
+ const end = performance.now();
112
+
113
+ testArea.innerHTML = '';
114
+ return { total: end - start };
115
+ });
116
+
117
+ expect(result.total).toBeLessThan(50);
118
+ });
119
+ });
120
+
121
+ describe('Memory Stability', () => {
122
+ test('component lifecycle: 300 create/destroy cycles', async () => {
123
+ const result = await page.evaluate(async () => {
124
+ const testArea = document.getElementById('test-area');
125
+
126
+ for (let i = 0; i < 300; i++) {
127
+ const btn = document.createElement('mu-button');
128
+ btn.textContent = `B${i}`;
129
+ testArea.appendChild(btn);
130
+ }
131
+
132
+ testArea.innerHTML = '';
133
+ await new Promise(r => setTimeout(r, 50));
134
+
135
+ return { passed: true };
136
+ });
137
+
138
+ expect(result.passed).toBe(true);
139
+ });
140
+
141
+ test('stress test: 3 cycles of 500 components', async () => {
142
+ const result = await page.evaluate(async () => {
143
+ const testArea = document.getElementById('test-area');
144
+
145
+ for (let cycle = 0; cycle < 3; cycle++) {
146
+ for (let i = 0; i < 500; i++) {
147
+ const btn = document.createElement('mu-button');
148
+ btn.textContent = `${cycle}-${i}`;
149
+ testArea.appendChild(btn);
150
+ }
151
+ testArea.innerHTML = '';
152
+ }
153
+
154
+ await new Promise(r => setTimeout(r, 20));
155
+ return { passed: true };
156
+ });
157
+
158
+ expect(result.passed).toBe(true);
159
+ });
160
+ });
161
+ });
@@ -0,0 +1,137 @@
1
+ /**
2
+ * @fileoverview Shared Puppeteer helper for E2E tests
3
+ *
4
+ * Uses puppeteer-core with globally installed Chrome:
5
+ * - puppeteer-core: NO automatic Chrome download
6
+ * - Chrome: Installed via `npx puppeteer browsers install chrome-headless-shell`
7
+ * Location: ~/.cache/puppeteer/ (persistent) or /tmp/puppeteer/ (sandbox fallback)
8
+ *
9
+ * This eliminates:
10
+ * - Hardcoded paths scattered across 19+ test files
11
+ * - macOS sandbox EPERM issues (userDataDir in /tmp)
12
+ * - Version drift between test files
13
+ * - Automatic Chrome downloads per-project
14
+ */
15
+
16
+ import puppeteer from 'puppeteer-core';
17
+ import { execSync } from 'child_process';
18
+ import { existsSync, readdirSync } from 'fs';
19
+ import { join } from 'path';
20
+
21
+ /**
22
+ * Find chrome-headless-shell in various cache locations
23
+ * Searches: /tmp/puppeteer, ~/.cache/puppeteer
24
+ * @returns {string|null} Path to Chrome executable
25
+ */
26
+ export function findGlobalChrome() {
27
+ const cachePaths = [
28
+ '/tmp/puppeteer', // macOS sandbox-friendly location
29
+ join(process.env.HOME, '.cache', 'puppeteer') // Standard puppeteer cache
30
+ ];
31
+
32
+ for (const cachePath of cachePaths) {
33
+ if (!existsSync(cachePath)) continue;
34
+
35
+ const dirs = readdirSync(cachePath);
36
+
37
+ // Look for chrome-headless-shell first (preferred), then chrome
38
+ for (const browserType of ['chrome-headless-shell', 'chrome']) {
39
+ for (const dir of dirs) {
40
+ if (dir.startsWith(browserType)) {
41
+ const chromeDir = join(cachePath, dir);
42
+
43
+ // Check if it's a directory with versions
44
+ try {
45
+ const versions = readdirSync(chromeDir).sort().reverse(); // Latest first
46
+
47
+ for (const version of versions) {
48
+ // Check for mac_arm first, then mac x64
49
+ const armPath = join(chromeDir, version, `${browserType}-mac-arm64`, browserType);
50
+ const x64Path = join(chromeDir, version, `${browserType}-mac-x64`, browserType);
51
+
52
+ if (existsSync(armPath)) return armPath;
53
+ if (existsSync(x64Path)) return x64Path;
54
+ }
55
+ } catch (e) {
56
+ // Not a directory with versions, skip
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ return null;
64
+ }
65
+
66
+ /**
67
+ * Generate a unique userDataDir in /tmp to avoid macOS sandbox issues
68
+ * @param {string} testName - Name of the test for identification
69
+ * @returns {string} Path to userDataDir
70
+ */
71
+ export function getTmpUserDataDir(testName = 'e2e') {
72
+ const sanitized = testName.replace(/[^a-z0-9_-]/gi, '_');
73
+ return `/tmp/puppeteer-${sanitized}-${Date.now()}`;
74
+ }
75
+
76
+ /**
77
+ * Launch Puppeteer browser with standardized configuration
78
+ * Uses global Chrome from ~/.cache/puppeteer
79
+ *
80
+ * @param {Object} options - Optional overrides
81
+ * @param {string} options.testName - Test name for userDataDir
82
+ * @param {boolean} options.headless - Default: true
83
+ * @param {string[]} options.args - Additional browser args
84
+ * @returns {Promise<Browser>} Puppeteer browser instance
85
+ */
86
+ export async function launchBrowser(options = {}) {
87
+ const {
88
+ testName = 'test',
89
+ headless = true,
90
+ args = []
91
+ } = options;
92
+
93
+ const executablePath = findGlobalChrome();
94
+
95
+ if (!executablePath) {
96
+ throw new Error(
97
+ '[puppeteer-helper] Chrome not found in ~/.cache/puppeteer.\n' +
98
+ 'Install with: PUPPETEER_CACHE_DIR=~/.cache/puppeteer npx puppeteer browsers install chrome-headless-shell'
99
+ );
100
+ }
101
+
102
+ const browser = await puppeteer.launch({
103
+ headless,
104
+ executablePath,
105
+ args: [
106
+ '--no-sandbox',
107
+ '--disable-setuid-sandbox',
108
+ '--disable-dev-shm-usage',
109
+ ...args
110
+ ],
111
+ userDataDir: getTmpUserDataDir(testName)
112
+ });
113
+
114
+ return browser;
115
+ }
116
+
117
+ /**
118
+ * Launch browser with remote debugging port (for Lighthouse)
119
+ * @param {number} port - Debugging port (default: 9222)
120
+ * @returns {Promise<Browser>} Puppeteer browser instance
121
+ */
122
+ export async function launchBrowserForLighthouse(port = 9222) {
123
+ return launchBrowser({
124
+ testName: `lighthouse-${port}`,
125
+ args: [`--remote-debugging-port=${port}`]
126
+ });
127
+ }
128
+
129
+ export default {
130
+ findGlobalChrome,
131
+ getTmpUserDataDir,
132
+ launchBrowser,
133
+ launchBrowserForLighthouse
134
+ };
135
+
136
+ // Re-export puppeteer-core for tests that need direct access
137
+ export { default as puppeteer } from 'puppeteer-core';
@@ -0,0 +1,226 @@
1
+ /**
2
+ * @fileoverview Puppeteer E2E Tests for microUI features that require real browser
3
+ *
4
+ * Tests: signals, theme (matchMedia), component events (CustomEvent bubbling)
5
+ * These tests cover functionality that cannot run in linkedom environment.
6
+ */
7
+
8
+ import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
9
+ import { launchBrowser, puppeteer } from './puppeteer-helper.js';
10
+ import { fileURLToPath } from 'url';
11
+ import { dirname, join } from 'path';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = dirname(__filename);
15
+
16
+ describe('Puppeteer E2E Tests', () => {
17
+ let browser;
18
+ let page;
19
+ let server;
20
+ let testResults;
21
+
22
+ beforeAll(async () => {
23
+ // Start a simple HTTP server using Bun
24
+ const projectRoot = join(__dirname, '../..');
25
+
26
+ server = Bun.serve({
27
+ port: 0, // Random available port
28
+ async fetch(req) {
29
+ const url = new URL(req.url);
30
+ let filePath = join(projectRoot, url.pathname);
31
+
32
+ // Default to test harness
33
+ if (url.pathname === '/') {
34
+ filePath = join(__dirname, 'test-harness.html');
35
+ }
36
+
37
+ try {
38
+ const file = Bun.file(filePath);
39
+ const exists = await file.exists();
40
+ if (!exists) {
41
+ console.error(`[404] ${url.pathname} -> ${filePath}`);
42
+ return new Response('Not Found', { status: 404 });
43
+ }
44
+
45
+ const content = await file.text();
46
+ const ext = filePath.split('.').pop();
47
+ const mimeTypes = {
48
+ 'html': 'text/html',
49
+ 'js': 'text/javascript',
50
+ 'css': 'text/css',
51
+ 'json': 'application/json'
52
+ };
53
+
54
+ return new Response(content, {
55
+ headers: { 'Content-Type': mimeTypes[ext] || 'text/plain' }
56
+ });
57
+ } catch (e) {
58
+ console.error(`[500] ${url.pathname}: ${e.message}`);
59
+ return new Response('Error: ' + e.message, { status: 500 });
60
+ }
61
+ }
62
+ });
63
+
64
+ const serverUrl = `http://localhost:${server.port}`;
65
+ console.log(`Test server started at ${serverUrl}`);
66
+
67
+ browser = await puppeteer.launch({
68
+ headless: true,
69
+ executablePath: '/tmp/puppeteer/chrome-headless-shell/mac_arm-144.0.7559.96/chrome-headless-shell-mac-arm64/chrome-headless-shell',
70
+ args: ['--no-sandbox', '--disable-setuid-sandbox'],
71
+ userDataDir: `./.tmp/puppeteer-puppeteer-${Date.now()}-${Math.random().toString(36).slice(2)}`
72
+ });
73
+ page = await browser.newPage();
74
+
75
+ // Enable console logging for debugging
76
+ page.on('console', msg => {
77
+ console.log('BROWSER:', msg.text());
78
+ });
79
+ page.on('pageerror', err => {
80
+ console.error('PAGE ERROR:', err.message);
81
+ });
82
+
83
+ // Navigate to test harness
84
+ console.log('Navigating to test harness...');
85
+ await page.goto(serverUrl, { waitUntil: 'domcontentloaded' });
86
+
87
+ // Give some time for module loading
88
+ console.log('Waiting for tests to complete...');
89
+
90
+ try {
91
+ await page.waitForFunction(() => window.testsComplete === true, {
92
+ timeout: 30000
93
+ });
94
+ console.log('Tests completed!');
95
+ } catch (e) {
96
+ // If timeout, try to get partial results
97
+ console.log('Timeout - checking what happened...');
98
+ const pageContent = await page.content();
99
+ console.log('Page has content:', pageContent.length, 'chars');
100
+
101
+ const hasTestResults = await page.evaluate(() => !!window.testResults);
102
+ console.log('Has testResults:', hasTestResults);
103
+
104
+ const testsComplete = await page.evaluate(() => window.testsComplete);
105
+ console.log('testsComplete:', testsComplete);
106
+
107
+ if (!hasTestResults) {
108
+ throw new Error('Page failed to load or execute tests');
109
+ }
110
+ }
111
+
112
+ // Get results
113
+ testResults = await page.evaluate(() => window.testResults);
114
+ console.log('Test results:', JSON.stringify(testResults, null, 2));
115
+ }, 60000);
116
+
117
+ afterAll(async () => {
118
+ if (browser) {
119
+ await browser.close();
120
+ }
121
+ if (server) {
122
+ server.stop();
123
+ }
124
+ });
125
+
126
+ // ========================================
127
+ // SIGNALS TESTS (require Function.name assignment)
128
+ // ========================================
129
+
130
+ describe('signals Module (Browser)', () => {
131
+ test('signal should create reactive value with functional accessor', () => {
132
+ expect(testResults?.signalCreate).toBe(true);
133
+ });
134
+
135
+ test('signal.set should update value', () => {
136
+ expect(testResults?.signalSet).toBe(true);
137
+ });
138
+
139
+ test('signal.update should work with function', () => {
140
+ expect(testResults?.signalUpdate).toBe(true);
141
+ });
142
+
143
+ test('signal.peek should return value without tracking', () => {
144
+ expect(testResults?.signalPeek).toBe(true);
145
+ });
146
+
147
+ test('computed should derive value', () => {
148
+ expect(testResults?.computed).toBe(true);
149
+ });
150
+ });
151
+
152
+ // ========================================
153
+ // THEME TESTS (require matchMedia)
154
+ // ========================================
155
+
156
+ describe('theme Module (Browser)', () => {
157
+ test('Theme object should exist', () => {
158
+ expect(testResults?.themeExists).toBe(true);
159
+ });
160
+
161
+ test('Theme.init should be a function', () => {
162
+ expect(testResults?.themeHasInit).toBe(true);
163
+ });
164
+
165
+ test('Theme.set should be a function', () => {
166
+ expect(testResults?.themeHasSet).toBe(true);
167
+ });
168
+
169
+ test('Theme.get should be a function', () => {
170
+ expect(testResults?.themeHasGet).toBe(true);
171
+ });
172
+
173
+ test('Theme.toggle should be a function', () => {
174
+ expect(testResults?.themeHasToggle).toBe(true);
175
+ });
176
+
177
+ test('Theme.set("dark") should set dark theme', () => {
178
+ expect(testResults?.themeSetDark).toBe(true);
179
+ });
180
+
181
+ test('Theme.set("light") should set light theme', () => {
182
+ expect(testResults?.themeSetLight).toBe(true);
183
+ });
184
+ });
185
+
186
+ // ========================================
187
+ // COMPONENT EVENT TESTS (require CustomEvent)
188
+ // ========================================
189
+
190
+ describe('Component Events (Browser)', () => {
191
+ test('MuElement.emit() should dispatch custom event', () => {
192
+ expect(testResults?.muElementEmit).toBe(true);
193
+ });
194
+
195
+ test('mu-modal.open() should emit mu-open event', () => {
196
+ expect(testResults?.modalOpenEvent).toBe(true);
197
+ });
198
+
199
+ test('mu-modal.close() should emit mu-close event', () => {
200
+ expect(testResults?.modalCloseEvent).toBe(true);
201
+ });
202
+
203
+ test('mu-checkbox.toggle() should toggle checked state', () => {
204
+ expect(testResults?.checkboxToggle).toBe(true);
205
+ });
206
+
207
+ test('mu-switch.toggle() should toggle state', () => {
208
+ expect(testResults?.switchToggle).toBe(true);
209
+ });
210
+
211
+ test('mu-chip.toggle() should toggle selection', () => {
212
+ expect(testResults?.chipToggle).toBe(true);
213
+ });
214
+ });
215
+
216
+ // ========================================
217
+ // STRUCTURAL TESTS (verify all components render with baseClass)
218
+ // ========================================
219
+
220
+ describe('Component Structure (Browser)', () => {
221
+ test('all 31 components should have correct baseClass', () => {
222
+ expect(testResults?.structPass).toBe(31);
223
+ expect(testResults?.structFail).toBe(0);
224
+ });
225
+ });
226
+ });