microui-wc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (609) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +33 -0
  3. package/.github/PULL_REQUEST_TEMPLATE.md +28 -0
  4. package/.github/workflows/ci.yml +42 -0
  5. package/.github/workflows/deploy-pages.yml +112 -0
  6. package/AGENTS.md +2366 -0
  7. package/CHANGELOG.md +47 -0
  8. package/CODE_OF_CONDUCT.md +59 -0
  9. package/CONTRIBUTING.md +156 -0
  10. package/LICENSE +190 -0
  11. package/README.md +254 -0
  12. package/SECURITY.md +58 -0
  13. package/app/.generated/routes/alerts.js +8 -0
  14. package/app/.generated/routes/avatars.js +8 -0
  15. package/app/.generated/routes/badges.js +8 -0
  16. package/app/.generated/routes/buttons.js +10 -0
  17. package/app/.generated/routes/cards.js +10 -0
  18. package/app/.generated/routes/checkboxes.js +9 -0
  19. package/app/.generated/routes/chips.js +8 -0
  20. package/app/.generated/routes/dropdowns.js +9 -0
  21. package/app/.generated/routes/home.js +7 -0
  22. package/app/.generated/routes/icons.js +9 -0
  23. package/app/.generated/routes/inputs.js +10 -0
  24. package/app/.generated/routes/installation.js +7 -0
  25. package/app/.generated/routes/layout.js +9 -0
  26. package/app/.generated/routes/modals.js +9 -0
  27. package/app/.generated/routes/navbar.js +7 -0
  28. package/app/.generated/routes/progress.js +9 -0
  29. package/app/.generated/routes/radios.js +9 -0
  30. package/app/.generated/routes/switches.js +9 -0
  31. package/app/.generated/routes/tabs.js +8 -0
  32. package/app/.generated/routes/toasts.js +9 -0
  33. package/app/index.html +67 -0
  34. package/app/pages/alerts.html +23 -0
  35. package/app/pages/avatars.html +22 -0
  36. package/app/pages/badges.html +22 -0
  37. package/app/pages/buttons.html +71 -0
  38. package/app/pages/cards.html +54 -0
  39. package/app/pages/checkboxes.html +39 -0
  40. package/app/pages/chips.html +23 -0
  41. package/app/pages/dropdowns.html +41 -0
  42. package/app/pages/home.html +59 -0
  43. package/app/pages/icons.html +29 -0
  44. package/app/pages/inputs.html +66 -0
  45. package/app/pages/installation.html +34 -0
  46. package/app/pages/layout.html +30 -0
  47. package/app/pages/modals.html +21 -0
  48. package/app/pages/navbar.html +22 -0
  49. package/app/pages/progress.html +35 -0
  50. package/app/pages/radios.html +40 -0
  51. package/app/pages/switches.html +39 -0
  52. package/app/pages/tabs.html +30 -0
  53. package/app/pages/toasts.html +22 -0
  54. package/app-dist/index.html +67 -0
  55. package/app-dist/pages/alerts.html +23 -0
  56. package/app-dist/pages/avatars.html +22 -0
  57. package/app-dist/pages/badges.html +22 -0
  58. package/app-dist/pages/buttons.html +71 -0
  59. package/app-dist/pages/cards.html +54 -0
  60. package/app-dist/pages/checkboxes.html +39 -0
  61. package/app-dist/pages/chips.html +23 -0
  62. package/app-dist/pages/dropdowns.html +41 -0
  63. package/app-dist/pages/home.html +59 -0
  64. package/app-dist/pages/icons.html +29 -0
  65. package/app-dist/pages/inputs.html +66 -0
  66. package/app-dist/pages/installation.html +34 -0
  67. package/app-dist/pages/layout.html +30 -0
  68. package/app-dist/pages/modals.html +21 -0
  69. package/app-dist/pages/navbar.html +22 -0
  70. package/app-dist/pages/progress.html +35 -0
  71. package/app-dist/pages/radios.html +40 -0
  72. package/app-dist/pages/switches.html +39 -0
  73. package/app-dist/pages/tabs.html +30 -0
  74. package/app-dist/pages/toasts.html +22 -0
  75. package/app-dist/pages.json +217 -0
  76. package/app-dist/routes/alerts.js +5 -0
  77. package/app-dist/routes/avatars.js +1 -0
  78. package/app-dist/routes/badges.js +1 -0
  79. package/app-dist/routes/buttons.js +1 -0
  80. package/app-dist/routes/cards.js +1 -0
  81. package/app-dist/routes/checkboxes.js +9 -0
  82. package/app-dist/routes/chips.js +4 -0
  83. package/app-dist/routes/chunk-019e5e2f.js +5 -0
  84. package/app-dist/routes/chunk-0m4j19yd.js +2 -0
  85. package/app-dist/routes/chunk-0tmmp5q0.js +1 -0
  86. package/app-dist/routes/chunk-10xn709r.js +1 -0
  87. package/app-dist/routes/chunk-15m2qcda.js +2 -0
  88. package/app-dist/routes/chunk-1bh8g23n.js +1 -0
  89. package/app-dist/routes/chunk-1vg0v937.js +1 -0
  90. package/app-dist/routes/chunk-1zvcgy3j.js +1 -0
  91. package/app-dist/routes/chunk-2afb0861.js +1 -0
  92. package/app-dist/routes/chunk-2c6ttpzt.js +5 -0
  93. package/app-dist/routes/chunk-3dy30fhs.js +1 -0
  94. package/app-dist/routes/chunk-426dnces.js +13 -0
  95. package/app-dist/routes/chunk-44kgxery.js +1 -0
  96. package/app-dist/routes/chunk-47fdnejd.js +33 -0
  97. package/app-dist/routes/chunk-49a6t2vq.js +1 -0
  98. package/app-dist/routes/chunk-4fe1rm5b.js +1 -0
  99. package/app-dist/routes/chunk-4ggmvkta.js +33 -0
  100. package/app-dist/routes/chunk-4vkz81q7.js +33 -0
  101. package/app-dist/routes/chunk-4w4tmj8f.js +31 -0
  102. package/app-dist/routes/chunk-532s62kr.js +31 -0
  103. package/app-dist/routes/chunk-5hm3bssy.js +33 -0
  104. package/app-dist/routes/chunk-5vrh24hc.js +1 -0
  105. package/app-dist/routes/chunk-61pcg25a.js +1 -0
  106. package/app-dist/routes/chunk-6nfhygvf.js +1 -0
  107. package/app-dist/routes/chunk-700e7je6.js +33 -0
  108. package/app-dist/routes/chunk-7fsn17kg.js +1 -0
  109. package/app-dist/routes/chunk-7k789b32.js +1 -0
  110. package/app-dist/routes/chunk-7r46q0ys.js +36 -0
  111. package/app-dist/routes/chunk-86fmc1fr.js +5 -0
  112. package/app-dist/routes/chunk-8qth37vw.js +1 -0
  113. package/app-dist/routes/chunk-924wv8n0.js +1 -0
  114. package/app-dist/routes/chunk-9mbhgxk9.js +1 -0
  115. package/app-dist/routes/chunk-a216hyd9.js +1 -0
  116. package/app-dist/routes/chunk-akzxykh9.js +33 -0
  117. package/app-dist/routes/chunk-b3dcvy8c.js +1 -0
  118. package/app-dist/routes/chunk-b74zahz5.js +31 -0
  119. package/app-dist/routes/chunk-bftj53p2.js +5 -0
  120. package/app-dist/routes/chunk-c01hnz3e.js +1 -0
  121. package/app-dist/routes/chunk-d8pvv5km.js +1 -0
  122. package/app-dist/routes/chunk-dev0aezr.js +2 -0
  123. package/app-dist/routes/chunk-dh6vnv0e.js +1 -0
  124. package/app-dist/routes/chunk-dn2cbpva.js +36 -0
  125. package/app-dist/routes/chunk-dvn0my90.js +1 -0
  126. package/app-dist/routes/chunk-dvq8mnve.js +36 -0
  127. package/app-dist/routes/chunk-e8c2gc4d.js +5 -0
  128. package/app-dist/routes/chunk-ejf9ak2x.js +1 -0
  129. package/app-dist/routes/chunk-f083m55s.js +1 -0
  130. package/app-dist/routes/chunk-fnrj28s1.js +31 -0
  131. package/app-dist/routes/chunk-fvg3yjdp.js +31 -0
  132. package/app-dist/routes/chunk-g7k381n1.js +1 -0
  133. package/app-dist/routes/chunk-h01kq2ae.js +13 -0
  134. package/app-dist/routes/chunk-h4dk761v.js +5 -0
  135. package/app-dist/routes/chunk-hmx91z2x.js +5 -0
  136. package/app-dist/routes/chunk-hxbg4m42.js +36 -0
  137. package/app-dist/routes/chunk-jbjnfp2b.js +2 -0
  138. package/app-dist/routes/chunk-jxtz5vv6.js +36 -0
  139. package/app-dist/routes/chunk-jxzcs0ey.js +36 -0
  140. package/app-dist/routes/chunk-kt7wwhcx.js +1 -0
  141. package/app-dist/routes/chunk-kzptszyc.js +33 -0
  142. package/app-dist/routes/chunk-mhgca4w4.js +2 -0
  143. package/app-dist/routes/chunk-mhswxa20.js +1 -0
  144. package/app-dist/routes/chunk-n8zfeex6.js +1 -0
  145. package/app-dist/routes/chunk-pee47b2r.js +1 -0
  146. package/app-dist/routes/chunk-pesmw829.js +1 -0
  147. package/app-dist/routes/chunk-pgc4c6f3.js +36 -0
  148. package/app-dist/routes/chunk-q8egegm1.js +1 -0
  149. package/app-dist/routes/chunk-q9mn2qyq.js +36 -0
  150. package/app-dist/routes/chunk-qh0rtaf3.js +5 -0
  151. package/app-dist/routes/chunk-qqhmk6ye.js +2 -0
  152. package/app-dist/routes/chunk-qrxygmf7.js +33 -0
  153. package/app-dist/routes/chunk-r46yzksx.js +36 -0
  154. package/app-dist/routes/chunk-rgpbw2w0.js +5 -0
  155. package/app-dist/routes/chunk-rnpzv3d8.js +2 -0
  156. package/app-dist/routes/chunk-s5v8cv05.js +2 -0
  157. package/app-dist/routes/chunk-sbwn5bpc.js +1 -0
  158. package/app-dist/routes/chunk-sqbg8jbt.js +33 -0
  159. package/app-dist/routes/chunk-sv8dqnf7.js +1 -0
  160. package/app-dist/routes/chunk-t67sw3za.js +1 -0
  161. package/app-dist/routes/chunk-tjdpqwdf.js +31 -0
  162. package/app-dist/routes/chunk-tq2mfghg.js +1 -0
  163. package/app-dist/routes/chunk-ttn10vt6.js +1 -0
  164. package/app-dist/routes/chunk-v2hzpjxr.js +1 -0
  165. package/app-dist/routes/chunk-wfjjkw9y.js +1 -0
  166. package/app-dist/routes/chunk-wt8cxzmf.js +31 -0
  167. package/app-dist/routes/chunk-x45d372k.js +5 -0
  168. package/app-dist/routes/chunk-y3wsazkt.js +1 -0
  169. package/app-dist/routes/chunk-y7pmgc7t.js +33 -0
  170. package/app-dist/routes/chunk-zefdt2q3.js +31 -0
  171. package/app-dist/routes/dropdowns.js +6 -0
  172. package/app-dist/routes/home.js +1 -0
  173. package/app-dist/routes/icons.js +1 -0
  174. package/app-dist/routes/inputs.js +12 -0
  175. package/app-dist/routes/installation.js +1 -0
  176. package/app-dist/routes/layout.js +1 -0
  177. package/app-dist/routes/modals.js +7 -0
  178. package/app-dist/routes/navbar.js +1 -0
  179. package/app-dist/routes/progress.js +1 -0
  180. package/app-dist/routes/radios.js +6 -0
  181. package/app-dist/routes/switches.js +6 -0
  182. package/app-dist/routes/tabs.js +1 -0
  183. package/app-dist/routes/toasts.js +16 -0
  184. package/assets/fonts/material-symbols-mini.woff2 +0 -0
  185. package/assets/fonts/material-symbols.woff2 +0 -0
  186. package/assets/fonts/roboto-400.woff2 +0 -0
  187. package/assets/fonts/roboto-500.woff2 +0 -0
  188. package/assets/fonts/roboto-700.woff2 +0 -0
  189. package/assets/logo-banner-400.jpg +0 -0
  190. package/assets/logo-banner-400.webp +0 -0
  191. package/assets/logo-banner-800.webp +0 -0
  192. package/assets/logo-banner.jpg +0 -0
  193. package/assets/logo-icon-64.jpg +0 -0
  194. package/assets/logo-icon-64.webp +0 -0
  195. package/assets/logo-icon.jpg +0 -0
  196. package/assets/logo-square.jpg +0 -0
  197. package/bun.lock +312 -0
  198. package/bunfig.toml +4 -0
  199. package/custom-elements.json +1916 -0
  200. package/demo/api/sample-data.json +38 -0
  201. package/demo/content/alerts.html +115 -0
  202. package/demo/content/avatars.html +70 -0
  203. package/demo/content/badges.html +65 -0
  204. package/demo/content/buttons.html +188 -0
  205. package/demo/content/callouts.html +91 -0
  206. package/demo/content/cards.html +121 -0
  207. package/demo/content/checkboxes.html +178 -0
  208. package/demo/content/chips.html +67 -0
  209. package/demo/content/codeblocks.html +101 -0
  210. package/demo/content/confirms.html +115 -0
  211. package/demo/content/datatables.html +149 -0
  212. package/demo/content/dividers.html +119 -0
  213. package/demo/content/dropdowns.html +89 -0
  214. package/demo/content/enterprise.html +252 -0
  215. package/demo/content/home.html +149 -0
  216. package/demo/content/icons.html +89 -0
  217. package/demo/content/inputs.html +135 -0
  218. package/demo/content/installation.html +16 -0
  219. package/demo/content/layout.html +136 -0
  220. package/demo/content/modals.html +141 -0
  221. package/demo/content/navbar.html +70 -0
  222. package/demo/content/progress.html +119 -0
  223. package/demo/content/radios.html +88 -0
  224. package/demo/content/skeletons.html +109 -0
  225. package/demo/content/spinners.html +96 -0
  226. package/demo/content/switches.html +84 -0
  227. package/demo/content/tables.html +124 -0
  228. package/demo/content/tabs.html +85 -0
  229. package/demo/content/toasts.html +116 -0
  230. package/demo/content/tooltips.html +107 -0
  231. package/demo/content/virtual-lists.html +233 -0
  232. package/demo/favicon.ico +0 -0
  233. package/demo/favicon.png +0 -0
  234. package/demo/full.html +52 -0
  235. package/demo/iife.html +46 -0
  236. package/demo/manifest.json +34 -0
  237. package/demo/pages/datatable-demo.html +237 -0
  238. package/demo/pages/prompt-ui-demo.html +218 -0
  239. package/demo/pages/responsive-demo.html +122 -0
  240. package/demo/pages/schema-form-demo.html +270 -0
  241. package/demo/robots.txt +6 -0
  242. package/demo/shell.html +712 -0
  243. package/demo/sw.js +387 -0
  244. package/dist/AGENTS.md +2366 -0
  245. package/dist/README.md +254 -0
  246. package/dist/chunks/advanced.js +174 -0
  247. package/dist/chunks/chunk-1nhr1wrq.js +14 -0
  248. package/dist/chunks/chunk-hssyjbr0.js +2 -0
  249. package/dist/chunks/chunk-k8etzx0z.js +2 -0
  250. package/dist/chunks/chunk-rr1et8fg.js +2 -0
  251. package/dist/chunks/chunk-sjcx4fd5.js +6 -0
  252. package/dist/chunks/chunk-v1c777xh.js +5 -0
  253. package/dist/chunks/chunk-w5k5vwjd.js +13 -0
  254. package/dist/chunks/core.js +10 -0
  255. package/dist/chunks/display.js +17 -0
  256. package/dist/chunks/feedback.js +15 -0
  257. package/dist/chunks/forms.js +48 -0
  258. package/dist/chunks/layout.js +9 -0
  259. package/dist/components/chunk-4tezav8r.js +2 -0
  260. package/dist/components/chunk-fqyb2pms.js +2 -0
  261. package/dist/components/chunk-h7cdbhxw.js +13 -0
  262. package/dist/components/chunk-mzd8jwrs.js +2 -0
  263. package/dist/components/chunk-qwmxyn8e.js +2 -0
  264. package/dist/components/chunk-redtk47a.js +14 -0
  265. package/dist/components/mu-alert.js +5 -0
  266. package/dist/components/mu-api-table.js +33 -0
  267. package/dist/components/mu-avatar.js +1 -0
  268. package/dist/components/mu-badge.js +1 -0
  269. package/dist/components/mu-bottom-nav.js +1 -0
  270. package/dist/components/mu-button.js +1 -0
  271. package/dist/components/mu-callout.js +1 -0
  272. package/dist/components/mu-card.js +1 -0
  273. package/dist/components/mu-checkbox.js +9 -0
  274. package/dist/components/mu-chip.js +4 -0
  275. package/dist/components/mu-code.js +48 -0
  276. package/dist/components/mu-confirm.js +10 -0
  277. package/dist/components/mu-container.js +1 -0
  278. package/dist/components/mu-datatable.js +96 -0
  279. package/dist/components/mu-divider.js +1 -0
  280. package/dist/components/mu-doc-page.js +26 -0
  281. package/dist/components/mu-drawer-item.js +9 -0
  282. package/dist/components/mu-drawer.js +1 -0
  283. package/dist/components/mu-dropdown.js +6 -0
  284. package/dist/components/mu-error-boundary.js +10 -0
  285. package/dist/components/mu-example.js +38 -0
  286. package/dist/components/mu-fetch.js +1 -0
  287. package/dist/components/mu-form.js +1 -0
  288. package/dist/components/mu-grid.js +1 -0
  289. package/dist/components/mu-icon.js +5 -0
  290. package/dist/components/mu-input.js +12 -0
  291. package/dist/components/mu-layout.js +1 -0
  292. package/dist/components/mu-lazy.js +1 -0
  293. package/dist/components/mu-modal.js +7 -0
  294. package/dist/components/mu-navbar.js +1 -0
  295. package/dist/components/mu-page.js +1 -0
  296. package/dist/components/mu-progress.js +1 -0
  297. package/dist/components/mu-prompt-ui.js +20 -0
  298. package/dist/components/mu-radio.js +6 -0
  299. package/dist/components/mu-repeat.js +1 -0
  300. package/dist/components/mu-router.js +6 -0
  301. package/dist/components/mu-schema-form.js +76 -0
  302. package/dist/components/mu-sidebar.js +1 -0
  303. package/dist/components/mu-skeleton.js +13 -0
  304. package/dist/components/mu-spinner.js +1 -0
  305. package/dist/components/mu-stack.js +1 -0
  306. package/dist/components/mu-switch.js +6 -0
  307. package/dist/components/mu-table.js +1 -0
  308. package/dist/components/mu-tabs.js +1 -0
  309. package/dist/components/mu-textarea.js +11 -0
  310. package/dist/components/mu-theme-toggle.js +5 -0
  311. package/dist/components/mu-toast.js +4 -0
  312. package/dist/components/mu-tooltip.js +10 -0
  313. package/dist/components/mu-virtual-list.js +33 -0
  314. package/dist/components.css +1 -0
  315. package/dist/microui.css +1 -0
  316. package/dist/microui.d.ts +234 -0
  317. package/dist/microui.esm.js +549 -0
  318. package/dist/microui.esm.js.map +79 -0
  319. package/dist/microui.min.js +549 -0
  320. package/dist/microui.min.js.map +79 -0
  321. package/dist/routes/alerts.js +1 -0
  322. package/dist/routes/avatars.js +1 -0
  323. package/dist/routes/badges.js +1 -0
  324. package/dist/routes/buttons.js +1 -0
  325. package/dist/routes/callouts.js +1 -0
  326. package/dist/routes/cards.js +1 -0
  327. package/dist/routes/checkboxes.js +9 -0
  328. package/dist/routes/chips.js +4 -0
  329. package/dist/routes/chunk-19wgcncm.js +2 -0
  330. package/dist/routes/chunk-1khyr3v1.js +33 -0
  331. package/dist/routes/chunk-4rhxe97g.js +1 -0
  332. package/dist/routes/chunk-5qah04bh.js +2 -0
  333. package/dist/routes/chunk-7gfxy70n.js +5 -0
  334. package/dist/routes/chunk-e86zbeta.js +1 -0
  335. package/dist/routes/chunk-fagt36h6.js +2 -0
  336. package/dist/routes/chunk-fed7zr7m.js +1 -0
  337. package/dist/routes/chunk-hwj7pfwp.js +1 -0
  338. package/dist/routes/chunk-mhvcs2f8.js +5 -0
  339. package/dist/routes/chunk-nv3bddmj.js +13 -0
  340. package/dist/routes/chunk-q3f2aeqe.js +7 -0
  341. package/dist/routes/chunk-qxxa8trk.js +1 -0
  342. package/dist/routes/chunk-rw15y9zh.js +1 -0
  343. package/dist/routes/chunk-sfb7x11v.js +5 -0
  344. package/dist/routes/chunk-swyhghrm.js +48 -0
  345. package/dist/routes/chunk-sxddjs2d.js +2 -0
  346. package/dist/routes/chunk-vby0zg5w.js +17 -0
  347. package/dist/routes/chunk-w6zqjqqs.js +9 -0
  348. package/dist/routes/chunk-z960rexd.js +38 -0
  349. package/dist/routes/codeblocks.js +1 -0
  350. package/dist/routes/confirms.js +10 -0
  351. package/dist/routes/datatables.js +96 -0
  352. package/dist/routes/dividers.js +1 -0
  353. package/dist/routes/dropdowns.js +6 -0
  354. package/dist/routes/enterprise.js +15 -0
  355. package/dist/routes/home.js +1 -0
  356. package/dist/routes/icons.js +1 -0
  357. package/dist/routes/inputs.js +22 -0
  358. package/dist/routes/installation.js +1 -0
  359. package/dist/routes/layout.js +1 -0
  360. package/dist/routes/modals.js +1 -0
  361. package/dist/routes/navbar.js +1 -0
  362. package/dist/routes/page-components.json +316 -0
  363. package/dist/routes/progress.js +1 -0
  364. package/dist/routes/radios.js +6 -0
  365. package/dist/routes/route-deps.json +156 -0
  366. package/dist/routes/shell-critical.js +1 -0
  367. package/dist/routes/shell-deferred.js +1 -0
  368. package/dist/routes/shell.js +20 -0
  369. package/dist/routes/skeletons.js +13 -0
  370. package/dist/routes/spinners.js +1 -0
  371. package/dist/routes/src/chunks/core.js +36 -0
  372. package/dist/routes/switches.js +6 -0
  373. package/dist/routes/tables.js +1 -0
  374. package/dist/routes/tabs.js +1 -0
  375. package/dist/routes/toasts.js +1 -0
  376. package/dist/routes/tooltips.js +10 -0
  377. package/dist/routes/virtual-lists.js +33 -0
  378. package/dist/styles/common.css +1 -0
  379. package/dist/styles/components/animations.css +1 -0
  380. package/dist/styles/components/avatar.css +1 -0
  381. package/dist/styles/components/badge.css +1 -0
  382. package/dist/styles/components/bottom-nav.css +1 -0
  383. package/dist/styles/components/button.css +1 -0
  384. package/dist/styles/components/card.css +1 -0
  385. package/dist/styles/components/checkbox.css +1 -0
  386. package/dist/styles/components/chip.css +1 -0
  387. package/dist/styles/components/datatable.css +1 -0
  388. package/dist/styles/components/divider.css +1 -0
  389. package/dist/styles/components/drawer-item.css +1 -0
  390. package/dist/styles/components/drawer.css +1 -0
  391. package/dist/styles/components/grid.css +1 -0
  392. package/dist/styles/components/icon.css +1 -0
  393. package/dist/styles/components/input.css +1 -0
  394. package/dist/styles/components/layout.css +1 -0
  395. package/dist/styles/components/navbar.css +1 -0
  396. package/dist/styles/components/overlays.css +1 -0
  397. package/dist/styles/components/progress.css +1 -0
  398. package/dist/styles/components/prompt-ui.css +1 -0
  399. package/dist/styles/components/radio.css +1 -0
  400. package/dist/styles/components/schema-form.css +1 -0
  401. package/dist/styles/components/switch.css +1 -0
  402. package/dist/styles/components/tabs.css +1 -0
  403. package/dist/styles/components/tooltip.css +1 -0
  404. package/dist/styles/components/virtual-list.css +1 -0
  405. package/dist/tokens.css +1 -0
  406. package/docs/api-reference.md +175 -0
  407. package/docs/component-schema.md +231 -0
  408. package/docs/components.md +269 -0
  409. package/docs/design-system.md +183 -0
  410. package/docs/getting-started.md +198 -0
  411. package/docs/message-protocol.md +262 -0
  412. package/docs/utility-classes.md +205 -0
  413. package/lighthouse-audit.mjs +113 -0
  414. package/package.json +45 -0
  415. package/scripts/analyze-components.js +105 -0
  416. package/scripts/build-app.js +193 -0
  417. package/scripts/build-framework.js +444 -0
  418. package/scripts/build-utils.js +101 -0
  419. package/scripts/test-isolated.js +151 -0
  420. package/server.js +256 -0
  421. package/src/chunks/advanced.js +27 -0
  422. package/src/chunks/core.js +61 -0
  423. package/src/chunks/display.js +25 -0
  424. package/src/chunks/feedback.js +15 -0
  425. package/src/chunks/forms.js +25 -0
  426. package/src/chunks/layout.js +27 -0
  427. package/src/components/mu-alert.js +96 -0
  428. package/src/components/mu-api-table.js +167 -0
  429. package/src/components/mu-avatar.js +94 -0
  430. package/src/components/mu-badge.js +32 -0
  431. package/src/components/mu-bottom-nav.js +115 -0
  432. package/src/components/mu-button.js +61 -0
  433. package/src/components/mu-callout.js +71 -0
  434. package/src/components/mu-card.js +36 -0
  435. package/src/components/mu-checkbox.js +186 -0
  436. package/src/components/mu-chip.js +125 -0
  437. package/src/components/mu-code.js +534 -0
  438. package/src/components/mu-confirm.js +268 -0
  439. package/src/components/mu-container.js +53 -0
  440. package/src/components/mu-datatable.js +517 -0
  441. package/src/components/mu-divider.js +40 -0
  442. package/src/components/mu-doc-page.js +100 -0
  443. package/src/components/mu-drawer-item.js +158 -0
  444. package/src/components/mu-drawer.js +305 -0
  445. package/src/components/mu-dropdown.js +239 -0
  446. package/src/components/mu-error-boundary.js +191 -0
  447. package/src/components/mu-example.js +335 -0
  448. package/src/components/mu-fetch.js +256 -0
  449. package/src/components/mu-form.js +133 -0
  450. package/src/components/mu-grid.js +63 -0
  451. package/src/components/mu-icon.js +211 -0
  452. package/src/components/mu-input.js +142 -0
  453. package/src/components/mu-layout.js +129 -0
  454. package/src/components/mu-lazy.js +94 -0
  455. package/src/components/mu-modal.js +160 -0
  456. package/src/components/mu-navbar.js +71 -0
  457. package/src/components/mu-page.js +77 -0
  458. package/src/components/mu-progress.js +54 -0
  459. package/src/components/mu-prompt-ui.js +382 -0
  460. package/src/components/mu-radio.js +200 -0
  461. package/src/components/mu-repeat.js +135 -0
  462. package/src/components/mu-router.js +169 -0
  463. package/src/components/mu-schema-form.js +441 -0
  464. package/src/components/mu-sidebar.js +81 -0
  465. package/src/components/mu-skeleton.js +69 -0
  466. package/src/components/mu-spinner.js +30 -0
  467. package/src/components/mu-stack.js +59 -0
  468. package/src/components/mu-switch.js +150 -0
  469. package/src/components/mu-table.js +80 -0
  470. package/src/components/mu-tabs.js +112 -0
  471. package/src/components/mu-textarea.js +96 -0
  472. package/src/components/mu-theme-toggle.js +52 -0
  473. package/src/components/mu-toast.js +151 -0
  474. package/src/components/mu-tooltip.js +182 -0
  475. package/src/components/mu-virtual-list.js +184 -0
  476. package/src/core/MuElement.js +562 -0
  477. package/src/core/agent-api.js +771 -0
  478. package/src/core/breakpoints.js +195 -0
  479. package/src/core/bus.js +378 -0
  480. package/src/core/component-schema.js +287 -0
  481. package/src/core/feature-registry.js +241 -0
  482. package/src/core/form-state.js +252 -0
  483. package/src/core/http.js +104 -0
  484. package/src/core/keyboard.js +105 -0
  485. package/src/core/layers.js +71 -0
  486. package/src/core/render.js +201 -0
  487. package/src/core/ripple.js +158 -0
  488. package/src/core/router.js +100 -0
  489. package/src/core/scheduler.js +109 -0
  490. package/src/core/signals.js +164 -0
  491. package/src/core/store.js +268 -0
  492. package/src/core/theme.js +68 -0
  493. package/src/core/transitions.js +72 -0
  494. package/src/core/utils.js +30 -0
  495. package/src/index.d.ts +234 -0
  496. package/src/index.js +308 -0
  497. package/src/styles/animations.css +252 -0
  498. package/src/styles/common.css +82 -0
  499. package/src/styles/components/animations.css +129 -0
  500. package/src/styles/components/avatar.css +83 -0
  501. package/src/styles/components/badge.css +80 -0
  502. package/src/styles/components/bottom-nav.css +37 -0
  503. package/src/styles/components/button.css +348 -0
  504. package/src/styles/components/card.css +138 -0
  505. package/src/styles/components/checkbox.css +201 -0
  506. package/src/styles/components/chip.css +93 -0
  507. package/src/styles/components/datatable.css +180 -0
  508. package/src/styles/components/divider.css +49 -0
  509. package/src/styles/components/drawer-item.css +123 -0
  510. package/src/styles/components/drawer.css +273 -0
  511. package/src/styles/components/grid.css +189 -0
  512. package/src/styles/components/icon.css +40 -0
  513. package/src/styles/components/input.css +203 -0
  514. package/src/styles/components/layout.css +121 -0
  515. package/src/styles/components/navbar.css +91 -0
  516. package/src/styles/components/overlays.css +329 -0
  517. package/src/styles/components/progress.css +79 -0
  518. package/src/styles/components/prompt-ui.css +286 -0
  519. package/src/styles/components/radio.css +17 -0
  520. package/src/styles/components/schema-form.css +85 -0
  521. package/src/styles/components/switch.css +69 -0
  522. package/src/styles/components/tabs.css +145 -0
  523. package/src/styles/components/tooltip.css +93 -0
  524. package/src/styles/components/virtual-list.css +36 -0
  525. package/src/styles/components.css +3677 -0
  526. package/src/styles/routes/home.css +97 -0
  527. package/src/styles/tokens.css +675 -0
  528. package/tests/agents/agent-integration.test.js +76 -0
  529. package/tests/benchmark.html +296 -0
  530. package/tests/build/scan-components.test.js +173 -0
  531. package/tests/components/all-components.test.js +245 -0
  532. package/tests/components/all-missing-components.test.js +574 -0
  533. package/tests/components/mu-alert.test.js +113 -0
  534. package/tests/components/mu-avatar.test.js +148 -0
  535. package/tests/components/mu-badge.test.js +92 -0
  536. package/tests/components/mu-button.test.js +112 -0
  537. package/tests/components/mu-card.test.js +89 -0
  538. package/tests/components/mu-checkbox.test.js +158 -0
  539. package/tests/components/mu-chip.test.js +118 -0
  540. package/tests/components/mu-container.test.js +120 -0
  541. package/tests/components/mu-divider.test.js +98 -0
  542. package/tests/components/mu-drawer-item.test.js +199 -0
  543. package/tests/components/mu-drawer.test.js +96 -0
  544. package/tests/components/mu-dropdown.test.js +125 -0
  545. package/tests/components/mu-form.test.js +138 -0
  546. package/tests/components/mu-grid.test.js +135 -0
  547. package/tests/components/mu-icon.test.js +110 -0
  548. package/tests/components/mu-input.test.js +131 -0
  549. package/tests/components/mu-lazy.test.js +103 -0
  550. package/tests/components/mu-modal.test.js +275 -0
  551. package/tests/components/mu-navbar.test.js +101 -0
  552. package/tests/components/mu-progress.test.js +115 -0
  553. package/tests/components/mu-radio.test.js +114 -0
  554. package/tests/components/mu-repeat.test.js +106 -0
  555. package/tests/components/mu-sidebar.test.js +126 -0
  556. package/tests/components/mu-skeleton.test.js +162 -0
  557. package/tests/components/mu-stack.test.js +143 -0
  558. package/tests/components/mu-switch.test.js +292 -0
  559. package/tests/components/mu-table.test.js +124 -0
  560. package/tests/components/mu-tabs.test.js +104 -0
  561. package/tests/components/mu-textarea.test.js +115 -0
  562. package/tests/components/mu-toast.test.js +321 -0
  563. package/tests/components/mu-tooltip.test.js +133 -0
  564. package/tests/components/mu-virtual-list.test.js +109 -0
  565. package/tests/core/MuElement.test.js +120 -0
  566. package/tests/core/agent-api.test.js +125 -0
  567. package/tests/core/all-core-modules.test.js +442 -0
  568. package/tests/core/bus.test.js +364 -0
  569. package/tests/core/component-schema.test.js +160 -0
  570. package/tests/core/feature-registry.test.js +198 -0
  571. package/tests/core/form-state.test.js +167 -0
  572. package/tests/core/http.test.js +119 -0
  573. package/tests/core/keyboard.test.js +319 -0
  574. package/tests/core/layers.test.js +129 -0
  575. package/tests/core/namespaced-stores.test.js +114 -0
  576. package/tests/core/render.test.js +121 -0
  577. package/tests/core/ripple.test.js +131 -0
  578. package/tests/core/router.test.js +89 -0
  579. package/tests/core/scheduler.test.js +121 -0
  580. package/tests/core/signals.test.js +128 -0
  581. package/tests/core/store.test.js +171 -0
  582. package/tests/core/transitions.test.js +82 -0
  583. package/tests/e2e/accessibility-harness.html +58 -0
  584. package/tests/e2e/accessibility.test.js +401 -0
  585. package/tests/e2e/agent-features.test.js +372 -0
  586. package/tests/e2e/card-spacing.test.js +287 -0
  587. package/tests/e2e/components.test.js +439 -0
  588. package/tests/e2e/demo-routes.test.js +478 -0
  589. package/tests/e2e/layout-css-fallback.test.js +334 -0
  590. package/tests/e2e/mu-alert.e2e.test.js +111 -0
  591. package/tests/e2e/mu-checkbox.test.js +489 -0
  592. package/tests/e2e/mu-chip.test.js +347 -0
  593. package/tests/e2e/mu-form.test.js +499 -0
  594. package/tests/e2e/mu-icon.test.js +114 -0
  595. package/tests/e2e/mu-radio.test.js +113 -0
  596. package/tests/e2e/mu-skeleton.test.js +140 -0
  597. package/tests/e2e/mu-switch.test.js +415 -0
  598. package/tests/e2e/mu-tabs.test.js +494 -0
  599. package/tests/e2e/mu-textarea.test.js +242 -0
  600. package/tests/e2e/mu-virtual-list.test.js +427 -0
  601. package/tests/e2e/perf-memory.test.js +161 -0
  602. package/tests/e2e/puppeteer-helper.js +137 -0
  603. package/tests/e2e/puppeteer.test.js +226 -0
  604. package/tests/e2e/pwa.test.js +261 -0
  605. package/tests/e2e/test-harness.html +319 -0
  606. package/tests/manual/test-components.html +120 -0
  607. package/tests/memory-test.html +309 -0
  608. package/tests/setup-dom.js +93 -0
  609. package/tests/visual-test.html +301 -0
@@ -0,0 +1,164 @@
1
+ /**
2
+ * @fileoverview Signals - Fine-Grained Reactivity via EventBus (2026 SOTA)
3
+ *
4
+ * Built on top of microUI's EventBus for consistent event architecture.
5
+ * Enables reactive updates without VDOM diffing.
6
+ *
7
+ * Usage:
8
+ * const count = signal(0, 'count');
9
+ * effect((bus) => bus.on('signal:count', (v) => console.log(v)));
10
+ * count.set(5); // Emits 'signal:count' on bus
11
+ */
12
+
13
+ import { bus } from './bus.js';
14
+
15
+ let signalId = 0;
16
+
17
+ /**
18
+ * Create a reactive signal backed by EventBus
19
+ * @param {T} initialValue
20
+ * @param {string} name - Optional name for debugging
21
+ * @returns {Signal<T>}
22
+ */
23
+ export function signal(initialValue, name) {
24
+ let value = initialValue;
25
+ const id = name || `signal_${++signalId}`;
26
+ const eventName = `signal:${id}`;
27
+ const subscribers = new Set();
28
+
29
+ // Read function
30
+ const read = () => {
31
+ // Track in current computation
32
+ if (currentComputation) {
33
+ const unsub = bus.on(eventName, currentComputation);
34
+ subscribers.add(unsub);
35
+ }
36
+ return value;
37
+ };
38
+
39
+ // Set value and emit on bus
40
+ read.set = (newValue) => {
41
+ if (value !== newValue) {
42
+ const oldValue = value;
43
+ value = newValue;
44
+
45
+ // Emit change event on bus
46
+ bus.emit(eventName, { value: newValue, oldValue, signal: id });
47
+ }
48
+ };
49
+
50
+ // Update with function
51
+ read.update = (fn) => {
52
+ read.set(fn(value));
53
+ };
54
+
55
+ // Get value without tracking
56
+ read.peek = () => value;
57
+
58
+ // Get signal name (using signalName since Function.name is readonly)
59
+ read.signalName = id;
60
+
61
+ // Subscribe to this signal via bus
62
+ read.subscribe = (callback) => {
63
+ return bus.on(eventName, (data) => callback(data.value, data.oldValue));
64
+ };
65
+
66
+ // Cleanup
67
+ read.dispose = () => {
68
+ for (const unsub of subscribers) {
69
+ unsub();
70
+ }
71
+ subscribers.clear();
72
+ };
73
+
74
+ return read;
75
+ }
76
+
77
+ // Current computation being tracked
78
+ let currentComputation = null;
79
+
80
+ /**
81
+ * Create a computed signal (derived)
82
+ * Re-computes when dependencies change via bus events
83
+ */
84
+ export function computed(fn, name) {
85
+ const id = name || `computed_${++signalId}`;
86
+ const eventName = `signal:${id}`;
87
+ let cachedValue;
88
+ let dirty = true;
89
+
90
+ const recompute = () => {
91
+ dirty = true;
92
+ const newValue = fn();
93
+ if (cachedValue !== newValue) {
94
+ cachedValue = newValue;
95
+ bus.emit(eventName, { value: newValue, signal: id });
96
+ }
97
+ };
98
+
99
+ const read = () => {
100
+ if (dirty) {
101
+ const prevComputation = currentComputation;
102
+ currentComputation = recompute;
103
+ try {
104
+ cachedValue = fn();
105
+ } finally {
106
+ currentComputation = prevComputation;
107
+ }
108
+ dirty = false;
109
+ }
110
+
111
+ // Track in parent computation
112
+ if (currentComputation) {
113
+ bus.on(eventName, currentComputation);
114
+ }
115
+
116
+ return cachedValue;
117
+ };
118
+
119
+ read.signalName = id;
120
+ read.subscribe = (callback) => bus.on(eventName, (d) => callback(d.value));
121
+
122
+ return read;
123
+ }
124
+
125
+ /**
126
+ * Create a reactive effect (side effect)
127
+ * Runs when any tracked signal changes via bus
128
+ */
129
+ export function effect(fn) {
130
+ let disposed = false;
131
+ const unsubs = [];
132
+
133
+ const run = () => {
134
+ if (disposed) return;
135
+
136
+ // Clear old subscriptions
137
+ for (const unsub of unsubs) unsub();
138
+ unsubs.length = 0;
139
+
140
+ const prevComputation = currentComputation;
141
+ currentComputation = run;
142
+ try {
143
+ fn();
144
+ } finally {
145
+ currentComputation = prevComputation;
146
+ }
147
+ };
148
+
149
+ // Run immediately
150
+ run();
151
+
152
+ // Return dispose function
153
+ return () => {
154
+ disposed = true;
155
+ for (const unsub of unsubs) unsub();
156
+ };
157
+ }
158
+
159
+ /**
160
+ * Batch multiple signal updates (uses bus batching)
161
+ */
162
+ export function batch(fn) {
163
+ fn();
164
+ }
@@ -0,0 +1,268 @@
1
+ /**
2
+ * @fileoverview Simple Reactive Store for microUI
3
+ *
4
+ * Lightweight state management without complexity.
5
+ *
6
+ * Usage:
7
+ * const store = createStore({ count: 0 });
8
+ * store.subscribe((state) => console.log(state.count));
9
+ * store.set({ count: 1 });
10
+ * store.update(s => ({ count: s.count + 1 }));
11
+ */
12
+
13
+ /**
14
+ * Create a reactive store
15
+ * @param {T} initialState - Initial state object
16
+ * @returns {Store<T>}
17
+ */
18
+ export function createStore(initialState = {}) {
19
+ let state = { ...initialState };
20
+ const listeners = new Set();
21
+
22
+ return {
23
+ /**
24
+ * Get current state
25
+ */
26
+ get() {
27
+ return state;
28
+ },
29
+
30
+ /**
31
+ * Set new state (merges with existing)
32
+ * @param {Partial<T>} newState
33
+ */
34
+ set(newState) {
35
+ state = { ...state, ...newState };
36
+ this.notify();
37
+ },
38
+
39
+ /**
40
+ * Update state with function
41
+ * @param {(s: T) => Partial<T>} fn
42
+ */
43
+ update(fn) {
44
+ const updates = fn(state);
45
+ this.set(updates);
46
+ },
47
+
48
+ /**
49
+ * Subscribe to state changes
50
+ * @param {(state: T) => void} listener
51
+ * @returns {() => void} Unsubscribe function
52
+ */
53
+ subscribe(listener) {
54
+ listeners.add(listener);
55
+ // Call immediately with current state
56
+ listener(state);
57
+ return () => listeners.delete(listener);
58
+ },
59
+
60
+ /**
61
+ * Notify all listeners
62
+ */
63
+ notify() {
64
+ for (const listener of listeners) {
65
+ listener(state);
66
+ }
67
+ },
68
+
69
+ /**
70
+ * Reset to initial state
71
+ */
72
+ reset() {
73
+ state = { ...initialState };
74
+ this.notify();
75
+ }
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Global app store (singleton pattern)
81
+ */
82
+ export const appStore = createStore({});
83
+
84
+ // ============================================
85
+ // NAMESPACED STORES (Enterprise-Scale Feature)
86
+ // ============================================
87
+
88
+ /**
89
+ * Registry of all namespaced stores for large-scale apps
90
+ * @type {Map<string, Store>}
91
+ */
92
+ const storeRegistry = new Map();
93
+
94
+ /**
95
+ * State change history for observability
96
+ * @type {Map<string, Array<{timestamp: number, state: Object}>>}
97
+ */
98
+ const stateHistory = new Map();
99
+
100
+ /** Whether observability is enabled */
101
+ let observabilityEnabled = false;
102
+
103
+ /**
104
+ * Create a namespaced store for isolated state management.
105
+ * Each feature/module can have its own isolated store.
106
+ *
107
+ * @param {string} namespace - Unique namespace for this store (e.g., 'user', 'cart')
108
+ * @param {Object} initialState - Initial state for this namespace
109
+ * @returns {Store} Store instance
110
+ *
111
+ * @example
112
+ * const userStore = createNamespacedStore('user', { profile: null });
113
+ * const cartStore = createNamespacedStore('cart', { items: [] });
114
+ */
115
+ export function createNamespacedStore(namespace, initialState = {}) {
116
+ if (storeRegistry.has(namespace)) {
117
+ console.warn(`[microUI] Store namespace "${namespace}" already exists. Returning existing store.`);
118
+ return storeRegistry.get(namespace);
119
+ }
120
+
121
+ const store = createStore(initialState);
122
+
123
+ // Wrap set to track history if observability enabled
124
+ const originalSet = store.set.bind(store);
125
+ store.set = function (newState) {
126
+ if (observabilityEnabled) {
127
+ if (!stateHistory.has(namespace)) {
128
+ stateHistory.set(namespace, []);
129
+ }
130
+ stateHistory.get(namespace).push({
131
+ timestamp: Date.now(),
132
+ state: { ...store.get() }
133
+ });
134
+ // Keep last 100 entries
135
+ const history = stateHistory.get(namespace);
136
+ if (history.length > 100) history.shift();
137
+ }
138
+ originalSet(newState);
139
+ };
140
+
141
+ // Add namespace property
142
+ store.namespace = namespace;
143
+
144
+ storeRegistry.set(namespace, store);
145
+ return store;
146
+ }
147
+
148
+ /**
149
+ * Get a store by namespace
150
+ * @param {string} namespace
151
+ * @returns {Store|undefined}
152
+ */
153
+ export function getStore(namespace) {
154
+ return storeRegistry.get(namespace);
155
+ }
156
+
157
+ /**
158
+ * Get all registered stores as a plain object
159
+ * @returns {Object<string, Store>}
160
+ */
161
+ export function getAllStores() {
162
+ const stores = {};
163
+ for (const [namespace, store] of storeRegistry) {
164
+ stores[namespace] = store;
165
+ }
166
+ return stores;
167
+ }
168
+
169
+ /**
170
+ * Capture the entire application state (all namespaced stores)
171
+ * Useful for debugging, serialization, or time-travel debugging.
172
+ *
173
+ * @returns {Object} Snapshot of all store states
174
+ *
175
+ * @example
176
+ * const snapshot = captureAppState();
177
+ * localStorage.setItem('app-state', JSON.stringify(snapshot));
178
+ */
179
+ export function captureAppState() {
180
+ const snapshot = {
181
+ timestamp: Date.now(),
182
+ stores: {}
183
+ };
184
+
185
+ for (const [namespace, store] of storeRegistry) {
186
+ snapshot.stores[namespace] = { ...store.get() };
187
+ }
188
+
189
+ // Include global appStore
190
+ snapshot.stores['__global__'] = { ...appStore.get() };
191
+
192
+ return snapshot;
193
+ }
194
+
195
+ /**
196
+ * Restore application state from a snapshot
197
+ *
198
+ * @param {Object} snapshot - Previously captured state snapshot
199
+ * @param {Object} [options] - Options
200
+ * @param {boolean} [options.createMissing=false] - Create stores for namespaces not yet registered
201
+ *
202
+ * @example
203
+ * const snapshot = JSON.parse(localStorage.getItem('app-state'));
204
+ * restoreAppState(snapshot);
205
+ */
206
+ export function restoreAppState(snapshot, options = {}) {
207
+ const { createMissing = false } = options;
208
+
209
+ if (!snapshot?.stores) {
210
+ console.warn('[microUI] Invalid snapshot provided to restoreAppState');
211
+ return;
212
+ }
213
+
214
+ for (const [namespace, state] of Object.entries(snapshot.stores)) {
215
+ if (namespace === '__global__') {
216
+ appStore.set(state);
217
+ continue;
218
+ }
219
+
220
+ let store = storeRegistry.get(namespace);
221
+
222
+ if (!store && createMissing) {
223
+ store = createNamespacedStore(namespace, {});
224
+ }
225
+
226
+ if (store) {
227
+ store.set(state);
228
+ }
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Get state change history for a namespace (requires observability enabled)
234
+ * @param {string} namespace
235
+ * @returns {Array<{timestamp: number, state: Object}>}
236
+ */
237
+ export function getStateHistory(namespace) {
238
+ return stateHistory.get(namespace) || [];
239
+ }
240
+
241
+ /**
242
+ * Enable state observability (tracks state changes for debugging)
243
+ */
244
+ export function enableObservability() {
245
+ observabilityEnabled = true;
246
+ }
247
+
248
+ /**
249
+ * Disable state observability
250
+ */
251
+ export function disableObservability() {
252
+ observabilityEnabled = false;
253
+ }
254
+
255
+ /**
256
+ * Clear all state history
257
+ */
258
+ export function clearStateHistory() {
259
+ stateHistory.clear();
260
+ }
261
+
262
+ /**
263
+ * Clear store registry (useful for testing)
264
+ */
265
+ export function clearStoreRegistry() {
266
+ storeRegistry.clear();
267
+ stateHistory.clear();
268
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @fileoverview Theme System for microUI
3
+ *
4
+ * Provides light/dark mode toggling and theme management.
5
+ * Uses CSS custom properties and data-theme attribute.
6
+ */
7
+
8
+ import { bus, UIEvents } from './bus.js';
9
+
10
+ /**
11
+ * Theme manager singleton
12
+ */
13
+ export const Theme = {
14
+ /**
15
+ * Set the current theme
16
+ * @param {'light'|'dark'|'auto'} theme
17
+ */
18
+ set(theme) {
19
+ if (theme === 'auto') {
20
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
21
+ document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light');
22
+ } else {
23
+ document.documentElement.setAttribute('data-theme', theme);
24
+ }
25
+ localStorage.setItem('mu-theme', theme);
26
+ bus.emit(UIEvents.THEME_CHANGE, { theme });
27
+ },
28
+
29
+ /**
30
+ * Get current theme
31
+ * @returns {'light'|'dark'}
32
+ */
33
+ get() {
34
+ return document.documentElement.getAttribute('data-theme') || 'light';
35
+ },
36
+
37
+ /**
38
+ * Toggle between light and dark
39
+ */
40
+ toggle() {
41
+ const current = this.get();
42
+ this.set(current === 'dark' ? 'light' : 'dark');
43
+ },
44
+
45
+ /**
46
+ * Initialize theme from localStorage or system preference
47
+ */
48
+ init() {
49
+ const saved = localStorage.getItem('mu-theme');
50
+ if (saved) {
51
+ this.set(saved);
52
+ } else {
53
+ this.set('auto');
54
+ }
55
+
56
+ // Listen for system preference changes
57
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
58
+ if (localStorage.getItem('mu-theme') === 'auto') {
59
+ document.documentElement.setAttribute('data-theme', e.matches ? 'dark' : 'light');
60
+ }
61
+ });
62
+ }
63
+ };
64
+
65
+ // Auto-init on load
66
+ if (typeof window !== 'undefined') {
67
+ Theme.init();
68
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @fileoverview View Transitions API Wrapper (2026 SOTA)
3
+ *
4
+ * Provides smooth, GPU-accelerated page transitions.
5
+ * Falls back gracefully if not supported.
6
+ *
7
+ * Usage:
8
+ * await transition(() => {
9
+ * document.getElementById('app').innerHTML = newContent;
10
+ * });
11
+ */
12
+
13
+ /**
14
+ * Check if View Transitions API is supported
15
+ */
16
+ export const supportsViewTransitions = 'startViewTransition' in document;
17
+
18
+ /**
19
+ * Perform a view transition with fallback
20
+ * @param {() => void | Promise<void>} updateCallback - DOM update function
21
+ * @returns {Promise<void>}
22
+ */
23
+ export async function transition(updateCallback) {
24
+ if (supportsViewTransitions) {
25
+ const viewTransition = document.startViewTransition(async () => {
26
+ await updateCallback();
27
+ });
28
+
29
+ await viewTransition.finished;
30
+ } else {
31
+ // Fallback: just run the update
32
+ await updateCallback();
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Transition with custom animation classes
38
+ * @param {() => void | Promise<void>} updateCallback
39
+ * @param {Object} options
40
+ * @param {string} options.name - View transition name
41
+ */
42
+ export async function transitionNamed(updateCallback, { name = 'page' } = {}) {
43
+ if (supportsViewTransitions) {
44
+ // Add transition name dynamically
45
+ const style = document.createElement('style');
46
+ style.textContent = `
47
+ ::view-transition-old(${name}),
48
+ ::view-transition-new(${name}) {
49
+ animation-duration: 0.3s;
50
+ }
51
+ `;
52
+ document.head.appendChild(style);
53
+
54
+ await transition(updateCallback);
55
+
56
+ style.remove();
57
+ } else {
58
+ await updateCallback();
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Navigate with view transition
64
+ * @param {string} path - Route path
65
+ * @param {Function} render - Render function
66
+ */
67
+ export async function navigateWithTransition(path, render) {
68
+ await transition(() => {
69
+ window.history.pushState({}, '', path);
70
+ render();
71
+ });
72
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @fileoverview Centralized Utility Functions for microUI
3
+ *
4
+ * Common utility functions used across components.
5
+ * Import and use these instead of defining inline.
6
+ */
7
+
8
+ /**
9
+ * Escape HTML entities to prevent XSS attacks.
10
+ * Use this when inserting user-provided content into templates.
11
+ *
12
+ * @param {string|null|undefined} str - String to escape
13
+ * @returns {string} Escaped string safe for HTML insertion
14
+ *
15
+ * @example
16
+ * import { escapeHTML } from '../core/utils.js';
17
+ *
18
+ * const userInput = '<script>alert("xss")</script>';
19
+ * element.innerHTML = `<div>${escapeHTML(userInput)}</div>`;
20
+ * // Result: <div>&lt;script&gt;alert("xss")&lt;/script&gt;</div>
21
+ */
22
+ export function escapeHTML(str) {
23
+ if (str == null) return '';
24
+ return String(str)
25
+ .replace(/&/g, '&amp;')
26
+ .replace(/</g, '&lt;')
27
+ .replace(/>/g, '&gt;')
28
+ .replace(/"/g, '&quot;')
29
+ .replace(/'/g, '&#039;');
30
+ }