microui-wc 0.1.0 → 0.1.2

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 (343) hide show
  1. package/AGENTS.md +71 -71
  2. package/CHANGELOG.md +1 -1
  3. package/README.md +14 -9
  4. package/dist/AGENTS.md +116 -116
  5. package/dist/README.md +21 -16
  6. package/dist/components.css +1 -1
  7. package/dist/microui.css +1 -1
  8. package/dist/microui.esm.js.map +1 -1
  9. package/dist/microui.min.js.map +1 -1
  10. package/dist/styles/components/switch.css +1 -1
  11. package/docs/getting-started.md +3 -3
  12. package/package.json +38 -10
  13. package/src/components/mu-schema-form.js +1 -1
  14. package/src/styles/components/switch.css +7 -8
  15. package/src/styles/components.css +6 -6
  16. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
  17. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -33
  18. package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
  19. package/.github/workflows/ci.yml +0 -42
  20. package/.github/workflows/deploy-pages.yml +0 -112
  21. package/CODE_OF_CONDUCT.md +0 -59
  22. package/CONTRIBUTING.md +0 -156
  23. package/SECURITY.md +0 -58
  24. package/app/.generated/routes/alerts.js +0 -8
  25. package/app/.generated/routes/avatars.js +0 -8
  26. package/app/.generated/routes/badges.js +0 -8
  27. package/app/.generated/routes/buttons.js +0 -10
  28. package/app/.generated/routes/cards.js +0 -10
  29. package/app/.generated/routes/checkboxes.js +0 -9
  30. package/app/.generated/routes/chips.js +0 -8
  31. package/app/.generated/routes/dropdowns.js +0 -9
  32. package/app/.generated/routes/home.js +0 -7
  33. package/app/.generated/routes/icons.js +0 -9
  34. package/app/.generated/routes/inputs.js +0 -10
  35. package/app/.generated/routes/installation.js +0 -7
  36. package/app/.generated/routes/layout.js +0 -9
  37. package/app/.generated/routes/modals.js +0 -9
  38. package/app/.generated/routes/navbar.js +0 -7
  39. package/app/.generated/routes/progress.js +0 -9
  40. package/app/.generated/routes/radios.js +0 -9
  41. package/app/.generated/routes/switches.js +0 -9
  42. package/app/.generated/routes/tabs.js +0 -8
  43. package/app/.generated/routes/toasts.js +0 -9
  44. package/app/index.html +0 -67
  45. package/app/pages/alerts.html +0 -23
  46. package/app/pages/avatars.html +0 -22
  47. package/app/pages/badges.html +0 -22
  48. package/app/pages/buttons.html +0 -71
  49. package/app/pages/cards.html +0 -54
  50. package/app/pages/checkboxes.html +0 -39
  51. package/app/pages/chips.html +0 -23
  52. package/app/pages/dropdowns.html +0 -41
  53. package/app/pages/home.html +0 -59
  54. package/app/pages/icons.html +0 -29
  55. package/app/pages/inputs.html +0 -66
  56. package/app/pages/installation.html +0 -34
  57. package/app/pages/layout.html +0 -30
  58. package/app/pages/modals.html +0 -21
  59. package/app/pages/navbar.html +0 -22
  60. package/app/pages/progress.html +0 -35
  61. package/app/pages/radios.html +0 -40
  62. package/app/pages/switches.html +0 -39
  63. package/app/pages/tabs.html +0 -30
  64. package/app/pages/toasts.html +0 -22
  65. package/app-dist/index.html +0 -67
  66. package/app-dist/pages/alerts.html +0 -23
  67. package/app-dist/pages/avatars.html +0 -22
  68. package/app-dist/pages/badges.html +0 -22
  69. package/app-dist/pages/buttons.html +0 -71
  70. package/app-dist/pages/cards.html +0 -54
  71. package/app-dist/pages/checkboxes.html +0 -39
  72. package/app-dist/pages/chips.html +0 -23
  73. package/app-dist/pages/dropdowns.html +0 -41
  74. package/app-dist/pages/home.html +0 -59
  75. package/app-dist/pages/icons.html +0 -29
  76. package/app-dist/pages/inputs.html +0 -66
  77. package/app-dist/pages/installation.html +0 -34
  78. package/app-dist/pages/layout.html +0 -30
  79. package/app-dist/pages/modals.html +0 -21
  80. package/app-dist/pages/navbar.html +0 -22
  81. package/app-dist/pages/progress.html +0 -35
  82. package/app-dist/pages/radios.html +0 -40
  83. package/app-dist/pages/switches.html +0 -39
  84. package/app-dist/pages/tabs.html +0 -30
  85. package/app-dist/pages/toasts.html +0 -22
  86. package/app-dist/pages.json +0 -217
  87. package/app-dist/routes/alerts.js +0 -5
  88. package/app-dist/routes/avatars.js +0 -1
  89. package/app-dist/routes/badges.js +0 -1
  90. package/app-dist/routes/buttons.js +0 -1
  91. package/app-dist/routes/cards.js +0 -1
  92. package/app-dist/routes/checkboxes.js +0 -9
  93. package/app-dist/routes/chips.js +0 -4
  94. package/app-dist/routes/chunk-019e5e2f.js +0 -5
  95. package/app-dist/routes/chunk-0m4j19yd.js +0 -2
  96. package/app-dist/routes/chunk-0tmmp5q0.js +0 -1
  97. package/app-dist/routes/chunk-10xn709r.js +0 -1
  98. package/app-dist/routes/chunk-15m2qcda.js +0 -2
  99. package/app-dist/routes/chunk-1bh8g23n.js +0 -1
  100. package/app-dist/routes/chunk-1vg0v937.js +0 -1
  101. package/app-dist/routes/chunk-1zvcgy3j.js +0 -1
  102. package/app-dist/routes/chunk-2afb0861.js +0 -1
  103. package/app-dist/routes/chunk-2c6ttpzt.js +0 -5
  104. package/app-dist/routes/chunk-3dy30fhs.js +0 -1
  105. package/app-dist/routes/chunk-426dnces.js +0 -13
  106. package/app-dist/routes/chunk-44kgxery.js +0 -1
  107. package/app-dist/routes/chunk-47fdnejd.js +0 -33
  108. package/app-dist/routes/chunk-49a6t2vq.js +0 -1
  109. package/app-dist/routes/chunk-4fe1rm5b.js +0 -1
  110. package/app-dist/routes/chunk-4ggmvkta.js +0 -33
  111. package/app-dist/routes/chunk-4vkz81q7.js +0 -33
  112. package/app-dist/routes/chunk-4w4tmj8f.js +0 -31
  113. package/app-dist/routes/chunk-532s62kr.js +0 -31
  114. package/app-dist/routes/chunk-5hm3bssy.js +0 -33
  115. package/app-dist/routes/chunk-5vrh24hc.js +0 -1
  116. package/app-dist/routes/chunk-61pcg25a.js +0 -1
  117. package/app-dist/routes/chunk-6nfhygvf.js +0 -1
  118. package/app-dist/routes/chunk-700e7je6.js +0 -33
  119. package/app-dist/routes/chunk-7fsn17kg.js +0 -1
  120. package/app-dist/routes/chunk-7k789b32.js +0 -1
  121. package/app-dist/routes/chunk-7r46q0ys.js +0 -36
  122. package/app-dist/routes/chunk-86fmc1fr.js +0 -5
  123. package/app-dist/routes/chunk-8qth37vw.js +0 -1
  124. package/app-dist/routes/chunk-924wv8n0.js +0 -1
  125. package/app-dist/routes/chunk-9mbhgxk9.js +0 -1
  126. package/app-dist/routes/chunk-a216hyd9.js +0 -1
  127. package/app-dist/routes/chunk-akzxykh9.js +0 -33
  128. package/app-dist/routes/chunk-b3dcvy8c.js +0 -1
  129. package/app-dist/routes/chunk-b74zahz5.js +0 -31
  130. package/app-dist/routes/chunk-bftj53p2.js +0 -5
  131. package/app-dist/routes/chunk-c01hnz3e.js +0 -1
  132. package/app-dist/routes/chunk-d8pvv5km.js +0 -1
  133. package/app-dist/routes/chunk-dev0aezr.js +0 -2
  134. package/app-dist/routes/chunk-dh6vnv0e.js +0 -1
  135. package/app-dist/routes/chunk-dn2cbpva.js +0 -36
  136. package/app-dist/routes/chunk-dvn0my90.js +0 -1
  137. package/app-dist/routes/chunk-dvq8mnve.js +0 -36
  138. package/app-dist/routes/chunk-e8c2gc4d.js +0 -5
  139. package/app-dist/routes/chunk-ejf9ak2x.js +0 -1
  140. package/app-dist/routes/chunk-f083m55s.js +0 -1
  141. package/app-dist/routes/chunk-fnrj28s1.js +0 -31
  142. package/app-dist/routes/chunk-fvg3yjdp.js +0 -31
  143. package/app-dist/routes/chunk-g7k381n1.js +0 -1
  144. package/app-dist/routes/chunk-h01kq2ae.js +0 -13
  145. package/app-dist/routes/chunk-h4dk761v.js +0 -5
  146. package/app-dist/routes/chunk-hmx91z2x.js +0 -5
  147. package/app-dist/routes/chunk-hxbg4m42.js +0 -36
  148. package/app-dist/routes/chunk-jbjnfp2b.js +0 -2
  149. package/app-dist/routes/chunk-jxtz5vv6.js +0 -36
  150. package/app-dist/routes/chunk-jxzcs0ey.js +0 -36
  151. package/app-dist/routes/chunk-kt7wwhcx.js +0 -1
  152. package/app-dist/routes/chunk-kzptszyc.js +0 -33
  153. package/app-dist/routes/chunk-mhgca4w4.js +0 -2
  154. package/app-dist/routes/chunk-mhswxa20.js +0 -1
  155. package/app-dist/routes/chunk-n8zfeex6.js +0 -1
  156. package/app-dist/routes/chunk-pee47b2r.js +0 -1
  157. package/app-dist/routes/chunk-pesmw829.js +0 -1
  158. package/app-dist/routes/chunk-pgc4c6f3.js +0 -36
  159. package/app-dist/routes/chunk-q8egegm1.js +0 -1
  160. package/app-dist/routes/chunk-q9mn2qyq.js +0 -36
  161. package/app-dist/routes/chunk-qh0rtaf3.js +0 -5
  162. package/app-dist/routes/chunk-qqhmk6ye.js +0 -2
  163. package/app-dist/routes/chunk-qrxygmf7.js +0 -33
  164. package/app-dist/routes/chunk-r46yzksx.js +0 -36
  165. package/app-dist/routes/chunk-rgpbw2w0.js +0 -5
  166. package/app-dist/routes/chunk-rnpzv3d8.js +0 -2
  167. package/app-dist/routes/chunk-s5v8cv05.js +0 -2
  168. package/app-dist/routes/chunk-sbwn5bpc.js +0 -1
  169. package/app-dist/routes/chunk-sqbg8jbt.js +0 -33
  170. package/app-dist/routes/chunk-sv8dqnf7.js +0 -1
  171. package/app-dist/routes/chunk-t67sw3za.js +0 -1
  172. package/app-dist/routes/chunk-tjdpqwdf.js +0 -31
  173. package/app-dist/routes/chunk-tq2mfghg.js +0 -1
  174. package/app-dist/routes/chunk-ttn10vt6.js +0 -1
  175. package/app-dist/routes/chunk-v2hzpjxr.js +0 -1
  176. package/app-dist/routes/chunk-wfjjkw9y.js +0 -1
  177. package/app-dist/routes/chunk-wt8cxzmf.js +0 -31
  178. package/app-dist/routes/chunk-x45d372k.js +0 -5
  179. package/app-dist/routes/chunk-y3wsazkt.js +0 -1
  180. package/app-dist/routes/chunk-y7pmgc7t.js +0 -33
  181. package/app-dist/routes/chunk-zefdt2q3.js +0 -31
  182. package/app-dist/routes/dropdowns.js +0 -6
  183. package/app-dist/routes/home.js +0 -1
  184. package/app-dist/routes/icons.js +0 -1
  185. package/app-dist/routes/inputs.js +0 -12
  186. package/app-dist/routes/installation.js +0 -1
  187. package/app-dist/routes/layout.js +0 -1
  188. package/app-dist/routes/modals.js +0 -7
  189. package/app-dist/routes/navbar.js +0 -1
  190. package/app-dist/routes/progress.js +0 -1
  191. package/app-dist/routes/radios.js +0 -6
  192. package/app-dist/routes/switches.js +0 -6
  193. package/app-dist/routes/tabs.js +0 -1
  194. package/app-dist/routes/toasts.js +0 -16
  195. package/assets/fonts/material-symbols-mini.woff2 +0 -0
  196. package/assets/fonts/material-symbols.woff2 +0 -0
  197. package/assets/fonts/roboto-400.woff2 +0 -0
  198. package/assets/fonts/roboto-500.woff2 +0 -0
  199. package/assets/fonts/roboto-700.woff2 +0 -0
  200. package/assets/logo-banner-400.jpg +0 -0
  201. package/assets/logo-banner-400.webp +0 -0
  202. package/assets/logo-banner-800.webp +0 -0
  203. package/assets/logo-banner.jpg +0 -0
  204. package/assets/logo-icon-64.jpg +0 -0
  205. package/assets/logo-icon-64.webp +0 -0
  206. package/assets/logo-icon.jpg +0 -0
  207. package/assets/logo-square.jpg +0 -0
  208. package/bun.lock +0 -312
  209. package/bunfig.toml +0 -4
  210. package/custom-elements.json +0 -1916
  211. package/demo/api/sample-data.json +0 -38
  212. package/demo/content/alerts.html +0 -115
  213. package/demo/content/avatars.html +0 -70
  214. package/demo/content/badges.html +0 -65
  215. package/demo/content/buttons.html +0 -188
  216. package/demo/content/callouts.html +0 -91
  217. package/demo/content/cards.html +0 -121
  218. package/demo/content/checkboxes.html +0 -178
  219. package/demo/content/chips.html +0 -67
  220. package/demo/content/codeblocks.html +0 -101
  221. package/demo/content/confirms.html +0 -115
  222. package/demo/content/datatables.html +0 -149
  223. package/demo/content/dividers.html +0 -119
  224. package/demo/content/dropdowns.html +0 -89
  225. package/demo/content/enterprise.html +0 -252
  226. package/demo/content/home.html +0 -149
  227. package/demo/content/icons.html +0 -89
  228. package/demo/content/inputs.html +0 -135
  229. package/demo/content/installation.html +0 -16
  230. package/demo/content/layout.html +0 -136
  231. package/demo/content/modals.html +0 -141
  232. package/demo/content/navbar.html +0 -70
  233. package/demo/content/progress.html +0 -119
  234. package/demo/content/radios.html +0 -88
  235. package/demo/content/skeletons.html +0 -109
  236. package/demo/content/spinners.html +0 -96
  237. package/demo/content/switches.html +0 -84
  238. package/demo/content/tables.html +0 -124
  239. package/demo/content/tabs.html +0 -85
  240. package/demo/content/toasts.html +0 -116
  241. package/demo/content/tooltips.html +0 -107
  242. package/demo/content/virtual-lists.html +0 -233
  243. package/demo/favicon.ico +0 -0
  244. package/demo/favicon.png +0 -0
  245. package/demo/full.html +0 -52
  246. package/demo/iife.html +0 -46
  247. package/demo/manifest.json +0 -34
  248. package/demo/pages/datatable-demo.html +0 -237
  249. package/demo/pages/prompt-ui-demo.html +0 -218
  250. package/demo/pages/responsive-demo.html +0 -122
  251. package/demo/pages/schema-form-demo.html +0 -270
  252. package/demo/robots.txt +0 -6
  253. package/demo/shell.html +0 -712
  254. package/demo/sw.js +0 -387
  255. package/lighthouse-audit.mjs +0 -113
  256. package/scripts/analyze-components.js +0 -105
  257. package/scripts/build-app.js +0 -193
  258. package/scripts/build-framework.js +0 -444
  259. package/scripts/build-utils.js +0 -101
  260. package/scripts/test-isolated.js +0 -151
  261. package/server.js +0 -256
  262. package/tests/agents/agent-integration.test.js +0 -76
  263. package/tests/benchmark.html +0 -296
  264. package/tests/build/scan-components.test.js +0 -173
  265. package/tests/components/all-components.test.js +0 -245
  266. package/tests/components/all-missing-components.test.js +0 -574
  267. package/tests/components/mu-alert.test.js +0 -113
  268. package/tests/components/mu-avatar.test.js +0 -148
  269. package/tests/components/mu-badge.test.js +0 -92
  270. package/tests/components/mu-button.test.js +0 -112
  271. package/tests/components/mu-card.test.js +0 -89
  272. package/tests/components/mu-checkbox.test.js +0 -158
  273. package/tests/components/mu-chip.test.js +0 -118
  274. package/tests/components/mu-container.test.js +0 -120
  275. package/tests/components/mu-divider.test.js +0 -98
  276. package/tests/components/mu-drawer-item.test.js +0 -199
  277. package/tests/components/mu-drawer.test.js +0 -96
  278. package/tests/components/mu-dropdown.test.js +0 -125
  279. package/tests/components/mu-form.test.js +0 -138
  280. package/tests/components/mu-grid.test.js +0 -135
  281. package/tests/components/mu-icon.test.js +0 -110
  282. package/tests/components/mu-input.test.js +0 -131
  283. package/tests/components/mu-lazy.test.js +0 -103
  284. package/tests/components/mu-modal.test.js +0 -275
  285. package/tests/components/mu-navbar.test.js +0 -101
  286. package/tests/components/mu-progress.test.js +0 -115
  287. package/tests/components/mu-radio.test.js +0 -114
  288. package/tests/components/mu-repeat.test.js +0 -106
  289. package/tests/components/mu-sidebar.test.js +0 -126
  290. package/tests/components/mu-skeleton.test.js +0 -162
  291. package/tests/components/mu-stack.test.js +0 -143
  292. package/tests/components/mu-switch.test.js +0 -292
  293. package/tests/components/mu-table.test.js +0 -124
  294. package/tests/components/mu-tabs.test.js +0 -104
  295. package/tests/components/mu-textarea.test.js +0 -115
  296. package/tests/components/mu-toast.test.js +0 -321
  297. package/tests/components/mu-tooltip.test.js +0 -133
  298. package/tests/components/mu-virtual-list.test.js +0 -109
  299. package/tests/core/MuElement.test.js +0 -120
  300. package/tests/core/agent-api.test.js +0 -125
  301. package/tests/core/all-core-modules.test.js +0 -442
  302. package/tests/core/bus.test.js +0 -364
  303. package/tests/core/component-schema.test.js +0 -160
  304. package/tests/core/feature-registry.test.js +0 -198
  305. package/tests/core/form-state.test.js +0 -167
  306. package/tests/core/http.test.js +0 -119
  307. package/tests/core/keyboard.test.js +0 -319
  308. package/tests/core/layers.test.js +0 -129
  309. package/tests/core/namespaced-stores.test.js +0 -114
  310. package/tests/core/render.test.js +0 -121
  311. package/tests/core/ripple.test.js +0 -131
  312. package/tests/core/router.test.js +0 -89
  313. package/tests/core/scheduler.test.js +0 -121
  314. package/tests/core/signals.test.js +0 -128
  315. package/tests/core/store.test.js +0 -171
  316. package/tests/core/transitions.test.js +0 -82
  317. package/tests/e2e/accessibility-harness.html +0 -58
  318. package/tests/e2e/accessibility.test.js +0 -401
  319. package/tests/e2e/agent-features.test.js +0 -372
  320. package/tests/e2e/card-spacing.test.js +0 -287
  321. package/tests/e2e/components.test.js +0 -439
  322. package/tests/e2e/demo-routes.test.js +0 -478
  323. package/tests/e2e/layout-css-fallback.test.js +0 -334
  324. package/tests/e2e/mu-alert.e2e.test.js +0 -111
  325. package/tests/e2e/mu-checkbox.test.js +0 -489
  326. package/tests/e2e/mu-chip.test.js +0 -347
  327. package/tests/e2e/mu-form.test.js +0 -499
  328. package/tests/e2e/mu-icon.test.js +0 -114
  329. package/tests/e2e/mu-radio.test.js +0 -113
  330. package/tests/e2e/mu-skeleton.test.js +0 -140
  331. package/tests/e2e/mu-switch.test.js +0 -415
  332. package/tests/e2e/mu-tabs.test.js +0 -494
  333. package/tests/e2e/mu-textarea.test.js +0 -242
  334. package/tests/e2e/mu-virtual-list.test.js +0 -427
  335. package/tests/e2e/perf-memory.test.js +0 -161
  336. package/tests/e2e/puppeteer-helper.js +0 -137
  337. package/tests/e2e/puppeteer.test.js +0 -226
  338. package/tests/e2e/pwa.test.js +0 -261
  339. package/tests/e2e/test-harness.html +0 -319
  340. package/tests/manual/test-components.html +0 -120
  341. package/tests/memory-test.html +0 -309
  342. package/tests/setup-dom.js +0 -93
  343. package/tests/visual-test.html +0 -301
@@ -1,120 +0,0 @@
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>
@@ -1,309 +0,0 @@
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>
@@ -1,93 +0,0 @@
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
- }