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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +33 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +28 -0
- package/.github/workflows/ci.yml +42 -0
- package/.github/workflows/deploy-pages.yml +112 -0
- package/AGENTS.md +2366 -0
- package/CHANGELOG.md +47 -0
- package/CODE_OF_CONDUCT.md +59 -0
- package/CONTRIBUTING.md +156 -0
- package/LICENSE +190 -0
- package/README.md +254 -0
- package/SECURITY.md +58 -0
- package/app/.generated/routes/alerts.js +8 -0
- package/app/.generated/routes/avatars.js +8 -0
- package/app/.generated/routes/badges.js +8 -0
- package/app/.generated/routes/buttons.js +10 -0
- package/app/.generated/routes/cards.js +10 -0
- package/app/.generated/routes/checkboxes.js +9 -0
- package/app/.generated/routes/chips.js +8 -0
- package/app/.generated/routes/dropdowns.js +9 -0
- package/app/.generated/routes/home.js +7 -0
- package/app/.generated/routes/icons.js +9 -0
- package/app/.generated/routes/inputs.js +10 -0
- package/app/.generated/routes/installation.js +7 -0
- package/app/.generated/routes/layout.js +9 -0
- package/app/.generated/routes/modals.js +9 -0
- package/app/.generated/routes/navbar.js +7 -0
- package/app/.generated/routes/progress.js +9 -0
- package/app/.generated/routes/radios.js +9 -0
- package/app/.generated/routes/switches.js +9 -0
- package/app/.generated/routes/tabs.js +8 -0
- package/app/.generated/routes/toasts.js +9 -0
- package/app/index.html +67 -0
- package/app/pages/alerts.html +23 -0
- package/app/pages/avatars.html +22 -0
- package/app/pages/badges.html +22 -0
- package/app/pages/buttons.html +71 -0
- package/app/pages/cards.html +54 -0
- package/app/pages/checkboxes.html +39 -0
- package/app/pages/chips.html +23 -0
- package/app/pages/dropdowns.html +41 -0
- package/app/pages/home.html +59 -0
- package/app/pages/icons.html +29 -0
- package/app/pages/inputs.html +66 -0
- package/app/pages/installation.html +34 -0
- package/app/pages/layout.html +30 -0
- package/app/pages/modals.html +21 -0
- package/app/pages/navbar.html +22 -0
- package/app/pages/progress.html +35 -0
- package/app/pages/radios.html +40 -0
- package/app/pages/switches.html +39 -0
- package/app/pages/tabs.html +30 -0
- package/app/pages/toasts.html +22 -0
- package/app-dist/index.html +67 -0
- package/app-dist/pages/alerts.html +23 -0
- package/app-dist/pages/avatars.html +22 -0
- package/app-dist/pages/badges.html +22 -0
- package/app-dist/pages/buttons.html +71 -0
- package/app-dist/pages/cards.html +54 -0
- package/app-dist/pages/checkboxes.html +39 -0
- package/app-dist/pages/chips.html +23 -0
- package/app-dist/pages/dropdowns.html +41 -0
- package/app-dist/pages/home.html +59 -0
- package/app-dist/pages/icons.html +29 -0
- package/app-dist/pages/inputs.html +66 -0
- package/app-dist/pages/installation.html +34 -0
- package/app-dist/pages/layout.html +30 -0
- package/app-dist/pages/modals.html +21 -0
- package/app-dist/pages/navbar.html +22 -0
- package/app-dist/pages/progress.html +35 -0
- package/app-dist/pages/radios.html +40 -0
- package/app-dist/pages/switches.html +39 -0
- package/app-dist/pages/tabs.html +30 -0
- package/app-dist/pages/toasts.html +22 -0
- package/app-dist/pages.json +217 -0
- package/app-dist/routes/alerts.js +5 -0
- package/app-dist/routes/avatars.js +1 -0
- package/app-dist/routes/badges.js +1 -0
- package/app-dist/routes/buttons.js +1 -0
- package/app-dist/routes/cards.js +1 -0
- package/app-dist/routes/checkboxes.js +9 -0
- package/app-dist/routes/chips.js +4 -0
- package/app-dist/routes/chunk-019e5e2f.js +5 -0
- package/app-dist/routes/chunk-0m4j19yd.js +2 -0
- package/app-dist/routes/chunk-0tmmp5q0.js +1 -0
- package/app-dist/routes/chunk-10xn709r.js +1 -0
- package/app-dist/routes/chunk-15m2qcda.js +2 -0
- package/app-dist/routes/chunk-1bh8g23n.js +1 -0
- package/app-dist/routes/chunk-1vg0v937.js +1 -0
- package/app-dist/routes/chunk-1zvcgy3j.js +1 -0
- package/app-dist/routes/chunk-2afb0861.js +1 -0
- package/app-dist/routes/chunk-2c6ttpzt.js +5 -0
- package/app-dist/routes/chunk-3dy30fhs.js +1 -0
- package/app-dist/routes/chunk-426dnces.js +13 -0
- package/app-dist/routes/chunk-44kgxery.js +1 -0
- package/app-dist/routes/chunk-47fdnejd.js +33 -0
- package/app-dist/routes/chunk-49a6t2vq.js +1 -0
- package/app-dist/routes/chunk-4fe1rm5b.js +1 -0
- package/app-dist/routes/chunk-4ggmvkta.js +33 -0
- package/app-dist/routes/chunk-4vkz81q7.js +33 -0
- package/app-dist/routes/chunk-4w4tmj8f.js +31 -0
- package/app-dist/routes/chunk-532s62kr.js +31 -0
- package/app-dist/routes/chunk-5hm3bssy.js +33 -0
- package/app-dist/routes/chunk-5vrh24hc.js +1 -0
- package/app-dist/routes/chunk-61pcg25a.js +1 -0
- package/app-dist/routes/chunk-6nfhygvf.js +1 -0
- package/app-dist/routes/chunk-700e7je6.js +33 -0
- package/app-dist/routes/chunk-7fsn17kg.js +1 -0
- package/app-dist/routes/chunk-7k789b32.js +1 -0
- package/app-dist/routes/chunk-7r46q0ys.js +36 -0
- package/app-dist/routes/chunk-86fmc1fr.js +5 -0
- package/app-dist/routes/chunk-8qth37vw.js +1 -0
- package/app-dist/routes/chunk-924wv8n0.js +1 -0
- package/app-dist/routes/chunk-9mbhgxk9.js +1 -0
- package/app-dist/routes/chunk-a216hyd9.js +1 -0
- package/app-dist/routes/chunk-akzxykh9.js +33 -0
- package/app-dist/routes/chunk-b3dcvy8c.js +1 -0
- package/app-dist/routes/chunk-b74zahz5.js +31 -0
- package/app-dist/routes/chunk-bftj53p2.js +5 -0
- package/app-dist/routes/chunk-c01hnz3e.js +1 -0
- package/app-dist/routes/chunk-d8pvv5km.js +1 -0
- package/app-dist/routes/chunk-dev0aezr.js +2 -0
- package/app-dist/routes/chunk-dh6vnv0e.js +1 -0
- package/app-dist/routes/chunk-dn2cbpva.js +36 -0
- package/app-dist/routes/chunk-dvn0my90.js +1 -0
- package/app-dist/routes/chunk-dvq8mnve.js +36 -0
- package/app-dist/routes/chunk-e8c2gc4d.js +5 -0
- package/app-dist/routes/chunk-ejf9ak2x.js +1 -0
- package/app-dist/routes/chunk-f083m55s.js +1 -0
- package/app-dist/routes/chunk-fnrj28s1.js +31 -0
- package/app-dist/routes/chunk-fvg3yjdp.js +31 -0
- package/app-dist/routes/chunk-g7k381n1.js +1 -0
- package/app-dist/routes/chunk-h01kq2ae.js +13 -0
- package/app-dist/routes/chunk-h4dk761v.js +5 -0
- package/app-dist/routes/chunk-hmx91z2x.js +5 -0
- package/app-dist/routes/chunk-hxbg4m42.js +36 -0
- package/app-dist/routes/chunk-jbjnfp2b.js +2 -0
- package/app-dist/routes/chunk-jxtz5vv6.js +36 -0
- package/app-dist/routes/chunk-jxzcs0ey.js +36 -0
- package/app-dist/routes/chunk-kt7wwhcx.js +1 -0
- package/app-dist/routes/chunk-kzptszyc.js +33 -0
- package/app-dist/routes/chunk-mhgca4w4.js +2 -0
- package/app-dist/routes/chunk-mhswxa20.js +1 -0
- package/app-dist/routes/chunk-n8zfeex6.js +1 -0
- package/app-dist/routes/chunk-pee47b2r.js +1 -0
- package/app-dist/routes/chunk-pesmw829.js +1 -0
- package/app-dist/routes/chunk-pgc4c6f3.js +36 -0
- package/app-dist/routes/chunk-q8egegm1.js +1 -0
- package/app-dist/routes/chunk-q9mn2qyq.js +36 -0
- package/app-dist/routes/chunk-qh0rtaf3.js +5 -0
- package/app-dist/routes/chunk-qqhmk6ye.js +2 -0
- package/app-dist/routes/chunk-qrxygmf7.js +33 -0
- package/app-dist/routes/chunk-r46yzksx.js +36 -0
- package/app-dist/routes/chunk-rgpbw2w0.js +5 -0
- package/app-dist/routes/chunk-rnpzv3d8.js +2 -0
- package/app-dist/routes/chunk-s5v8cv05.js +2 -0
- package/app-dist/routes/chunk-sbwn5bpc.js +1 -0
- package/app-dist/routes/chunk-sqbg8jbt.js +33 -0
- package/app-dist/routes/chunk-sv8dqnf7.js +1 -0
- package/app-dist/routes/chunk-t67sw3za.js +1 -0
- package/app-dist/routes/chunk-tjdpqwdf.js +31 -0
- package/app-dist/routes/chunk-tq2mfghg.js +1 -0
- package/app-dist/routes/chunk-ttn10vt6.js +1 -0
- package/app-dist/routes/chunk-v2hzpjxr.js +1 -0
- package/app-dist/routes/chunk-wfjjkw9y.js +1 -0
- package/app-dist/routes/chunk-wt8cxzmf.js +31 -0
- package/app-dist/routes/chunk-x45d372k.js +5 -0
- package/app-dist/routes/chunk-y3wsazkt.js +1 -0
- package/app-dist/routes/chunk-y7pmgc7t.js +33 -0
- package/app-dist/routes/chunk-zefdt2q3.js +31 -0
- package/app-dist/routes/dropdowns.js +6 -0
- package/app-dist/routes/home.js +1 -0
- package/app-dist/routes/icons.js +1 -0
- package/app-dist/routes/inputs.js +12 -0
- package/app-dist/routes/installation.js +1 -0
- package/app-dist/routes/layout.js +1 -0
- package/app-dist/routes/modals.js +7 -0
- package/app-dist/routes/navbar.js +1 -0
- package/app-dist/routes/progress.js +1 -0
- package/app-dist/routes/radios.js +6 -0
- package/app-dist/routes/switches.js +6 -0
- package/app-dist/routes/tabs.js +1 -0
- package/app-dist/routes/toasts.js +16 -0
- package/assets/fonts/material-symbols-mini.woff2 +0 -0
- package/assets/fonts/material-symbols.woff2 +0 -0
- package/assets/fonts/roboto-400.woff2 +0 -0
- package/assets/fonts/roboto-500.woff2 +0 -0
- package/assets/fonts/roboto-700.woff2 +0 -0
- package/assets/logo-banner-400.jpg +0 -0
- package/assets/logo-banner-400.webp +0 -0
- package/assets/logo-banner-800.webp +0 -0
- package/assets/logo-banner.jpg +0 -0
- package/assets/logo-icon-64.jpg +0 -0
- package/assets/logo-icon-64.webp +0 -0
- package/assets/logo-icon.jpg +0 -0
- package/assets/logo-square.jpg +0 -0
- package/bun.lock +312 -0
- package/bunfig.toml +4 -0
- package/custom-elements.json +1916 -0
- package/demo/api/sample-data.json +38 -0
- package/demo/content/alerts.html +115 -0
- package/demo/content/avatars.html +70 -0
- package/demo/content/badges.html +65 -0
- package/demo/content/buttons.html +188 -0
- package/demo/content/callouts.html +91 -0
- package/demo/content/cards.html +121 -0
- package/demo/content/checkboxes.html +178 -0
- package/demo/content/chips.html +67 -0
- package/demo/content/codeblocks.html +101 -0
- package/demo/content/confirms.html +115 -0
- package/demo/content/datatables.html +149 -0
- package/demo/content/dividers.html +119 -0
- package/demo/content/dropdowns.html +89 -0
- package/demo/content/enterprise.html +252 -0
- package/demo/content/home.html +149 -0
- package/demo/content/icons.html +89 -0
- package/demo/content/inputs.html +135 -0
- package/demo/content/installation.html +16 -0
- package/demo/content/layout.html +136 -0
- package/demo/content/modals.html +141 -0
- package/demo/content/navbar.html +70 -0
- package/demo/content/progress.html +119 -0
- package/demo/content/radios.html +88 -0
- package/demo/content/skeletons.html +109 -0
- package/demo/content/spinners.html +96 -0
- package/demo/content/switches.html +84 -0
- package/demo/content/tables.html +124 -0
- package/demo/content/tabs.html +85 -0
- package/demo/content/toasts.html +116 -0
- package/demo/content/tooltips.html +107 -0
- package/demo/content/virtual-lists.html +233 -0
- package/demo/favicon.ico +0 -0
- package/demo/favicon.png +0 -0
- package/demo/full.html +52 -0
- package/demo/iife.html +46 -0
- package/demo/manifest.json +34 -0
- package/demo/pages/datatable-demo.html +237 -0
- package/demo/pages/prompt-ui-demo.html +218 -0
- package/demo/pages/responsive-demo.html +122 -0
- package/demo/pages/schema-form-demo.html +270 -0
- package/demo/robots.txt +6 -0
- package/demo/shell.html +712 -0
- package/demo/sw.js +387 -0
- package/dist/AGENTS.md +2366 -0
- package/dist/README.md +254 -0
- package/dist/chunks/advanced.js +174 -0
- package/dist/chunks/chunk-1nhr1wrq.js +14 -0
- package/dist/chunks/chunk-hssyjbr0.js +2 -0
- package/dist/chunks/chunk-k8etzx0z.js +2 -0
- package/dist/chunks/chunk-rr1et8fg.js +2 -0
- package/dist/chunks/chunk-sjcx4fd5.js +6 -0
- package/dist/chunks/chunk-v1c777xh.js +5 -0
- package/dist/chunks/chunk-w5k5vwjd.js +13 -0
- package/dist/chunks/core.js +10 -0
- package/dist/chunks/display.js +17 -0
- package/dist/chunks/feedback.js +15 -0
- package/dist/chunks/forms.js +48 -0
- package/dist/chunks/layout.js +9 -0
- package/dist/components/chunk-4tezav8r.js +2 -0
- package/dist/components/chunk-fqyb2pms.js +2 -0
- package/dist/components/chunk-h7cdbhxw.js +13 -0
- package/dist/components/chunk-mzd8jwrs.js +2 -0
- package/dist/components/chunk-qwmxyn8e.js +2 -0
- package/dist/components/chunk-redtk47a.js +14 -0
- package/dist/components/mu-alert.js +5 -0
- package/dist/components/mu-api-table.js +33 -0
- package/dist/components/mu-avatar.js +1 -0
- package/dist/components/mu-badge.js +1 -0
- package/dist/components/mu-bottom-nav.js +1 -0
- package/dist/components/mu-button.js +1 -0
- package/dist/components/mu-callout.js +1 -0
- package/dist/components/mu-card.js +1 -0
- package/dist/components/mu-checkbox.js +9 -0
- package/dist/components/mu-chip.js +4 -0
- package/dist/components/mu-code.js +48 -0
- package/dist/components/mu-confirm.js +10 -0
- package/dist/components/mu-container.js +1 -0
- package/dist/components/mu-datatable.js +96 -0
- package/dist/components/mu-divider.js +1 -0
- package/dist/components/mu-doc-page.js +26 -0
- package/dist/components/mu-drawer-item.js +9 -0
- package/dist/components/mu-drawer.js +1 -0
- package/dist/components/mu-dropdown.js +6 -0
- package/dist/components/mu-error-boundary.js +10 -0
- package/dist/components/mu-example.js +38 -0
- package/dist/components/mu-fetch.js +1 -0
- package/dist/components/mu-form.js +1 -0
- package/dist/components/mu-grid.js +1 -0
- package/dist/components/mu-icon.js +5 -0
- package/dist/components/mu-input.js +12 -0
- package/dist/components/mu-layout.js +1 -0
- package/dist/components/mu-lazy.js +1 -0
- package/dist/components/mu-modal.js +7 -0
- package/dist/components/mu-navbar.js +1 -0
- package/dist/components/mu-page.js +1 -0
- package/dist/components/mu-progress.js +1 -0
- package/dist/components/mu-prompt-ui.js +20 -0
- package/dist/components/mu-radio.js +6 -0
- package/dist/components/mu-repeat.js +1 -0
- package/dist/components/mu-router.js +6 -0
- package/dist/components/mu-schema-form.js +76 -0
- package/dist/components/mu-sidebar.js +1 -0
- package/dist/components/mu-skeleton.js +13 -0
- package/dist/components/mu-spinner.js +1 -0
- package/dist/components/mu-stack.js +1 -0
- package/dist/components/mu-switch.js +6 -0
- package/dist/components/mu-table.js +1 -0
- package/dist/components/mu-tabs.js +1 -0
- package/dist/components/mu-textarea.js +11 -0
- package/dist/components/mu-theme-toggle.js +5 -0
- package/dist/components/mu-toast.js +4 -0
- package/dist/components/mu-tooltip.js +10 -0
- package/dist/components/mu-virtual-list.js +33 -0
- package/dist/components.css +1 -0
- package/dist/microui.css +1 -0
- package/dist/microui.d.ts +234 -0
- package/dist/microui.esm.js +549 -0
- package/dist/microui.esm.js.map +79 -0
- package/dist/microui.min.js +549 -0
- package/dist/microui.min.js.map +79 -0
- package/dist/routes/alerts.js +1 -0
- package/dist/routes/avatars.js +1 -0
- package/dist/routes/badges.js +1 -0
- package/dist/routes/buttons.js +1 -0
- package/dist/routes/callouts.js +1 -0
- package/dist/routes/cards.js +1 -0
- package/dist/routes/checkboxes.js +9 -0
- package/dist/routes/chips.js +4 -0
- package/dist/routes/chunk-19wgcncm.js +2 -0
- package/dist/routes/chunk-1khyr3v1.js +33 -0
- package/dist/routes/chunk-4rhxe97g.js +1 -0
- package/dist/routes/chunk-5qah04bh.js +2 -0
- package/dist/routes/chunk-7gfxy70n.js +5 -0
- package/dist/routes/chunk-e86zbeta.js +1 -0
- package/dist/routes/chunk-fagt36h6.js +2 -0
- package/dist/routes/chunk-fed7zr7m.js +1 -0
- package/dist/routes/chunk-hwj7pfwp.js +1 -0
- package/dist/routes/chunk-mhvcs2f8.js +5 -0
- package/dist/routes/chunk-nv3bddmj.js +13 -0
- package/dist/routes/chunk-q3f2aeqe.js +7 -0
- package/dist/routes/chunk-qxxa8trk.js +1 -0
- package/dist/routes/chunk-rw15y9zh.js +1 -0
- package/dist/routes/chunk-sfb7x11v.js +5 -0
- package/dist/routes/chunk-swyhghrm.js +48 -0
- package/dist/routes/chunk-sxddjs2d.js +2 -0
- package/dist/routes/chunk-vby0zg5w.js +17 -0
- package/dist/routes/chunk-w6zqjqqs.js +9 -0
- package/dist/routes/chunk-z960rexd.js +38 -0
- package/dist/routes/codeblocks.js +1 -0
- package/dist/routes/confirms.js +10 -0
- package/dist/routes/datatables.js +96 -0
- package/dist/routes/dividers.js +1 -0
- package/dist/routes/dropdowns.js +6 -0
- package/dist/routes/enterprise.js +15 -0
- package/dist/routes/home.js +1 -0
- package/dist/routes/icons.js +1 -0
- package/dist/routes/inputs.js +22 -0
- package/dist/routes/installation.js +1 -0
- package/dist/routes/layout.js +1 -0
- package/dist/routes/modals.js +1 -0
- package/dist/routes/navbar.js +1 -0
- package/dist/routes/page-components.json +316 -0
- package/dist/routes/progress.js +1 -0
- package/dist/routes/radios.js +6 -0
- package/dist/routes/route-deps.json +156 -0
- package/dist/routes/shell-critical.js +1 -0
- package/dist/routes/shell-deferred.js +1 -0
- package/dist/routes/shell.js +20 -0
- package/dist/routes/skeletons.js +13 -0
- package/dist/routes/spinners.js +1 -0
- package/dist/routes/src/chunks/core.js +36 -0
- package/dist/routes/switches.js +6 -0
- package/dist/routes/tables.js +1 -0
- package/dist/routes/tabs.js +1 -0
- package/dist/routes/toasts.js +1 -0
- package/dist/routes/tooltips.js +10 -0
- package/dist/routes/virtual-lists.js +33 -0
- package/dist/styles/common.css +1 -0
- package/dist/styles/components/animations.css +1 -0
- package/dist/styles/components/avatar.css +1 -0
- package/dist/styles/components/badge.css +1 -0
- package/dist/styles/components/bottom-nav.css +1 -0
- package/dist/styles/components/button.css +1 -0
- package/dist/styles/components/card.css +1 -0
- package/dist/styles/components/checkbox.css +1 -0
- package/dist/styles/components/chip.css +1 -0
- package/dist/styles/components/datatable.css +1 -0
- package/dist/styles/components/divider.css +1 -0
- package/dist/styles/components/drawer-item.css +1 -0
- package/dist/styles/components/drawer.css +1 -0
- package/dist/styles/components/grid.css +1 -0
- package/dist/styles/components/icon.css +1 -0
- package/dist/styles/components/input.css +1 -0
- package/dist/styles/components/layout.css +1 -0
- package/dist/styles/components/navbar.css +1 -0
- package/dist/styles/components/overlays.css +1 -0
- package/dist/styles/components/progress.css +1 -0
- package/dist/styles/components/prompt-ui.css +1 -0
- package/dist/styles/components/radio.css +1 -0
- package/dist/styles/components/schema-form.css +1 -0
- package/dist/styles/components/switch.css +1 -0
- package/dist/styles/components/tabs.css +1 -0
- package/dist/styles/components/tooltip.css +1 -0
- package/dist/styles/components/virtual-list.css +1 -0
- package/dist/tokens.css +1 -0
- package/docs/api-reference.md +175 -0
- package/docs/component-schema.md +231 -0
- package/docs/components.md +269 -0
- package/docs/design-system.md +183 -0
- package/docs/getting-started.md +198 -0
- package/docs/message-protocol.md +262 -0
- package/docs/utility-classes.md +205 -0
- package/lighthouse-audit.mjs +113 -0
- package/package.json +45 -0
- package/scripts/analyze-components.js +105 -0
- package/scripts/build-app.js +193 -0
- package/scripts/build-framework.js +444 -0
- package/scripts/build-utils.js +101 -0
- package/scripts/test-isolated.js +151 -0
- package/server.js +256 -0
- package/src/chunks/advanced.js +27 -0
- package/src/chunks/core.js +61 -0
- package/src/chunks/display.js +25 -0
- package/src/chunks/feedback.js +15 -0
- package/src/chunks/forms.js +25 -0
- package/src/chunks/layout.js +27 -0
- package/src/components/mu-alert.js +96 -0
- package/src/components/mu-api-table.js +167 -0
- package/src/components/mu-avatar.js +94 -0
- package/src/components/mu-badge.js +32 -0
- package/src/components/mu-bottom-nav.js +115 -0
- package/src/components/mu-button.js +61 -0
- package/src/components/mu-callout.js +71 -0
- package/src/components/mu-card.js +36 -0
- package/src/components/mu-checkbox.js +186 -0
- package/src/components/mu-chip.js +125 -0
- package/src/components/mu-code.js +534 -0
- package/src/components/mu-confirm.js +268 -0
- package/src/components/mu-container.js +53 -0
- package/src/components/mu-datatable.js +517 -0
- package/src/components/mu-divider.js +40 -0
- package/src/components/mu-doc-page.js +100 -0
- package/src/components/mu-drawer-item.js +158 -0
- package/src/components/mu-drawer.js +305 -0
- package/src/components/mu-dropdown.js +239 -0
- package/src/components/mu-error-boundary.js +191 -0
- package/src/components/mu-example.js +335 -0
- package/src/components/mu-fetch.js +256 -0
- package/src/components/mu-form.js +133 -0
- package/src/components/mu-grid.js +63 -0
- package/src/components/mu-icon.js +211 -0
- package/src/components/mu-input.js +142 -0
- package/src/components/mu-layout.js +129 -0
- package/src/components/mu-lazy.js +94 -0
- package/src/components/mu-modal.js +160 -0
- package/src/components/mu-navbar.js +71 -0
- package/src/components/mu-page.js +77 -0
- package/src/components/mu-progress.js +54 -0
- package/src/components/mu-prompt-ui.js +382 -0
- package/src/components/mu-radio.js +200 -0
- package/src/components/mu-repeat.js +135 -0
- package/src/components/mu-router.js +169 -0
- package/src/components/mu-schema-form.js +441 -0
- package/src/components/mu-sidebar.js +81 -0
- package/src/components/mu-skeleton.js +69 -0
- package/src/components/mu-spinner.js +30 -0
- package/src/components/mu-stack.js +59 -0
- package/src/components/mu-switch.js +150 -0
- package/src/components/mu-table.js +80 -0
- package/src/components/mu-tabs.js +112 -0
- package/src/components/mu-textarea.js +96 -0
- package/src/components/mu-theme-toggle.js +52 -0
- package/src/components/mu-toast.js +151 -0
- package/src/components/mu-tooltip.js +182 -0
- package/src/components/mu-virtual-list.js +184 -0
- package/src/core/MuElement.js +562 -0
- package/src/core/agent-api.js +771 -0
- package/src/core/breakpoints.js +195 -0
- package/src/core/bus.js +378 -0
- package/src/core/component-schema.js +287 -0
- package/src/core/feature-registry.js +241 -0
- package/src/core/form-state.js +252 -0
- package/src/core/http.js +104 -0
- package/src/core/keyboard.js +105 -0
- package/src/core/layers.js +71 -0
- package/src/core/render.js +201 -0
- package/src/core/ripple.js +158 -0
- package/src/core/router.js +100 -0
- package/src/core/scheduler.js +109 -0
- package/src/core/signals.js +164 -0
- package/src/core/store.js +268 -0
- package/src/core/theme.js +68 -0
- package/src/core/transitions.js +72 -0
- package/src/core/utils.js +30 -0
- package/src/index.d.ts +234 -0
- package/src/index.js +308 -0
- package/src/styles/animations.css +252 -0
- package/src/styles/common.css +82 -0
- package/src/styles/components/animations.css +129 -0
- package/src/styles/components/avatar.css +83 -0
- package/src/styles/components/badge.css +80 -0
- package/src/styles/components/bottom-nav.css +37 -0
- package/src/styles/components/button.css +348 -0
- package/src/styles/components/card.css +138 -0
- package/src/styles/components/checkbox.css +201 -0
- package/src/styles/components/chip.css +93 -0
- package/src/styles/components/datatable.css +180 -0
- package/src/styles/components/divider.css +49 -0
- package/src/styles/components/drawer-item.css +123 -0
- package/src/styles/components/drawer.css +273 -0
- package/src/styles/components/grid.css +189 -0
- package/src/styles/components/icon.css +40 -0
- package/src/styles/components/input.css +203 -0
- package/src/styles/components/layout.css +121 -0
- package/src/styles/components/navbar.css +91 -0
- package/src/styles/components/overlays.css +329 -0
- package/src/styles/components/progress.css +79 -0
- package/src/styles/components/prompt-ui.css +286 -0
- package/src/styles/components/radio.css +17 -0
- package/src/styles/components/schema-form.css +85 -0
- package/src/styles/components/switch.css +69 -0
- package/src/styles/components/tabs.css +145 -0
- package/src/styles/components/tooltip.css +93 -0
- package/src/styles/components/virtual-list.css +36 -0
- package/src/styles/components.css +3677 -0
- package/src/styles/routes/home.css +97 -0
- package/src/styles/tokens.css +675 -0
- package/tests/agents/agent-integration.test.js +76 -0
- package/tests/benchmark.html +296 -0
- package/tests/build/scan-components.test.js +173 -0
- package/tests/components/all-components.test.js +245 -0
- package/tests/components/all-missing-components.test.js +574 -0
- package/tests/components/mu-alert.test.js +113 -0
- package/tests/components/mu-avatar.test.js +148 -0
- package/tests/components/mu-badge.test.js +92 -0
- package/tests/components/mu-button.test.js +112 -0
- package/tests/components/mu-card.test.js +89 -0
- package/tests/components/mu-checkbox.test.js +158 -0
- package/tests/components/mu-chip.test.js +118 -0
- package/tests/components/mu-container.test.js +120 -0
- package/tests/components/mu-divider.test.js +98 -0
- package/tests/components/mu-drawer-item.test.js +199 -0
- package/tests/components/mu-drawer.test.js +96 -0
- package/tests/components/mu-dropdown.test.js +125 -0
- package/tests/components/mu-form.test.js +138 -0
- package/tests/components/mu-grid.test.js +135 -0
- package/tests/components/mu-icon.test.js +110 -0
- package/tests/components/mu-input.test.js +131 -0
- package/tests/components/mu-lazy.test.js +103 -0
- package/tests/components/mu-modal.test.js +275 -0
- package/tests/components/mu-navbar.test.js +101 -0
- package/tests/components/mu-progress.test.js +115 -0
- package/tests/components/mu-radio.test.js +114 -0
- package/tests/components/mu-repeat.test.js +106 -0
- package/tests/components/mu-sidebar.test.js +126 -0
- package/tests/components/mu-skeleton.test.js +162 -0
- package/tests/components/mu-stack.test.js +143 -0
- package/tests/components/mu-switch.test.js +292 -0
- package/tests/components/mu-table.test.js +124 -0
- package/tests/components/mu-tabs.test.js +104 -0
- package/tests/components/mu-textarea.test.js +115 -0
- package/tests/components/mu-toast.test.js +321 -0
- package/tests/components/mu-tooltip.test.js +133 -0
- package/tests/components/mu-virtual-list.test.js +109 -0
- package/tests/core/MuElement.test.js +120 -0
- package/tests/core/agent-api.test.js +125 -0
- package/tests/core/all-core-modules.test.js +442 -0
- package/tests/core/bus.test.js +364 -0
- package/tests/core/component-schema.test.js +160 -0
- package/tests/core/feature-registry.test.js +198 -0
- package/tests/core/form-state.test.js +167 -0
- package/tests/core/http.test.js +119 -0
- package/tests/core/keyboard.test.js +319 -0
- package/tests/core/layers.test.js +129 -0
- package/tests/core/namespaced-stores.test.js +114 -0
- package/tests/core/render.test.js +121 -0
- package/tests/core/ripple.test.js +131 -0
- package/tests/core/router.test.js +89 -0
- package/tests/core/scheduler.test.js +121 -0
- package/tests/core/signals.test.js +128 -0
- package/tests/core/store.test.js +171 -0
- package/tests/core/transitions.test.js +82 -0
- package/tests/e2e/accessibility-harness.html +58 -0
- package/tests/e2e/accessibility.test.js +401 -0
- package/tests/e2e/agent-features.test.js +372 -0
- package/tests/e2e/card-spacing.test.js +287 -0
- package/tests/e2e/components.test.js +439 -0
- package/tests/e2e/demo-routes.test.js +478 -0
- package/tests/e2e/layout-css-fallback.test.js +334 -0
- package/tests/e2e/mu-alert.e2e.test.js +111 -0
- package/tests/e2e/mu-checkbox.test.js +489 -0
- package/tests/e2e/mu-chip.test.js +347 -0
- package/tests/e2e/mu-form.test.js +499 -0
- package/tests/e2e/mu-icon.test.js +114 -0
- package/tests/e2e/mu-radio.test.js +113 -0
- package/tests/e2e/mu-skeleton.test.js +140 -0
- package/tests/e2e/mu-switch.test.js +415 -0
- package/tests/e2e/mu-tabs.test.js +494 -0
- package/tests/e2e/mu-textarea.test.js +242 -0
- package/tests/e2e/mu-virtual-list.test.js +427 -0
- package/tests/e2e/perf-memory.test.js +161 -0
- package/tests/e2e/puppeteer-helper.js +137 -0
- package/tests/e2e/puppeteer.test.js +226 -0
- package/tests/e2e/pwa.test.js +261 -0
- package/tests/e2e/test-harness.html +319 -0
- package/tests/manual/test-components.html +120 -0
- package/tests/memory-test.html +309 -0
- package/tests/setup-dom.js +93 -0
- 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><script>alert("xss")</script></div>
|
|
21
|
+
*/
|
|
22
|
+
export function escapeHTML(str) {
|
|
23
|
+
if (str == null) return '';
|
|
24
|
+
return String(str)
|
|
25
|
+
.replace(/&/g, '&')
|
|
26
|
+
.replace(/</g, '<')
|
|
27
|
+
.replace(/>/g, '>')
|
|
28
|
+
.replace(/"/g, '"')
|
|
29
|
+
.replace(/'/g, ''');
|
|
30
|
+
}
|