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,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
- });