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