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,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Render Utilities for Large-Scale Applications
|
|
3
|
+
*
|
|
4
|
+
* Optimizes rendering for complex apps with thousands of components.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - requestAnimationFrame batching
|
|
8
|
+
* - Lazy component rendering
|
|
9
|
+
* - Intersection Observer for viewport-based rendering
|
|
10
|
+
* - Memoization for expensive computations
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Batch multiple DOM updates into single animation frame
|
|
15
|
+
* Prevents layout thrashing in complex updates
|
|
16
|
+
*/
|
|
17
|
+
class RenderScheduler {
|
|
18
|
+
#queue = [];
|
|
19
|
+
#scheduled = false;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Schedule a render callback for next animation frame
|
|
23
|
+
* Multiple calls are batched together
|
|
24
|
+
*/
|
|
25
|
+
schedule(callback) {
|
|
26
|
+
this.#queue.push(callback);
|
|
27
|
+
|
|
28
|
+
if (!this.#scheduled) {
|
|
29
|
+
this.#scheduled = true;
|
|
30
|
+
requestAnimationFrame(() => this.#flush());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#flush() {
|
|
35
|
+
const callbacks = this.#queue.slice();
|
|
36
|
+
this.#queue = [];
|
|
37
|
+
this.#scheduled = false;
|
|
38
|
+
|
|
39
|
+
// Execute all callbacks in single frame
|
|
40
|
+
for (const cb of callbacks) {
|
|
41
|
+
try {
|
|
42
|
+
cb();
|
|
43
|
+
} catch (e) {
|
|
44
|
+
console.error('[RenderScheduler] Error:', e);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const scheduler = new RenderScheduler();
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Memoize expensive function calls
|
|
54
|
+
* @param {Function} fn - Function to memoize
|
|
55
|
+
* @param {Function} keyFn - Optional key function for cache
|
|
56
|
+
*/
|
|
57
|
+
export function memo(fn, keyFn = JSON.stringify) {
|
|
58
|
+
const cache = new Map();
|
|
59
|
+
|
|
60
|
+
return (...args) => {
|
|
61
|
+
const key = keyFn(args);
|
|
62
|
+
|
|
63
|
+
if (cache.has(key)) {
|
|
64
|
+
return cache.get(key);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const result = fn(...args);
|
|
68
|
+
cache.set(key, result);
|
|
69
|
+
return result;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Debounce function calls
|
|
75
|
+
* @param {Function} fn
|
|
76
|
+
* @param {number} delay - Delay in ms
|
|
77
|
+
*/
|
|
78
|
+
export function debounce(fn, delay = 100) {
|
|
79
|
+
let timer = null;
|
|
80
|
+
|
|
81
|
+
return (...args) => {
|
|
82
|
+
if (timer) clearTimeout(timer);
|
|
83
|
+
timer = setTimeout(() => fn(...args), delay);
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Throttle function calls
|
|
89
|
+
* @param {Function} fn
|
|
90
|
+
* @param {number} limit - Minimum time between calls in ms
|
|
91
|
+
*/
|
|
92
|
+
export function throttle(fn, limit = 100) {
|
|
93
|
+
let inThrottle = false;
|
|
94
|
+
|
|
95
|
+
return (...args) => {
|
|
96
|
+
if (!inThrottle) {
|
|
97
|
+
fn(...args);
|
|
98
|
+
inThrottle = true;
|
|
99
|
+
setTimeout(() => inThrottle = false, limit);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Create an intersection observer for lazy rendering
|
|
106
|
+
* @param {Function} onVisible - Called when element becomes visible
|
|
107
|
+
* @param {Object} options - IntersectionObserver options
|
|
108
|
+
*/
|
|
109
|
+
export function createVisibilityObserver(onVisible, options = {}) {
|
|
110
|
+
const observer = new IntersectionObserver((entries) => {
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
if (entry.isIntersecting) {
|
|
113
|
+
onVisible(entry.target);
|
|
114
|
+
observer.unobserve(entry.target);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}, {
|
|
118
|
+
rootMargin: '100px',
|
|
119
|
+
threshold: 0,
|
|
120
|
+
...options
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
observe: (el) => observer.observe(el),
|
|
125
|
+
disconnect: () => observer.disconnect()
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Batch DOM reads and writes to prevent layout thrashing
|
|
131
|
+
* Based on fastdom pattern
|
|
132
|
+
*/
|
|
133
|
+
class DomBatch {
|
|
134
|
+
#reads = [];
|
|
135
|
+
#writes = [];
|
|
136
|
+
#scheduled = false;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Schedule a DOM read (measure)
|
|
140
|
+
*/
|
|
141
|
+
read(fn) {
|
|
142
|
+
this.#reads.push(fn);
|
|
143
|
+
this.#schedule();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Schedule a DOM write (mutate)
|
|
148
|
+
*/
|
|
149
|
+
write(fn) {
|
|
150
|
+
this.#writes.push(fn);
|
|
151
|
+
this.#schedule();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
#schedule() {
|
|
155
|
+
if (!this.#scheduled) {
|
|
156
|
+
this.#scheduled = true;
|
|
157
|
+
requestAnimationFrame(() => this.#flush());
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
#flush() {
|
|
162
|
+
// Reads first (measure phase)
|
|
163
|
+
let fn;
|
|
164
|
+
while (fn = this.#reads.shift()) {
|
|
165
|
+
try { fn(); } catch (e) { console.error(e); }
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Writes second (mutate phase)
|
|
169
|
+
while (fn = this.#writes.shift()) {
|
|
170
|
+
try { fn(); } catch (e) { console.error(e); }
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
this.#scheduled = false;
|
|
174
|
+
|
|
175
|
+
// If more work was added during flush, schedule again
|
|
176
|
+
if (this.#reads.length || this.#writes.length) {
|
|
177
|
+
this.#schedule();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export const domBatch = new DomBatch();
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Chunk large array operations to avoid blocking main thread
|
|
186
|
+
* @param {Array} items - Array to process
|
|
187
|
+
* @param {Function} processFn - Function to call for each item
|
|
188
|
+
* @param {number} chunkSize - Items per chunk
|
|
189
|
+
*/
|
|
190
|
+
export async function processInChunks(items, processFn, chunkSize = 100) {
|
|
191
|
+
for (let i = 0; i < items.length; i += chunkSize) {
|
|
192
|
+
const chunk = items.slice(i, i + chunkSize);
|
|
193
|
+
|
|
194
|
+
for (const item of chunk) {
|
|
195
|
+
processFn(item, i);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Yield to main thread between chunks
|
|
199
|
+
await new Promise(r => setTimeout(r, 0));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MD3 Ripple Effect Utility
|
|
3
|
+
*
|
|
4
|
+
* Creates Material Design 3 compliant ripple effects on interactive elements.
|
|
5
|
+
* The ripple originates from the exact click/touch point and expands outward.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { attachRipple } from './core/ripple.js';
|
|
9
|
+
* attachRipple(element);
|
|
10
|
+
*
|
|
11
|
+
* Or for controlled ripple:
|
|
12
|
+
* import { createRipple } from './core/ripple.js';
|
|
13
|
+
* element.addEventListener('click', (e) => createRipple(element, e));
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Create a ripple effect at the event position within the element.
|
|
18
|
+
* MD3 behavior: ripple expands immediately, persists while pressed, fades on release.
|
|
19
|
+
* @param {HTMLElement} element - Container element for the ripple
|
|
20
|
+
* @param {MouseEvent|TouchEvent} event - The triggering event
|
|
21
|
+
* @param {Object} options - Ripple options
|
|
22
|
+
* @param {string} options.color - Ripple color (default: currentColor)
|
|
23
|
+
* @param {boolean} options.centered - Force ripple to start from center
|
|
24
|
+
*/
|
|
25
|
+
export function createRipple(element, event, options = {}) {
|
|
26
|
+
const { color = 'currentColor', centered = false } = options;
|
|
27
|
+
|
|
28
|
+
// Get element bounds
|
|
29
|
+
const rect = element.getBoundingClientRect();
|
|
30
|
+
|
|
31
|
+
// Calculate ripple position (from click point or center)
|
|
32
|
+
let x, y;
|
|
33
|
+
if (centered || !event) {
|
|
34
|
+
x = rect.width / 2;
|
|
35
|
+
y = rect.height / 2;
|
|
36
|
+
} else {
|
|
37
|
+
// Get click/touch position
|
|
38
|
+
const clientX = event.touches ? event.touches[0].clientX : event.clientX;
|
|
39
|
+
const clientY = event.touches ? event.touches[0].clientY : event.clientY;
|
|
40
|
+
x = clientX - rect.left;
|
|
41
|
+
y = clientY - rect.top;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Calculate ripple size (must cover entire element from click point)
|
|
45
|
+
const size = Math.max(
|
|
46
|
+
Math.hypot(x, y),
|
|
47
|
+
Math.hypot(rect.width - x, y),
|
|
48
|
+
Math.hypot(x, rect.height - y),
|
|
49
|
+
Math.hypot(rect.width - x, rect.height - y)
|
|
50
|
+
) * 2;
|
|
51
|
+
|
|
52
|
+
// Create ripple element
|
|
53
|
+
const ripple = document.createElement('span');
|
|
54
|
+
ripple.className = 'mu-ripple-wave';
|
|
55
|
+
ripple.style.cssText = `
|
|
56
|
+
position: absolute;
|
|
57
|
+
width: ${size}px;
|
|
58
|
+
height: ${size}px;
|
|
59
|
+
left: ${x - size / 2}px;
|
|
60
|
+
top: ${y - size / 2}px;
|
|
61
|
+
background: ${color};
|
|
62
|
+
border-radius: 50%;
|
|
63
|
+
transform: scale(0);
|
|
64
|
+
opacity: 0.10;
|
|
65
|
+
pointer-events: none;
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
// Ensure container has proper positioning
|
|
69
|
+
const computedStyle = getComputedStyle(element);
|
|
70
|
+
if (computedStyle.position === 'static') {
|
|
71
|
+
element.style.position = 'relative';
|
|
72
|
+
}
|
|
73
|
+
if (computedStyle.overflow !== 'hidden') {
|
|
74
|
+
element.style.overflow = 'hidden';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Add ripple to element
|
|
78
|
+
element.appendChild(ripple);
|
|
79
|
+
|
|
80
|
+
// Phase 1: Expand animation (GPU - transform only)
|
|
81
|
+
ripple.animate([
|
|
82
|
+
{ transform: 'scale(0)' },
|
|
83
|
+
{ transform: 'scale(1)' }
|
|
84
|
+
], {
|
|
85
|
+
duration: 300,
|
|
86
|
+
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
87
|
+
fill: 'forwards'
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Phase 2: Fade out on release (pointer up or leave)
|
|
91
|
+
const fadeOut = () => {
|
|
92
|
+
ripple.animate([
|
|
93
|
+
{ opacity: '0.10' },
|
|
94
|
+
{ opacity: '0' }
|
|
95
|
+
], {
|
|
96
|
+
duration: 150,
|
|
97
|
+
easing: 'ease-out',
|
|
98
|
+
fill: 'forwards'
|
|
99
|
+
}).onfinish = () => ripple.remove();
|
|
100
|
+
|
|
101
|
+
// Cleanup listeners
|
|
102
|
+
element.removeEventListener('pointerup', fadeOut);
|
|
103
|
+
element.removeEventListener('pointerleave', fadeOut);
|
|
104
|
+
element.removeEventListener('pointercancel', fadeOut);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
element.addEventListener('pointerup', fadeOut, { once: true });
|
|
108
|
+
element.addEventListener('pointerleave', fadeOut, { once: true });
|
|
109
|
+
element.addEventListener('pointercancel', fadeOut, { once: true });
|
|
110
|
+
|
|
111
|
+
return ripple;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Attach ripple effect to an element.
|
|
116
|
+
* @param {HTMLElement} element - Element to attach ripple to
|
|
117
|
+
* @param {Object} options - Ripple options
|
|
118
|
+
* @returns {Function} Cleanup function to remove ripple listener
|
|
119
|
+
*/
|
|
120
|
+
export function attachRipple(element, options = {}) {
|
|
121
|
+
const handler = (e) => {
|
|
122
|
+
// Don't create ripple if element is disabled
|
|
123
|
+
if (element.hasAttribute('disabled')) return;
|
|
124
|
+
createRipple(element, e, options);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
element.addEventListener('pointerdown', handler);
|
|
128
|
+
|
|
129
|
+
// Return cleanup function
|
|
130
|
+
return () => {
|
|
131
|
+
element.removeEventListener('pointerdown', handler);
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Mixin for components that need ripple.
|
|
137
|
+
* Call this.initRipple(targetElement) in connectedCallback.
|
|
138
|
+
*/
|
|
139
|
+
export const RippleMixin = (superclass) => class extends superclass {
|
|
140
|
+
#rippleCleanup = null;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Initialize ripple on target element (or self).
|
|
144
|
+
* @param {HTMLElement} target - Element to add ripple to (defaults to this)
|
|
145
|
+
* @param {Object} options - Ripple options
|
|
146
|
+
*/
|
|
147
|
+
initRipple(target = this, options = {}) {
|
|
148
|
+
this.#rippleCleanup = attachRipple(target, options);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
disconnectedCallback() {
|
|
152
|
+
if (this.#rippleCleanup) {
|
|
153
|
+
this.#rippleCleanup();
|
|
154
|
+
this.#rippleCleanup = null;
|
|
155
|
+
}
|
|
156
|
+
super.disconnectedCallback?.();
|
|
157
|
+
}
|
|
158
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Simple SPA Router for microUI
|
|
3
|
+
*
|
|
4
|
+
* Hash-based routing for single page applications.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* Router.on('/', () => renderHome());
|
|
8
|
+
* Router.on('/about', () => renderAbout());
|
|
9
|
+
* Router.on('/user/:id', ({ id }) => renderUser(id));
|
|
10
|
+
* Router.start();
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
class RouterClass {
|
|
14
|
+
#routes = [];
|
|
15
|
+
#notFound = null;
|
|
16
|
+
#currentPath = '';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Register a route
|
|
20
|
+
* @param {string} path - Route path (supports :param)
|
|
21
|
+
* @param {(params: Object) => void} handler
|
|
22
|
+
*/
|
|
23
|
+
on(path, handler) {
|
|
24
|
+
// Convert path params to regex
|
|
25
|
+
const pattern = path
|
|
26
|
+
.replace(/:[a-zA-Z]+/g, '([^/]+)')
|
|
27
|
+
.replace(/\//g, '\\/');
|
|
28
|
+
|
|
29
|
+
const paramNames = (path.match(/:[a-zA-Z]+/g) || [])
|
|
30
|
+
.map(p => p.slice(1));
|
|
31
|
+
|
|
32
|
+
this.#routes.push({
|
|
33
|
+
path,
|
|
34
|
+
pattern: new RegExp(`^${pattern}$`),
|
|
35
|
+
paramNames,
|
|
36
|
+
handler
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Set 404 handler
|
|
44
|
+
*/
|
|
45
|
+
notFound(handler) {
|
|
46
|
+
this.#notFound = handler;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Navigate to a path
|
|
52
|
+
* @param {string} path
|
|
53
|
+
*/
|
|
54
|
+
navigate(path) {
|
|
55
|
+
window.location.hash = path;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get current path
|
|
60
|
+
*/
|
|
61
|
+
get current() {
|
|
62
|
+
return this.#currentPath;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Start the router
|
|
67
|
+
*/
|
|
68
|
+
start() {
|
|
69
|
+
const handleRoute = () => {
|
|
70
|
+
const hash = window.location.hash.slice(1) || '/';
|
|
71
|
+
this.#currentPath = hash;
|
|
72
|
+
|
|
73
|
+
for (const route of this.#routes) {
|
|
74
|
+
const match = hash.match(route.pattern);
|
|
75
|
+
if (match) {
|
|
76
|
+
// Extract params
|
|
77
|
+
const params = {};
|
|
78
|
+
route.paramNames.forEach((name, i) => {
|
|
79
|
+
params[name] = match[i + 1];
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
route.handler(params);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// No match - 404
|
|
88
|
+
if (this.#notFound) {
|
|
89
|
+
this.#notFound(hash);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
window.addEventListener('hashchange', handleRoute);
|
|
94
|
+
handleRoute(); // Handle initial route
|
|
95
|
+
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const Router = new RouterClass();
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Task Scheduler API (2026 SOTA)
|
|
3
|
+
*
|
|
4
|
+
* Uses scheduler.postTask() for priority-based scheduling.
|
|
5
|
+
* Falls back to setTimeout if not supported.
|
|
6
|
+
*
|
|
7
|
+
* Priority levels:
|
|
8
|
+
* - 'user-blocking': Highest priority (input handlers)
|
|
9
|
+
* - 'user-visible': Medium priority (rendering)
|
|
10
|
+
* - 'background': Lowest priority (analytics, prefetch)
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* await scheduleTask(() => heavyComputation(), 'background');
|
|
14
|
+
* await yieldToMain();
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check if Scheduler API is supported
|
|
19
|
+
*/
|
|
20
|
+
export const supportsScheduler = 'scheduler' in globalThis;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Schedule a task with priority
|
|
24
|
+
* @param {() => T} callback
|
|
25
|
+
* @param {'user-blocking' | 'user-visible' | 'background'} priority
|
|
26
|
+
* @returns {Promise<T>}
|
|
27
|
+
*/
|
|
28
|
+
export async function scheduleTask(callback, priority = 'user-visible') {
|
|
29
|
+
if (supportsScheduler) {
|
|
30
|
+
return globalThis.scheduler.postTask(callback, { priority });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Fallback with setTimeout based on priority
|
|
34
|
+
const delay = priority === 'user-blocking' ? 0 :
|
|
35
|
+
priority === 'user-visible' ? 0 : 1;
|
|
36
|
+
|
|
37
|
+
return new Promise(resolve => {
|
|
38
|
+
setTimeout(() => resolve(callback()), delay);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Yield to main thread (allow input/rendering)
|
|
44
|
+
* @returns {Promise<void>}
|
|
45
|
+
*/
|
|
46
|
+
export async function yieldToMain() {
|
|
47
|
+
if (supportsScheduler && 'yield' in globalThis.scheduler) {
|
|
48
|
+
return globalThis.scheduler.yield();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Fallback: yield with setTimeout
|
|
52
|
+
return new Promise(resolve => setTimeout(resolve, 0));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Process items in chunks, yielding between chunks
|
|
57
|
+
* Better than processInChunks because it uses scheduler.yield()
|
|
58
|
+
*
|
|
59
|
+
* @param {T[]} items
|
|
60
|
+
* @param {(item: T, index: number) => void} process
|
|
61
|
+
* @param {number} chunkSize
|
|
62
|
+
*/
|
|
63
|
+
export async function processWithYield(items, process, chunkSize = 50) {
|
|
64
|
+
for (let i = 0; i < items.length; i++) {
|
|
65
|
+
process(items[i], i);
|
|
66
|
+
|
|
67
|
+
// Yield every chunk
|
|
68
|
+
if ((i + 1) % chunkSize === 0) {
|
|
69
|
+
await yieldToMain();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Run background task (lowest priority, won't block UI)
|
|
76
|
+
* @param {() => T} callback
|
|
77
|
+
* @returns {Promise<T>}
|
|
78
|
+
*/
|
|
79
|
+
export function runBackground(callback) {
|
|
80
|
+
return scheduleTask(callback, 'background');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Run user-blocking task (highest priority)
|
|
85
|
+
* @param {() => T} callback
|
|
86
|
+
* @returns {Promise<T>}
|
|
87
|
+
*/
|
|
88
|
+
export function runImmediate(callback) {
|
|
89
|
+
return scheduleTask(callback, 'user-blocking');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Wait for next browser paint (double-rAF pattern)
|
|
94
|
+
* Use for CSS animation triggers after DOM changes.
|
|
95
|
+
* This ensures the browser has completed layout/paint before applying
|
|
96
|
+
* additional classes that would trigger transitions.
|
|
97
|
+
*
|
|
98
|
+
* @returns {Promise<void>}
|
|
99
|
+
* @example
|
|
100
|
+
* // Trigger CSS animation after DOM change
|
|
101
|
+
* element.classList.add('is-open');
|
|
102
|
+
* await afterPaint();
|
|
103
|
+
* element.classList.add('is-visible'); // Now transition will animate
|
|
104
|
+
*/
|
|
105
|
+
export function afterPaint() {
|
|
106
|
+
return new Promise(resolve => {
|
|
107
|
+
requestAnimationFrame(() => requestAnimationFrame(resolve));
|
|
108
|
+
});
|
|
109
|
+
}
|