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,120 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Per-Component Loading Test</title>
8
+ <link rel="stylesheet" href="dist/microui.css">
9
+ <style>
10
+ body {
11
+ font-family: system-ui;
12
+ padding: 40px;
13
+ max-width: 800px;
14
+ margin: 0 auto;
15
+ background: var(--md-sys-color-background, #fffbfe);
16
+ color: var(--md-sys-color-on-background, #1d1b20);
17
+ }
18
+
19
+ h1 {
20
+ margin-bottom: 8px;
21
+ }
22
+
23
+ .subtitle {
24
+ color: #666;
25
+ margin-bottom: 32px;
26
+ }
27
+
28
+ .test-section {
29
+ margin: 24px 0;
30
+ padding: 20px;
31
+ background: var(--md-sys-color-surface-container, #f3edf7);
32
+ border-radius: 12px;
33
+ }
34
+
35
+ .log {
36
+ font-family: monospace;
37
+ font-size: 13px;
38
+ padding: 12px;
39
+ background: #1d1b20;
40
+ color: #c6ffc1;
41
+ border-radius: 8px;
42
+ margin-top: 16px;
43
+ }
44
+ </style>
45
+ </head>
46
+
47
+ <body>
48
+ <h1>🧪 Per-Component Loading Test</h1>
49
+ <p class="subtitle">Testing individual component imports from dist/components/</p>
50
+
51
+ <div class="test-section">
52
+ <h2>Test 1: Button Component</h2>
53
+ <mu-button variant="filled">Loaded Button</mu-button>
54
+ <mu-button variant="tonal">Tonal</mu-button>
55
+ <mu-button variant="outlined">Outlined</mu-button>
56
+ </div>
57
+
58
+ <div class="test-section">
59
+ <h2>Test 2: Card Component</h2>
60
+ <mu-card style="padding: 20px;">
61
+ <h3>Card Title</h3>
62
+ <p>This card was loaded via per-component import.</p>
63
+ </mu-card>
64
+ </div>
65
+
66
+ <div class="test-section">
67
+ <h2>Test 3: Modal Component</h2>
68
+ <mu-button variant="filled" id="open-modal">Open Modal</mu-button>
69
+ <mu-modal id="test-modal">
70
+ <h2>Modal Test</h2>
71
+ <p>Modal loaded via per-component import!</p>
72
+ <mu-button variant="filled" onclick="document.getElementById('test-modal').close()">Close</mu-button>
73
+ </mu-modal>
74
+ </div>
75
+
76
+ <div class="log" id="log">Loading components...</div>
77
+
78
+ <script type="module">
79
+ const log = document.getElementById('log');
80
+ const logs = [];
81
+
82
+ function addLog(msg) {
83
+ logs.push(msg);
84
+ log.innerHTML = logs.join('<br>');
85
+ }
86
+
87
+ const perfStart = performance.now();
88
+ addLog('⏱️ Starting per-component load test...');
89
+
90
+ // Load only the components we need
91
+ const componentsToLoad = [
92
+ 'mu-button',
93
+ 'mu-card',
94
+ 'mu-modal',
95
+ 'mu-stack'
96
+ ];
97
+
98
+ for (const comp of componentsToLoad) {
99
+ const start = performance.now();
100
+ try {
101
+ await import('./dist/components/' + comp + '.js');
102
+ const time = (performance.now() - start).toFixed(0);
103
+ addLog('✅ ' + comp + '.js loaded in ' + time + 'ms');
104
+ } catch (e) {
105
+ addLog('❌ ' + comp + '.js failed: ' + e.message);
106
+ }
107
+ }
108
+
109
+ const totalTime = (performance.now() - perfStart).toFixed(0);
110
+ addLog('');
111
+ addLog('📦 Total: 4 components loaded in ' + totalTime + 'ms');
112
+
113
+ // Setup modal button
114
+ document.getElementById('open-modal').onclick = () => {
115
+ document.getElementById('test-modal').open();
116
+ };
117
+ </script>
118
+ </body>
119
+
120
+ </html>
@@ -0,0 +1,309 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>microUI v0.1.0 - Memory Leak Test</title>
8
+ <link rel="stylesheet" href="../src/styles/tokens.css">
9
+ <link rel="stylesheet" href="../src/styles/components.css">
10
+ <style>
11
+ body {
12
+ font-family: var(--md-sys-typescale-font);
13
+ background: var(--md-sys-color-surface);
14
+ color: var(--md-sys-color-on-surface);
15
+ padding: 24px;
16
+ max-width: 800px;
17
+ margin: 0 auto;
18
+ }
19
+
20
+ .card {
21
+ background: var(--md-sys-color-surface-container);
22
+ border-radius: 12px;
23
+ padding: 20px;
24
+ margin-bottom: 16px;
25
+ }
26
+
27
+ .result {
28
+ font-family: monospace;
29
+ background: var(--md-sys-color-surface-container-highest);
30
+ padding: 12px;
31
+ border-radius: 8px;
32
+ white-space: pre-wrap;
33
+ }
34
+
35
+ button {
36
+ background: var(--md-sys-color-primary);
37
+ color: var(--md-sys-color-on-primary);
38
+ border: none;
39
+ padding: 12px 24px;
40
+ border-radius: 8px;
41
+ cursor: pointer;
42
+ font-size: 16px;
43
+ margin: 4px;
44
+ }
45
+
46
+ .pass {
47
+ color: var(--md-sys-color-primary);
48
+ }
49
+
50
+ .fail {
51
+ color: var(--md-sys-color-error);
52
+ }
53
+
54
+ #container {
55
+ display: none;
56
+ }
57
+ </style>
58
+ </head>
59
+
60
+ <body>
61
+ <h1>🔬 Memory Leak Test Suite</h1>
62
+
63
+ <div class="card">
64
+ <h2>Test 1: Component Lifecycle</h2>
65
+ <p>Creates and destroys 1000 components, checks for proper cleanup.</p>
66
+ <button onclick="testLifecycle()">Run Test</button>
67
+ <div id="lifecycle-result" class="result">Click to run...</div>
68
+ </div>
69
+
70
+ <div class="card">
71
+ <h2>Test 2: Event Listener Cleanup</h2>
72
+ <p>Tests that event listeners are properly removed on disconnect.</p>
73
+ <button onclick="testEventListeners()">Run Test</button>
74
+ <div id="events-result" class="result">Click to run...</div>
75
+ </div>
76
+
77
+ <div class="card">
78
+ <h2>Test 3: Timer/Interval Cleanup</h2>
79
+ <p>Tests that timers and intervals are cleared on disconnect.</p>
80
+ <button onclick="testTimers()">Run Test</button>
81
+ <div id="timers-result" class="result">Click to run...</div>
82
+ </div>
83
+
84
+ <div class="card">
85
+ <h2>Test 4: WeakRef EventBus</h2>
86
+ <p>Tests that WeakRef listeners are garbage collected.</p>
87
+ <button onclick="testWeakRef()">Run Test</button>
88
+ <div id="weakref-result" class="result">Click to run...</div>
89
+ </div>
90
+
91
+ <div class="card">
92
+ <h2>Test 5: Stress Test</h2>
93
+ <p>Creates 10000 components rapidly to detect memory growth.</p>
94
+ <button onclick="testStress()">Run Stress Test</button>
95
+ <div id="stress-result" class="result">Click to run...</div>
96
+ </div>
97
+
98
+ <div id="container"></div>
99
+
100
+ <script type="module">
101
+ import { MuButton, bus } from '../src/index.js';
102
+
103
+ const container = document.getElementById('container');
104
+
105
+ // Test 1: Component Lifecycle
106
+ window.testLifecycle = async () => {
107
+ const result = document.getElementById('lifecycle-result');
108
+ result.textContent = 'Running...';
109
+
110
+ const initialMemory = performance.memory?.usedJSHeapSize;
111
+
112
+ // Create and destroy 1000 components
113
+ for (let i = 0; i < 1000; i++) {
114
+ const btn = document.createElement('mu-button');
115
+ btn.textContent = `Button ${i}`;
116
+ container.appendChild(btn);
117
+ }
118
+
119
+ const afterCreate = performance.memory?.usedJSHeapSize;
120
+
121
+ // Remove all
122
+ container.innerHTML = '';
123
+
124
+ // Force GC if available
125
+ if (window.gc) window.gc();
126
+
127
+ await new Promise(r => setTimeout(r, 500));
128
+
129
+ const afterDestroy = performance.memory?.usedJSHeapSize;
130
+
131
+ if (performance.memory) {
132
+ const createdMB = ((afterCreate - initialMemory) / 1024 / 1024).toFixed(2);
133
+ const retainedMB = ((afterDestroy - initialMemory) / 1024 / 1024).toFixed(2);
134
+ const freedMB = ((afterCreate - afterDestroy) / 1024 / 1024).toFixed(2);
135
+
136
+ const isGood = parseFloat(retainedMB) < parseFloat(createdMB) * 0.2;
137
+
138
+ result.innerHTML = `
139
+ <span class="${isGood ? 'pass' : 'fail'}">${isGood ? '✓ PASS' : '✗ POTENTIAL LEAK'}</span>
140
+
141
+ Memory allocated: ${createdMB} MB
142
+ Memory after cleanup: ${retainedMB} MB
143
+ Memory freed: ${freedMB} MB
144
+
145
+ ${isGood ? 'Components properly cleaned up!' : 'Warning: Memory not fully released'}`;
146
+ } else {
147
+ result.textContent = '⚠️ Memory API not available. Run with --enable-precise-memory-info';
148
+ }
149
+ };
150
+
151
+ // Test 2: Event Listener Cleanup
152
+ window.testEventListeners = () => {
153
+ const result = document.getElementById('events-result');
154
+ let listenerCalled = false;
155
+
156
+ // Create component that adds global listener
157
+ const btn = document.createElement('mu-button');
158
+
159
+ // Manually add listener using component's listen method
160
+ const handler = () => { listenerCalled = true; };
161
+
162
+ container.appendChild(btn);
163
+
164
+ // Use the new listen() method
165
+ btn.listen(window, 'test-event', handler);
166
+
167
+ // Dispatch to confirm it works
168
+ window.dispatchEvent(new Event('test-event'));
169
+ const calledBefore = listenerCalled;
170
+
171
+ // Remove component
172
+ container.removeChild(btn);
173
+
174
+ // Reset and try again
175
+ listenerCalled = false;
176
+ window.dispatchEvent(new Event('test-event'));
177
+ const calledAfter = listenerCalled;
178
+
179
+ if (calledBefore && !calledAfter) {
180
+ result.innerHTML = '<span class="pass">✓ PASS</span>\n\nListener active before disconnect: ✓\nListener cleaned up after disconnect: ✓';
181
+ } else if (!calledBefore) {
182
+ result.innerHTML = '<span class="fail">✗ FAIL</span>\n\nListener was not active before disconnect';
183
+ } else {
184
+ result.innerHTML = '<span class="fail">✗ FAIL - MEMORY LEAK</span>\n\nListener still active after disconnect!\nThis indicates a memory leak.';
185
+ }
186
+ };
187
+
188
+ // Test 3: Timer/Interval Cleanup
189
+ window.testTimers = async () => {
190
+ const result = document.getElementById('timers-result');
191
+ let timerFired = false;
192
+ let intervalCount = 0;
193
+
194
+ // Create component with timers
195
+ const btn = document.createElement('mu-button');
196
+ container.appendChild(btn);
197
+
198
+ // Use component's safe setTimeout/setInterval
199
+ btn.setTimeout(() => { timerFired = true; }, 200);
200
+ btn.setInterval(() => { intervalCount++; }, 100);
201
+
202
+ // Remove immediately
203
+ container.removeChild(btn);
204
+
205
+ // Wait for timers
206
+ await new Promise(r => setTimeout(r, 500));
207
+
208
+ const isGood = !timerFired && intervalCount === 0;
209
+
210
+ result.innerHTML = `
211
+ <span class="${isGood ? 'pass' : 'fail'}">${isGood ? '✓ PASS' : '✗ FAIL'}</span>
212
+
213
+ Timer fired after disconnect: ${timerFired ? 'YES (leak!)' : 'NO ✓'}
214
+ Interval count after disconnect: ${intervalCount} ${intervalCount === 0 ? '✓' : '(should be 0)'}
215
+
216
+ ${isGood ? 'Timers properly cleaned up!' : 'Warning: Timers still running after component removed!'}`;
217
+ };
218
+
219
+ // Test 4: WeakRef EventBus
220
+ window.testWeakRef = async () => {
221
+ const result = document.getElementById('weakref-result');
222
+
223
+ const counts = bus.listenerCount('test:weak');
224
+ const initialCount = counts.total;
225
+
226
+ // Add a weak listener
227
+ let callback = (data) => console.log('weak callback');
228
+ bus.on('test:weak', callback, { weak: true });
229
+
230
+ const afterAdd = bus.listenerCount('test:weak');
231
+
232
+ // Remove reference
233
+ callback = null;
234
+
235
+ // Force GC if available
236
+ if (window.gc) window.gc();
237
+
238
+ // Emit to trigger cleanup
239
+ await new Promise(r => setTimeout(r, 100));
240
+ bus.emit('test:weak', {});
241
+
242
+ const afterEmit = bus.listenerCount('test:weak');
243
+
244
+ result.innerHTML = `
245
+ <span class="pass">✓ WeakRef Support Active</span>
246
+
247
+ Listeners before: ${initialCount}
248
+ After adding weak: ${afterAdd.weak} weak, ${afterAdd.strong} strong
249
+ After emit (cleanup): ${afterEmit.weak} weak, ${afterEmit.strong} strong
250
+
251
+ Note: Actual GC timing is unpredictable.
252
+ Use --expose-gc flag and window.gc() for deterministic testing.`;
253
+ };
254
+
255
+ // Test 5: Stress Test
256
+ window.testStress = async () => {
257
+ const result = document.getElementById('stress-result');
258
+ result.textContent = 'Running stress test (10000 components)...';
259
+
260
+ const before = performance.memory?.usedJSHeapSize || 0;
261
+ const start = performance.now();
262
+
263
+ // Create 10000 components
264
+ for (let i = 0; i < 10000; i++) {
265
+ const btn = document.createElement('mu-button');
266
+ btn.textContent = `B${i}`;
267
+ container.appendChild(btn);
268
+
269
+ // Report progress
270
+ if (i % 1000 === 0) {
271
+ result.textContent = `Creating: ${i}/10000...`;
272
+ await new Promise(r => setTimeout(r, 0));
273
+ }
274
+ }
275
+
276
+ const afterCreate = performance.now();
277
+ const memAfterCreate = performance.memory?.usedJSHeapSize || 0;
278
+
279
+ // Destroy all
280
+ container.innerHTML = '';
281
+
282
+ if (window.gc) window.gc();
283
+ await new Promise(r => setTimeout(r, 500));
284
+
285
+ const afterDestroy = performance.now();
286
+ const memAfterDestroy = performance.memory?.usedJSHeapSize || 0;
287
+
288
+ const createTime = (afterCreate - start).toFixed(0);
289
+ const destroyTime = (afterDestroy - afterCreate).toFixed(0);
290
+ const memUsed = ((memAfterCreate - before) / 1024 / 1024).toFixed(2);
291
+ const memRetained = ((memAfterDestroy - before) / 1024 / 1024).toFixed(2);
292
+
293
+ result.innerHTML = `
294
+ <span class="pass">✓ Stress Test Complete</span>
295
+
296
+ Components: 10,000
297
+ Create time: ${createTime}ms (${(10000 / (createTime / 1000)).toFixed(0)} components/sec)
298
+ Destroy time: ${destroyTime}ms
299
+
300
+ Memory used: ${memUsed} MB
301
+ Memory after cleanup: ${memRetained} MB
302
+ Per-component: ~${(memAfterCreate - before) / 10000} bytes`;
303
+ };
304
+
305
+ console.log('🔬 Memory Leak Test Suite Ready');
306
+ </script>
307
+ </body>
308
+
309
+ </html>
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @fileoverview Shared test setup for linkedom DOM environment
3
+ *
4
+ * This file provides a shared linkedom DOM instance for all tests.
5
+ * It must be imported before any component imports to ensure consistent
6
+ * globalThis state across all test files.
7
+ *
8
+ * Usage in test files:
9
+ * import '../setup-dom.js'; // First import!
10
+ * import { MuButton } from '../../src/components/mu-button.js';
11
+ */
12
+
13
+ import { parseHTML } from 'linkedom';
14
+
15
+ // Create shared DOM instance
16
+ const dom = parseHTML(`<!DOCTYPE html>
17
+ <html lang="en">
18
+ <head>
19
+ <meta charset="UTF-8">
20
+ <title>Test</title>
21
+ </head>
22
+ <body></body>
23
+ </html>`);
24
+
25
+ // Set up globals only once
26
+ if (!globalThis.__testDomInitialized) {
27
+ globalThis.__testDomInitialized = true;
28
+
29
+ globalThis.window = dom.window;
30
+ globalThis.document = dom.document;
31
+ globalThis.customElements = dom.customElements;
32
+ globalThis.HTMLElement = dom.HTMLElement;
33
+ globalThis.Node = dom.Node || globalThis.Node;
34
+ globalThis.Element = dom.Element || globalThis.Element;
35
+ globalThis.DocumentFragment = dom.DocumentFragment || globalThis.DocumentFragment;
36
+
37
+ // Mock requestAnimationFrame
38
+ globalThis.requestAnimationFrame = (cb) => {
39
+ cb(Date.now());
40
+ return 0;
41
+ };
42
+ globalThis.cancelAnimationFrame = () => { };
43
+
44
+ // Mock getComputedStyle
45
+ globalThis.getComputedStyle = () => ({
46
+ position: 'static',
47
+ overflow: 'visible',
48
+ getPropertyValue: () => ''
49
+ });
50
+
51
+ // Mock Web Animations API
52
+ if (!dom.HTMLElement.prototype.animate) {
53
+ dom.HTMLElement.prototype.animate = function (keyframes, options) {
54
+ return {
55
+ finished: Promise.resolve(),
56
+ cancel: () => { },
57
+ play: () => { },
58
+ pause: () => { },
59
+ onfinish: null
60
+ };
61
+ };
62
+ }
63
+
64
+ // Mock IntersectionObserver
65
+ globalThis.IntersectionObserver = class {
66
+ constructor(callback) {
67
+ this.callback = callback;
68
+ }
69
+ observe() { }
70
+ unobserve() { }
71
+ disconnect() { }
72
+ };
73
+
74
+ // Mock ResizeObserver
75
+ globalThis.ResizeObserver = class {
76
+ constructor(callback) {
77
+ this.callback = callback;
78
+ }
79
+ observe() { }
80
+ unobserve() { }
81
+ disconnect() { }
82
+ };
83
+ }
84
+
85
+ // Export for tests that need direct access
86
+ export const testDocument = dom.document;
87
+ export const testBody = dom.document.body;
88
+ export const testCustomElements = dom.customElements;
89
+
90
+ // Helper to reset body between tests
91
+ export function resetBody() {
92
+ dom.document.body.innerHTML = '';
93
+ }