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,125 +0,0 @@
1
- /**
2
- * @fileoverview Unit Tests for mu-dropdown Component (Popover API)
3
- *
4
- * Tests only PUBLIC API - internal state is private.
5
- * - open(), close(), toggle(), select()
6
- * - value getter/setter
7
- * - DOM structure
8
- */
9
-
10
- import { describe, test, expect, beforeAll, beforeEach } from 'bun:test';
11
- import { parseHTML } from 'linkedom';
12
-
13
- let document, customElements, body;
14
- let MuDropdown;
15
-
16
- describe('mu-dropdown Unit Tests', () => {
17
-
18
- beforeAll(async () => {
19
- const dom = parseHTML('<!DOCTYPE html><html><body></body></html>');
20
- document = dom.document;
21
- customElements = dom.customElements;
22
- body = document.body;
23
-
24
- globalThis.window = dom.window;
25
- globalThis.document = document;
26
- globalThis.customElements = customElements;
27
- globalThis.HTMLElement = dom.HTMLElement;
28
- globalThis.requestAnimationFrame = (cb) => { cb(Date.now()); return 0; };
29
-
30
- const module = await import('../../src/components/mu-dropdown.js');
31
- MuDropdown = module.MuDropdown;
32
- });
33
-
34
- beforeEach(() => { body.innerHTML = ''; });
35
-
36
- // ============================================================
37
- // REGISTRATION
38
- // ============================================================
39
- test('should be registered', () => {
40
- expect(customElements.get('mu-dropdown')).toBe(MuDropdown);
41
- });
42
-
43
- test('should have correct baseClass', () => {
44
- expect(MuDropdown.baseClass).toBe('mu-dropdown');
45
- });
46
-
47
- test('should observe placeholder, value, disabled', () => {
48
- expect(MuDropdown.observedAttributes).toContain('placeholder');
49
- expect(MuDropdown.observedAttributes).toContain('value');
50
- expect(MuDropdown.observedAttributes).toContain('disabled');
51
- });
52
-
53
- // ============================================================
54
- // PUBLIC METHODS EXIST
55
- // ============================================================
56
- test('should have toggle method', () => {
57
- const el = document.createElement('mu-dropdown');
58
- body.appendChild(el);
59
- expect(typeof el.toggle).toBe('function');
60
- });
61
-
62
- test('should have open method', () => {
63
- const el = document.createElement('mu-dropdown');
64
- body.appendChild(el);
65
- expect(typeof el.open).toBe('function');
66
- });
67
-
68
- test('should have close method', () => {
69
- const el = document.createElement('mu-dropdown');
70
- body.appendChild(el);
71
- expect(typeof el.close).toBe('function');
72
- });
73
-
74
- test('should have select method', () => {
75
- const el = document.createElement('mu-dropdown');
76
- body.appendChild(el);
77
- expect(typeof el.select).toBe('function');
78
- });
79
-
80
- // ============================================================
81
- // VALUE GETTER/SETTER
82
- // ============================================================
83
- test('should have value getter', () => {
84
- const el = document.createElement('mu-dropdown');
85
- body.appendChild(el);
86
- expect(el.value).toBeDefined();
87
- });
88
-
89
- test('should have value setter', () => {
90
- const el = document.createElement('mu-dropdown');
91
- body.appendChild(el);
92
- el.value = 'test';
93
- expect(el.getAttribute('value')).toBe('test');
94
- });
95
-
96
- // ============================================================
97
- // DOM STRUCTURE (idempotent render)
98
- // ============================================================
99
- test('render should be idempotent', async () => {
100
- const el = document.createElement('mu-dropdown');
101
- body.appendChild(el);
102
-
103
- // Wait for render (uses rAF)
104
- await new Promise(r => setTimeout(r, 50));
105
-
106
- // Force re-render attempt
107
- el.render?.();
108
- el.render?.();
109
-
110
- expect(el.querySelectorAll('.mu-dropdown__trigger').length).toBe(1);
111
- });
112
-
113
- test('should create trigger with proper accessibility attributes', async () => {
114
- const el = document.createElement('mu-dropdown');
115
- el.setAttribute('placeholder', 'Choose');
116
- body.appendChild(el);
117
-
118
- await new Promise(r => setTimeout(r, 50));
119
-
120
- const trigger = el.querySelector('.mu-dropdown__trigger');
121
- expect(trigger).not.toBeNull();
122
- expect(trigger.getAttribute('aria-haspopup')).toBe('listbox');
123
- expect(trigger.getAttribute('aria-expanded')).toBe('false');
124
- });
125
- });
@@ -1,138 +0,0 @@
1
- /**
2
- * @fileoverview Unit Tests for mu-form Component
3
- * Target: 70% → 95% coverage
4
- */
5
-
6
- import { describe, test, expect, beforeAll, beforeEach } from 'bun:test';
7
- import { parseHTML } from 'linkedom';
8
-
9
- let document, customElements, body;
10
- let MuForm;
11
-
12
- describe('mu-form Unit Tests', () => {
13
-
14
- beforeAll(async () => {
15
- const dom = parseHTML('<!DOCTYPE html><html><body></body></html>');
16
- document = dom.document;
17
- customElements = dom.customElements;
18
- body = document.body;
19
-
20
- globalThis.window = dom.window;
21
- globalThis.document = document;
22
- globalThis.customElements = customElements;
23
- globalThis.HTMLElement = dom.HTMLElement;
24
- globalThis.requestAnimationFrame = (cb) => { cb(Date.now()); return 0; };
25
- globalThis.setTimeout = (cb) => cb();
26
-
27
- const module = await import('../../src/components/mu-form.js');
28
- MuForm = module.MuForm;
29
- });
30
-
31
- beforeEach(() => { body.innerHTML = ''; });
32
-
33
- // REGISTRATION
34
- test('should be registered', () => {
35
- expect(customElements.get('mu-form')).toBe(MuForm);
36
- });
37
-
38
- test('should have correct baseClass', () => {
39
- expect(MuForm.baseClass).toBe('mu-form');
40
- });
41
-
42
- test('should observe action and method', () => {
43
- expect(MuForm.observedAttributes).toContain('action');
44
- expect(MuForm.observedAttributes).toContain('method');
45
- });
46
-
47
- // RENDER
48
- test('should set role form', () => {
49
- const el = document.createElement('mu-form');
50
- body.appendChild(el);
51
- expect(el.getAttribute('role')).toBe('form');
52
- });
53
-
54
- // GET FORM DATA
55
- test('should have getFormData method', () => {
56
- const el = document.createElement('mu-form');
57
- body.appendChild(el);
58
- expect(typeof el.getFormData).toBe('function');
59
- });
60
-
61
- test('getFormData should return empty object for empty form', () => {
62
- const el = document.createElement('mu-form');
63
- body.appendChild(el);
64
- expect(el.getFormData()).toEqual({});
65
- });
66
-
67
- test('getFormData should collect native input values', () => {
68
- const el = document.createElement('mu-form');
69
- el.innerHTML = '<input name="email" value="test@example.com">';
70
- body.appendChild(el);
71
- expect(el.getFormData().email).toBe('test@example.com');
72
- });
73
-
74
- test.skip('getFormData should handle checkbox (E2E only) inputs', () => {
75
- const el = document.createElement('mu-form');
76
- el.innerHTML = '<input type="checkbox" name="agree" checked>';
77
- body.appendChild(el);
78
- expect(el.getFormData().agree).toBe(true);
79
- });
80
-
81
- // VALIDATE
82
- test('should have validate method', () => {
83
- const el = document.createElement('mu-form');
84
- body.appendChild(el);
85
- expect(typeof el.validate).toBe('function');
86
- });
87
-
88
- test('validate should return true for empty form', () => {
89
- const el = document.createElement('mu-form');
90
- body.appendChild(el);
91
- expect(el.validate()).toBe(true);
92
- });
93
-
94
- test('validate should return false for invalid required field', () => {
95
- const el = document.createElement('mu-form');
96
- el.innerHTML = '<input name="email" required value="">';
97
- body.appendChild(el);
98
- expect(el.validate()).toBe(false);
99
- });
100
-
101
- test('validate should return true for valid required field', () => {
102
- const el = document.createElement('mu-form');
103
- el.innerHTML = '<input name="email" required value="test@example.com">';
104
- body.appendChild(el);
105
- expect(el.validate()).toBe(true);
106
- });
107
-
108
- test('validate should add is-invalid class', () => {
109
- const el = document.createElement('mu-form');
110
- el.innerHTML = '<input name="email" required value="">';
111
- body.appendChild(el);
112
- el.validate();
113
- expect(el.querySelector('input').classList.contains('is-invalid')).toBe(true);
114
- });
115
-
116
- // RESET
117
- test('should have reset method', () => {
118
- const el = document.createElement('mu-form');
119
- body.appendChild(el);
120
- expect(typeof el.reset).toBe('function');
121
- });
122
-
123
- test.skip('reset should clear native inputs (E2E only)', () => {
124
- const el = document.createElement('mu-form');
125
- el.innerHTML = '<input name="email" value="test@example.com">';
126
- body.appendChild(el);
127
- el.reset();
128
- expect(el.querySelector('input').value).toBe('');
129
- });
130
-
131
- test.skip('reset should remove is-invalid (E2E only) class', () => {
132
- const el = document.createElement('mu-form');
133
- el.innerHTML = '<input name="email" required value="" class="is-invalid">';
134
- body.appendChild(el);
135
- el.reset();
136
- expect(el.querySelector('input').classList.contains('is-invalid')).toBe(false);
137
- });
138
- });
@@ -1,135 +0,0 @@
1
- /**
2
- * @fileoverview Unit Tests for mu-grid Layout Component
3
- * Target: 25% → 90% coverage
4
- */
5
-
6
- import { describe, test, expect, beforeAll, beforeEach } from 'bun:test';
7
- import { parseHTML } from 'linkedom';
8
-
9
- let document, customElements, body;
10
- let MuGrid;
11
-
12
- describe('mu-grid Unit Tests', () => {
13
-
14
- beforeAll(async () => {
15
- const dom = parseHTML('<!DOCTYPE html><html><body></body></html>');
16
- document = dom.document;
17
- customElements = dom.customElements;
18
- body = document.body;
19
-
20
- globalThis.window = dom.window;
21
- globalThis.document = document;
22
- globalThis.customElements = customElements;
23
- globalThis.HTMLElement = dom.HTMLElement;
24
- globalThis.requestAnimationFrame = (cb) => { cb(Date.now()); return 0; };
25
-
26
- const module = await import('../../src/components/mu-grid.js');
27
- MuGrid = module.MuGrid;
28
- });
29
-
30
- beforeEach(() => { body.innerHTML = ''; });
31
-
32
- // REGISTRATION
33
- test('should be registered', () => {
34
- expect(customElements.get('mu-grid')).toBe(MuGrid);
35
- });
36
-
37
- test('should have correct baseClass', () => {
38
- expect(MuGrid.baseClass).toBe('mu-grid');
39
- });
40
-
41
- test('should observe grid attributes', () => {
42
- expect(MuGrid.observedAttributes).toContain('cols');
43
- expect(MuGrid.observedAttributes).toContain('rows');
44
- expect(MuGrid.observedAttributes).toContain('gap');
45
- expect(MuGrid.observedAttributes).toContain('align');
46
- });
47
-
48
- // DISPLAY
49
- test('should have display grid', () => {
50
- const el = document.createElement('mu-grid');
51
- body.appendChild(el);
52
- expect(el.style.display).toBe('grid');
53
- });
54
-
55
- // COLUMNS
56
- test('should default to 1 column', () => {
57
- const el = document.createElement('mu-grid');
58
- body.appendChild(el);
59
- expect(el.style.gridTemplateColumns).toBe('repeat(1, 1fr)');
60
- });
61
-
62
- test('should support numeric columns', () => {
63
- const el = document.createElement('mu-grid');
64
- el.setAttribute('cols', '3');
65
- body.appendChild(el);
66
- expect(el.style.gridTemplateColumns).toBe('repeat(3, 1fr)');
67
- });
68
-
69
- test('should support fr columns', () => {
70
- const el = document.createElement('mu-grid');
71
- el.setAttribute('cols', '1fr 2fr');
72
- body.appendChild(el);
73
- expect(el.style.gridTemplateColumns).toBe('1fr 2fr');
74
- });
75
-
76
- test('should support px columns', () => {
77
- const el = document.createElement('mu-grid');
78
- el.setAttribute('cols', '200px 1fr');
79
- body.appendChild(el);
80
- expect(el.style.gridTemplateColumns).toBe('200px 1fr');
81
- });
82
-
83
- // ROWS
84
- test('should support numeric rows', () => {
85
- const el = document.createElement('mu-grid');
86
- el.setAttribute('rows', '2');
87
- body.appendChild(el);
88
- expect(el.style.gridTemplateRows).toBe('repeat(2, 1fr)');
89
- });
90
-
91
- test('should support fr rows', () => {
92
- const el = document.createElement('mu-grid');
93
- el.setAttribute('rows', '1fr 2fr');
94
- body.appendChild(el);
95
- expect(el.style.gridTemplateRows).toBe('1fr 2fr');
96
- });
97
-
98
- // GAP
99
- test('should support gap values', () => {
100
- const el = document.createElement('mu-grid');
101
- el.setAttribute('gap', 'lg');
102
- body.appendChild(el);
103
- expect(el.style.gap).toBe('24px');
104
- });
105
-
106
- test('should support custom gap', () => {
107
- const el = document.createElement('mu-grid');
108
- el.setAttribute('gap', '20px');
109
- body.appendChild(el);
110
- expect(el.style.gap).toBe('20px');
111
- });
112
-
113
- // ALIGN
114
- test('should default to stretch align', () => {
115
- const el = document.createElement('mu-grid');
116
- body.appendChild(el);
117
- expect(el.style.alignItems).toBe('stretch');
118
- });
119
-
120
- test('should support center align', () => {
121
- const el = document.createElement('mu-grid');
122
- el.setAttribute('align', 'center');
123
- body.appendChild(el);
124
- expect(el.style.alignItems).toBe('center');
125
- });
126
-
127
- // UPDATE
128
- test('update should re-apply styles', () => {
129
- const el = document.createElement('mu-grid');
130
- body.appendChild(el);
131
- el.setAttribute('cols', '4');
132
- el.update('cols', '4', '1');
133
- expect(el.style.gridTemplateColumns).toBe('repeat(4, 1fr)');
134
- });
135
- });
@@ -1,110 +0,0 @@
1
- /**
2
- * @fileoverview Unit Tests for mu-icon Component
3
- * Target: 78% → 90% coverage
4
- */
5
-
6
- import { describe, test, expect, beforeAll, beforeEach } from 'bun:test';
7
- import { parseHTML } from 'linkedom';
8
-
9
- let document, customElements, body;
10
- let MuIcon;
11
-
12
- describe('mu-icon Unit Tests', () => {
13
-
14
- beforeAll(async () => {
15
- const dom = parseHTML('<!DOCTYPE html><html><body></body></html>');
16
- document = dom.document;
17
- customElements = dom.customElements;
18
- body = document.body;
19
-
20
- globalThis.window = dom.window;
21
- globalThis.document = document;
22
- globalThis.customElements = customElements;
23
- globalThis.HTMLElement = dom.HTMLElement;
24
- globalThis.requestAnimationFrame = (cb) => { cb(Date.now()); return 0; };
25
-
26
- const module = await import('../../src/components/mu-icon.js');
27
- MuIcon = module.MuIcon;
28
- });
29
-
30
- beforeEach(() => { body.innerHTML = ''; });
31
-
32
- // REGISTRATION
33
- test('should be registered', () => {
34
- expect(customElements.get('mu-icon')).toBe(MuIcon);
35
- });
36
-
37
- test('should have correct baseClass', () => {
38
- expect(MuIcon.baseClass).toBe('mu-icon');
39
- });
40
-
41
- test('should observe name, size, svg, filled, font', () => {
42
- expect(MuIcon.observedAttributes).toContain('name');
43
- expect(MuIcon.observedAttributes).toContain('size');
44
- expect(MuIcon.observedAttributes).toContain('filled');
45
- expect(MuIcon.observedAttributes).toContain('font');
46
- });
47
-
48
- // RENDER
49
- test.skip('should set role img (E2E only)', () => {
50
- const el = document.createElement('mu-icon');
51
- body.appendChild(el);
52
- el.render(); // linkedom doesn't auto-call connectedCallback
53
- expect(el.getAttribute('role')).toBe('img');
54
- });
55
-
56
- test.skip('should set aria-hidden (E2E only) by default', () => {
57
- const el = document.createElement('mu-icon');
58
- body.appendChild(el);
59
- el.render(); // linkedom doesn't auto-call connectedCallback
60
- expect(el.getAttribute('aria-hidden')).toBe('true');
61
- });
62
-
63
- test.skip('render should be idempotent (E2E only)', () => {
64
- const el = document.createElement('mu-icon');
65
- el.setAttribute('name', 'home');
66
- body.appendChild(el);
67
- el.render();
68
- expect(el.textContent.trim()).toBe('home');
69
- });
70
-
71
- // NAME
72
- test.skip('should render icon name as text (E2E only)', () => {
73
- const el = document.createElement('mu-icon');
74
- el.setAttribute('name', 'settings');
75
- body.appendChild(el);
76
- el.render(); // linkedom doesn't auto-call connectedCallback
77
- expect(el.textContent).toContain('settings');
78
- });
79
-
80
- // SIZE
81
- test('should support small size', () => {
82
- const el = document.createElement('mu-icon');
83
- el.setAttribute('size', 'sm');
84
- body.appendChild(el);
85
- expect(el.getAttribute('size')).toBe('sm');
86
- });
87
-
88
- test('should support large size', () => {
89
- const el = document.createElement('mu-icon');
90
- el.setAttribute('size', 'lg');
91
- body.appendChild(el);
92
- expect(el.getAttribute('size')).toBe('lg');
93
- });
94
-
95
- // FILLED
96
- test('should support filled variant', () => {
97
- const el = document.createElement('mu-icon');
98
- el.setAttribute('filled', '');
99
- body.appendChild(el);
100
- expect(el.has('filled')).toBe(true);
101
- });
102
-
103
- // WEIGHT
104
- test('should support weight attribute', () => {
105
- const el = document.createElement('mu-icon');
106
- el.setAttribute('weight', '700');
107
- body.appendChild(el);
108
- expect(el.getAttribute('weight')).toBe('700');
109
- });
110
- });
@@ -1,131 +0,0 @@
1
- /**
2
- * @fileoverview Unit Tests for mu-input Component
3
- * Target: 63% → 90% coverage
4
- */
5
-
6
- import { describe, test, expect, beforeAll, beforeEach } from 'bun:test';
7
- import { parseHTML } from 'linkedom';
8
-
9
- let document, customElements, body;
10
- let MuInput;
11
-
12
- describe('mu-input Unit Tests', () => {
13
-
14
- beforeAll(async () => {
15
- const dom = parseHTML('<!DOCTYPE html><html><body></body></html>');
16
- document = dom.document;
17
- customElements = dom.customElements;
18
- body = document.body;
19
-
20
- globalThis.window = dom.window;
21
- globalThis.document = document;
22
- globalThis.customElements = customElements;
23
- globalThis.HTMLElement = dom.HTMLElement;
24
- globalThis.requestAnimationFrame = (cb) => { cb(Date.now()); return 0; };
25
-
26
- const module = await import('../../src/components/mu-input.js');
27
- MuInput = module.MuInput;
28
- });
29
-
30
- beforeEach(() => { body.innerHTML = ''; });
31
-
32
- // REGISTRATION
33
- test('should be registered', () => {
34
- expect(customElements.get('mu-input')).toBe(MuInput);
35
- });
36
-
37
- test('should have correct baseClass', () => {
38
- expect(MuInput.baseClass).toBe('mu-input');
39
- });
40
-
41
- test('should observe type, placeholder, value, disabled, variant, size, label', () => {
42
- expect(MuInput.observedAttributes).toContain('type');
43
- expect(MuInput.observedAttributes).toContain('placeholder');
44
- expect(MuInput.observedAttributes).toContain('value');
45
- expect(MuInput.observedAttributes).toContain('disabled');
46
- expect(MuInput.observedAttributes).toContain('variant');
47
- expect(MuInput.observedAttributes).toContain('size');
48
- expect(MuInput.observedAttributes).toContain('label');
49
- });
50
-
51
- // RENDER
52
- test('should render input field', () => {
53
- const el = document.createElement('mu-input');
54
- el.setAttribute('placeholder', 'Test');
55
- body.appendChild(el);
56
- expect(el.querySelector('.mu-input__field')).not.toBeNull();
57
- });
58
-
59
- test('should render label when provided', () => {
60
- const el = document.createElement('mu-input');
61
- el.setAttribute('label', 'Email');
62
- body.appendChild(el);
63
- expect(el.querySelector('.mu-input__label')).not.toBeNull();
64
- });
65
-
66
- test('render should be idempotent', () => {
67
- const el = document.createElement('mu-input');
68
- el.setAttribute('placeholder', 'Test');
69
- body.appendChild(el);
70
- el.render();
71
- expect(el.querySelectorAll('.mu-input__field').length).toBe(1);
72
- });
73
-
74
- // VALUE
75
- test('should have value getter', () => {
76
- const el = document.createElement('mu-input');
77
- el.setAttribute('placeholder', 'Test');
78
- body.appendChild(el);
79
- expect(el.value).toBeDefined();
80
- });
81
-
82
- test('should have value setter', () => {
83
- const el = document.createElement('mu-input');
84
- el.setAttribute('placeholder', 'Test');
85
- body.appendChild(el);
86
- el.value = 'test value';
87
- expect(el.querySelector('input').value).toBe('test value');
88
- });
89
-
90
- // FOCUS
91
- test('should have focus method', () => {
92
- const el = document.createElement('mu-input');
93
- el.setAttribute('placeholder', 'Test');
94
- body.appendChild(el);
95
- expect(typeof el.focus).toBe('function');
96
- });
97
-
98
- // DISABLED
99
- test('should support disabled attribute', () => {
100
- const el = document.createElement('mu-input');
101
- el.setAttribute('placeholder', 'Test');
102
- el.setAttribute('disabled', '');
103
- body.appendChild(el);
104
- expect(el.querySelector('input').disabled).toBe(true);
105
- });
106
-
107
- // TYPE
108
- test('should default to text type', () => {
109
- const el = document.createElement('mu-input');
110
- el.setAttribute('placeholder', 'Test');
111
- body.appendChild(el);
112
- expect(el.querySelector('input').type).toBe('text');
113
- });
114
-
115
- test('should support password type', () => {
116
- const el = document.createElement('mu-input');
117
- el.setAttribute('type', 'password');
118
- el.setAttribute('placeholder', 'Password');
119
- body.appendChild(el);
120
- expect(el.querySelector('input').type).toBe('password');
121
- });
122
-
123
- // UPDATE
124
- test('update should handle value change', () => {
125
- const el = document.createElement('mu-input');
126
- el.setAttribute('placeholder', 'Test');
127
- body.appendChild(el);
128
- el.setAttribute('value', 'new value');
129
- expect(el.querySelector('input').value).toBe('new value');
130
- });
131
- });