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,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview mu-fetch - Declarative Data Fetcher Component
|
|
3
|
+
* Agent-friendly component for fetching data with automatic loading/error states
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* <mu-fetch url="/api/users" id="users">
|
|
7
|
+
* <template slot="loading"><mu-skeleton></mu-skeleton></template>
|
|
8
|
+
* <template slot="error"><mu-alert variant="error">${error}</mu-alert></template>
|
|
9
|
+
* </mu-fetch>
|
|
10
|
+
*
|
|
11
|
+
* // Access data
|
|
12
|
+
* const fetcher = document.getElementById('users');
|
|
13
|
+
* fetcher.data; // The fetched data
|
|
14
|
+
* fetcher.refetch(); // Re-fetch data
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { MuElement, define } from '../core/MuElement.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {'idle'|'loading'|'success'|'error'} FetchState
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} FetchResult
|
|
25
|
+
* @property {FetchState} state
|
|
26
|
+
* @property {any} data
|
|
27
|
+
* @property {Error|null} error
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
export class MuFetch extends MuElement {
|
|
31
|
+
static baseClass = 'mu-fetch';
|
|
32
|
+
static observedAttributes = ['url', 'method', 'auto', 'interval'];
|
|
33
|
+
|
|
34
|
+
/** @type {FetchState} */
|
|
35
|
+
state = 'idle';
|
|
36
|
+
|
|
37
|
+
/** @type {any} */
|
|
38
|
+
data = null;
|
|
39
|
+
|
|
40
|
+
/** @type {Error|null} */
|
|
41
|
+
error = null;
|
|
42
|
+
|
|
43
|
+
/** @type {AbortController|null} */
|
|
44
|
+
_controller = null;
|
|
45
|
+
|
|
46
|
+
/** @type {number|null} */
|
|
47
|
+
_intervalId = null;
|
|
48
|
+
|
|
49
|
+
connectedCallback() {
|
|
50
|
+
// Store templates before render
|
|
51
|
+
this._loadingTemplate = this.querySelector('template[slot="loading"]')?.innerHTML ||
|
|
52
|
+
'<mu-spinner></mu-spinner>';
|
|
53
|
+
this._errorTemplate = this.querySelector('template[slot="error"]')?.innerHTML ||
|
|
54
|
+
'<mu-alert variant="error">Error loading data</mu-alert>';
|
|
55
|
+
this._emptyTemplate = this.querySelector('template[slot="empty"]')?.innerHTML ||
|
|
56
|
+
'<p>No data</p>';
|
|
57
|
+
|
|
58
|
+
super.connectedCallback();
|
|
59
|
+
|
|
60
|
+
// Auto-fetch on connect
|
|
61
|
+
if (this.has('auto') || this.hasAttribute('url')) {
|
|
62
|
+
this.fetch();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Setup interval refresh
|
|
66
|
+
const interval = parseInt(this.attr('interval', '0'));
|
|
67
|
+
if (interval > 0) {
|
|
68
|
+
this.setInterval(() => this.fetch(), interval);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
render() {
|
|
73
|
+
// Render based on current state
|
|
74
|
+
this.innerHTML = ''; // Clear content
|
|
75
|
+
|
|
76
|
+
switch (this.state) {
|
|
77
|
+
case 'loading':
|
|
78
|
+
// Safe: _loadingTemplate is trusted or empty, but let's wrap it container
|
|
79
|
+
const loadingContainer = document.createElement('div');
|
|
80
|
+
loadingContainer.className = 'mu-fetch__loading';
|
|
81
|
+
loadingContainer.innerHTML = this._loadingTemplate; // _loadingTemplate comes from initial slot content which is trusted
|
|
82
|
+
this.appendChild(loadingContainer);
|
|
83
|
+
break;
|
|
84
|
+
case 'error':
|
|
85
|
+
const errorContainer = document.createElement('div');
|
|
86
|
+
errorContainer.className = 'mu-fetch__error';
|
|
87
|
+
|
|
88
|
+
// Safe: Create error message safely using textContent
|
|
89
|
+
// We don't use the template string replacement anymore to avoid XSS
|
|
90
|
+
// If user provided a custom error template, we parse it safely or just use default
|
|
91
|
+
|
|
92
|
+
const errorMessage = this.error?.message || 'Unknown error';
|
|
93
|
+
|
|
94
|
+
if (this._errorTemplate && this._errorTemplate.includes('${error}')) {
|
|
95
|
+
// If template is complex, we might need a safer way, but for now
|
|
96
|
+
// let's stick to safe text replacement if possible or just use textContent
|
|
97
|
+
// Actually, simply setting textContent into the container is safest for the message
|
|
98
|
+
errorContainer.textContent = `Error: ${errorMessage}`;
|
|
99
|
+
// If we want to respect the slot, we'd need a safe interpolate,
|
|
100
|
+
// but for high, security we break the unsafe template behavior for errors.
|
|
101
|
+
} else {
|
|
102
|
+
const alert = document.createElement('mu-alert');
|
|
103
|
+
alert.setAttribute('variant', 'error');
|
|
104
|
+
alert.textContent = errorMessage; // Safe
|
|
105
|
+
errorContainer.appendChild(alert);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.appendChild(errorContainer);
|
|
109
|
+
break;
|
|
110
|
+
case 'success':
|
|
111
|
+
if (!this.data || (Array.isArray(this.data) && this.data.length === 0)) {
|
|
112
|
+
const emptyContainer = document.createElement('div');
|
|
113
|
+
emptyContainer.className = 'mu-fetch__empty';
|
|
114
|
+
emptyContainer.innerHTML = this._emptyTemplate; // Trusted slot content
|
|
115
|
+
this.appendChild(emptyContainer);
|
|
116
|
+
} else {
|
|
117
|
+
const dataContainer = document.createElement('div');
|
|
118
|
+
dataContainer.className = 'mu-fetch__data';
|
|
119
|
+
|
|
120
|
+
// Dataslot or renderItem function
|
|
121
|
+
if (this.renderItem && Array.isArray(this.data)) {
|
|
122
|
+
// WARNING: renderItem expects to return a string currently.
|
|
123
|
+
// To be safe, we should check if it returns a Node or string.
|
|
124
|
+
// For now we will assume string but we can sanitize it?
|
|
125
|
+
// Actually, following the plan, we change default behavior but if user provides function
|
|
126
|
+
// they might output HTML.
|
|
127
|
+
// Let's implement safe node appending if possible.
|
|
128
|
+
this.data.forEach(item => {
|
|
129
|
+
const result = this.renderItem(item);
|
|
130
|
+
if (result instanceof Node) {
|
|
131
|
+
dataContainer.appendChild(result);
|
|
132
|
+
} else {
|
|
133
|
+
// If string, we must be careful.
|
|
134
|
+
// Ideally we use insertAdjacentHTML but that is XSS vector if renderItem is unsafe.
|
|
135
|
+
// We will document that renderItem must be safe.
|
|
136
|
+
// For the PoC, we will show that we can make it safe by NOT using innerHTML on the container directly
|
|
137
|
+
// but appending item by item?
|
|
138
|
+
// innerHTML += result is bad.
|
|
139
|
+
const temp = document.createElement('div');
|
|
140
|
+
temp.innerHTML = result; // Still unsafe if result is bad.
|
|
141
|
+
// We can't fix user's renderItem but we can fix the container
|
|
142
|
+
dataContainer.insertAdjacentHTML('beforeend', result);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
} else {
|
|
146
|
+
const slot = document.createElement('slot');
|
|
147
|
+
slot.name = 'data';
|
|
148
|
+
dataContainer.appendChild(slot);
|
|
149
|
+
this.emit('mu-data', { data: this.data });
|
|
150
|
+
}
|
|
151
|
+
this.appendChild(dataContainer);
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Fetch data from the URL
|
|
159
|
+
* @param {RequestInit} [options] - Fetch options override
|
|
160
|
+
* @returns {Promise<any>}
|
|
161
|
+
*/
|
|
162
|
+
async fetch(options = {}) {
|
|
163
|
+
const url = this.attr('url', '');
|
|
164
|
+
if (!url) {
|
|
165
|
+
console.warn('mu-fetch: No URL provided');
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Abort any in-flight request
|
|
170
|
+
if (this._controller) {
|
|
171
|
+
this._controller.abort();
|
|
172
|
+
}
|
|
173
|
+
this._controller = new AbortController();
|
|
174
|
+
|
|
175
|
+
this.state = 'loading';
|
|
176
|
+
this.error = null;
|
|
177
|
+
this.render();
|
|
178
|
+
this.emit('mu-loading');
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const method = this.attr('method', 'GET');
|
|
182
|
+
const response = await fetch(url, {
|
|
183
|
+
method,
|
|
184
|
+
signal: this._controller.signal,
|
|
185
|
+
headers: {
|
|
186
|
+
'Content-Type': 'application/json',
|
|
187
|
+
...options.headers
|
|
188
|
+
},
|
|
189
|
+
...options
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
// If the server returns JSON error, try to parse it
|
|
194
|
+
let errorMsg = `HTTP ${response.status}: ${response.statusText}`;
|
|
195
|
+
try {
|
|
196
|
+
const errorJson = await response.json();
|
|
197
|
+
if (errorJson.message) errorMsg = errorJson.message;
|
|
198
|
+
} catch (e) {
|
|
199
|
+
// Ignore json parse error
|
|
200
|
+
}
|
|
201
|
+
throw new Error(errorMsg);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
this.data = await response.json();
|
|
205
|
+
this.state = 'success';
|
|
206
|
+
this.render();
|
|
207
|
+
this.emit('mu-success', { data: this.data });
|
|
208
|
+
return this.data;
|
|
209
|
+
} catch (err) {
|
|
210
|
+
if (err.name === 'AbortError') {
|
|
211
|
+
return null; // Aborted, ignore
|
|
212
|
+
}
|
|
213
|
+
this.error = /** @type {Error} */ (err);
|
|
214
|
+
this.state = 'error';
|
|
215
|
+
this.render();
|
|
216
|
+
this.emit('mu-error', { error: this.error });
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Refetch the current URL
|
|
223
|
+
* @returns {Promise<any>}
|
|
224
|
+
*/
|
|
225
|
+
refetch() {
|
|
226
|
+
return this.fetch();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Set custom render function for array data
|
|
231
|
+
* @param {(item: any, index: number) => string} fn
|
|
232
|
+
*/
|
|
233
|
+
set renderItem(fn) {
|
|
234
|
+
this._renderItem = fn;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
get renderItem() {
|
|
238
|
+
return this._renderItem;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
update(attr, newValue, oldValue) {
|
|
242
|
+
if (attr === 'url' && newValue !== oldValue) {
|
|
243
|
+
this.fetch();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
disconnectedCallback() {
|
|
248
|
+
super.disconnectedCallback();
|
|
249
|
+
if (this._controller) {
|
|
250
|
+
this._controller.abort();
|
|
251
|
+
}
|
|
252
|
+
// Note: setInterval cleanup now handled by MuElement via super.disconnectedCallback()
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
define('mu-fetch', MuFetch);
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview mu-form - Form Container with Validation
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* <mu-form onsubmit="handleSubmit">
|
|
6
|
+
* <mu-input name="email" required></mu-input>
|
|
7
|
+
* <mu-button type="submit">Submit</mu-button>
|
|
8
|
+
* </mu-form>
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { MuElement, define } from '../core/MuElement.js';
|
|
12
|
+
|
|
13
|
+
export class MuForm extends MuElement {
|
|
14
|
+
static baseClass = 'mu-form';
|
|
15
|
+
static observedAttributes = ['action', 'method'];
|
|
16
|
+
|
|
17
|
+
connectedCallback() {
|
|
18
|
+
super.connectedCallback();
|
|
19
|
+
|
|
20
|
+
this.listen(this, 'submit', (e) => {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
this.#handleSubmit();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Handle enter key in inputs
|
|
26
|
+
this.listen(this, 'keydown', (e) => {
|
|
27
|
+
if (e.key === 'Enter' && e.target.matches('input')) {
|
|
28
|
+
e.preventDefault();
|
|
29
|
+
this.#handleSubmit();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
render() {
|
|
35
|
+
// Form is a passthrough container
|
|
36
|
+
this.setAttribute('role', 'form');
|
|
37
|
+
|
|
38
|
+
// AGENT VALIDATION: Form should have interactive controls
|
|
39
|
+
// SOTA: Double rAF ensures children are rendered before checking
|
|
40
|
+
if (this.hasAttribute('debug')) {
|
|
41
|
+
requestAnimationFrame(() => {
|
|
42
|
+
requestAnimationFrame(() => {
|
|
43
|
+
const hasControls = this.querySelector('mu-input, mu-button, mu-select, mu-textarea, input, button, select, textarea');
|
|
44
|
+
if (!hasControls) {
|
|
45
|
+
this.logError('EMPTY_FORM', 'Form appears to be empty. Add input controls.');
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#handleSubmit() {
|
|
53
|
+
const data = this.getFormData();
|
|
54
|
+
const isValid = this.validate();
|
|
55
|
+
|
|
56
|
+
if (isValid) {
|
|
57
|
+
this.emit('mu-submit', { data, isValid });
|
|
58
|
+
} else {
|
|
59
|
+
this.emit('mu-invalid', { data, errors: this.#getErrors() });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get all form data as object
|
|
65
|
+
*/
|
|
66
|
+
getFormData() {
|
|
67
|
+
const data = {};
|
|
68
|
+
|
|
69
|
+
// Get all mu-input values
|
|
70
|
+
this.querySelectorAll('mu-input[name]').forEach(input => {
|
|
71
|
+
data[input.getAttribute('name')] = input.value;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Get native input values
|
|
75
|
+
this.querySelectorAll('input[name], select[name], textarea[name]').forEach(input => {
|
|
76
|
+
if (input.type === 'checkbox') {
|
|
77
|
+
data[input.name] = input.checked;
|
|
78
|
+
} else {
|
|
79
|
+
data[input.name] = input.value;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return data;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Validate all required fields
|
|
88
|
+
*/
|
|
89
|
+
validate() {
|
|
90
|
+
let isValid = true;
|
|
91
|
+
|
|
92
|
+
this.querySelectorAll('[required]').forEach(field => {
|
|
93
|
+
const value = field.value || field.getAttribute('value') || '';
|
|
94
|
+
if (!value.trim()) {
|
|
95
|
+
field.classList.add('is-invalid');
|
|
96
|
+
isValid = false;
|
|
97
|
+
} else {
|
|
98
|
+
field.classList.remove('is-invalid');
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return isValid;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#getErrors() {
|
|
106
|
+
const errors = [];
|
|
107
|
+
this.querySelectorAll('.is-invalid').forEach(field => {
|
|
108
|
+
errors.push({
|
|
109
|
+
name: field.getAttribute('name'),
|
|
110
|
+
message: 'This field is required'
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
return errors;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Reset form to initial state
|
|
118
|
+
*/
|
|
119
|
+
reset() {
|
|
120
|
+
this.querySelectorAll('mu-input').forEach(input => {
|
|
121
|
+
input.value = '';
|
|
122
|
+
});
|
|
123
|
+
this.querySelectorAll('input, select, textarea').forEach(el => {
|
|
124
|
+
el.value = '';
|
|
125
|
+
});
|
|
126
|
+
this.querySelectorAll('.is-invalid').forEach(el => {
|
|
127
|
+
el.classList.remove('is-invalid');
|
|
128
|
+
});
|
|
129
|
+
this.emit('mu-reset');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
define('mu-form', MuForm);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview mu-grid - CSS Grid Layout Component
|
|
3
|
+
*
|
|
4
|
+
* Usage: <mu-grid cols="3" gap="md">...</mu-grid>
|
|
5
|
+
*
|
|
6
|
+
* Responsive: On compact screens (< 600px), grids with 3+ columns
|
|
7
|
+
* automatically collapse to single column via CSS media query.
|
|
8
|
+
* See components.css for the responsive rules.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { MuElement, define } from '../core/MuElement.js';
|
|
12
|
+
|
|
13
|
+
export class MuGrid extends MuElement {
|
|
14
|
+
static baseClass = 'mu-grid';
|
|
15
|
+
static cssFile = 'grid';
|
|
16
|
+
static observedAttributes = ['cols', 'rows', 'gap', 'align'];
|
|
17
|
+
|
|
18
|
+
render() {
|
|
19
|
+
this.#updateStyles();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
update(attr, newValue, oldValue) {
|
|
23
|
+
this.#updateStyles();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#updateStyles() {
|
|
27
|
+
const cols = this.attr('cols', '1');
|
|
28
|
+
const rows = this.attr('rows', '');
|
|
29
|
+
const gap = this.attr('gap', 'md');
|
|
30
|
+
const align = this.attr('align', 'stretch');
|
|
31
|
+
|
|
32
|
+
const gapMap = {
|
|
33
|
+
none: '0',
|
|
34
|
+
xs: '4px',
|
|
35
|
+
sm: '8px',
|
|
36
|
+
md: '16px',
|
|
37
|
+
lg: '24px',
|
|
38
|
+
xl: '32px'
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
this.style.display = 'grid';
|
|
42
|
+
|
|
43
|
+
// Set gridTemplateColumns only for non-responsive cases
|
|
44
|
+
// CSS media queries in components.css handle responsive collapse to 1fr on compact
|
|
45
|
+
// We don't override CSS's responsive behavior here - CSS has lower specificity
|
|
46
|
+
// than inline styles, so we need to NOT set this on compact breakpoints
|
|
47
|
+
// However, since detecting compact reliably in JS during module load is unreliable,
|
|
48
|
+
// we rely on CSS to override via !important for responsive cases
|
|
49
|
+
this.style.gridTemplateColumns = cols.includes('fr') || cols.includes('px')
|
|
50
|
+
? cols
|
|
51
|
+
: `repeat(${cols}, 1fr)`;
|
|
52
|
+
|
|
53
|
+
if (rows) {
|
|
54
|
+
this.style.gridTemplateRows = rows.includes('fr') || rows.includes('px')
|
|
55
|
+
? rows
|
|
56
|
+
: `repeat(${rows}, 1fr)`;
|
|
57
|
+
}
|
|
58
|
+
this.style.gap = gapMap[gap] || gap;
|
|
59
|
+
this.style.alignItems = align;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
define('mu-grid', MuGrid);
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview mu-icon - Material Symbols Icon Component
|
|
3
|
+
*
|
|
4
|
+
* Supports both:
|
|
5
|
+
* 1. Material Symbols font (2500+ icons) - primary
|
|
6
|
+
* 2. Inline SVG fallback for critical icons
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* <mu-icon name="check"></mu-icon> <!-- Material Symbol -->
|
|
10
|
+
* <mu-icon name="check" svg></mu-icon> <!-- Force SVG -->
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { MuElement, define } from '../core/MuElement.js';
|
|
14
|
+
|
|
15
|
+
// Inline SVG paths for critical icons (fallback when font not loaded)
|
|
16
|
+
const SVG_ICONS = {
|
|
17
|
+
// Actions
|
|
18
|
+
check: 'M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z',
|
|
19
|
+
close: 'M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
|
20
|
+
add: 'M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z',
|
|
21
|
+
remove: 'M19 13H5v-2h14z',
|
|
22
|
+
edit: 'M3 17.25V21h3.75L17.81 9.94l-3.75-3.75zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75z',
|
|
23
|
+
delete: 'M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6zM19 4h-3.5l-1-1h-5l-1 1H5v2h14z',
|
|
24
|
+
search: 'M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z',
|
|
25
|
+
|
|
26
|
+
// Navigation
|
|
27
|
+
menu: 'M3 18h18v-2H3zm0-5h18v-2H3zm0-7v2h18V6z',
|
|
28
|
+
chevron_right: 'M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z',
|
|
29
|
+
chevron_left: 'M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z',
|
|
30
|
+
expand_more: 'M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z',
|
|
31
|
+
expand_less: 'M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z',
|
|
32
|
+
home: 'M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z',
|
|
33
|
+
arrow_back: 'M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20z',
|
|
34
|
+
arrow_forward: 'M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z',
|
|
35
|
+
|
|
36
|
+
// Status
|
|
37
|
+
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2zm0-8h-2V7h2z',
|
|
38
|
+
warning: 'M1 21h22L12 2zm12-3h-2v-2h2zm0-4h-2v-4h2z',
|
|
39
|
+
error: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2zm0-4h-2V7h2z',
|
|
40
|
+
check_circle: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8z',
|
|
41
|
+
cancel: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12z',
|
|
42
|
+
|
|
43
|
+
// Aliases for alert severity
|
|
44
|
+
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8z',
|
|
45
|
+
|
|
46
|
+
// UI
|
|
47
|
+
settings: 'M19.14 12.94c.04-.31.06-.63.06-.94 0-.31-.02-.63-.06-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.04.31-.06.63-.06.94s.02.63.06.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z',
|
|
48
|
+
person: 'M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z',
|
|
49
|
+
light_mode: 'M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5M2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1m18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1M11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1m0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1M5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0z',
|
|
50
|
+
dark_mode: 'M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z',
|
|
51
|
+
visibility: 'M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5M12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5m0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3',
|
|
52
|
+
visibility_off: 'M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7M2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2m4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3z',
|
|
53
|
+
|
|
54
|
+
// Drawer/Navigation icons
|
|
55
|
+
download: 'M5 20h14v-2H5v2zM19 9h-4V3H9v6H5l7 7 7-7z',
|
|
56
|
+
smart_button: 'M22 9v6c0 1.1-.9 2-2 2h-1v-2h1V9H4v6h6v2H4c-1.1 0-2-.9-2-2V9c0-1.1.9-2 2-2h16c1.1 0 2 .9 2 2zm-7.5 11 1.09-2.41L18 16.5l-2.41-1.09L14.5 13l-1.09 2.41L11 16.5l2.41 1.09L14.5 20zm2.5-5 .62-1.38L19 14l-1.38-.62L17 12l-.62 1.38L15 14l1.38.62L17 16zm-2.5 5 1.09-2.41L18 16.5l-2.41-1.09L14.5 13l-1.09 2.41L11 16.5l2.41 1.09L14.5 20z',
|
|
57
|
+
text_fields: 'M2.5 4v3h5v12h3V7h5V4h-13zm19 5h-9v3h3v7h3v-7h3V9z',
|
|
58
|
+
check_box: 'M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
|
59
|
+
toggle_on: 'M17 7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h10c2.76 0 5-2.24 5-5s-2.24-5-5-5zm0 8c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z',
|
|
60
|
+
radio_button_checked: 'M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z',
|
|
61
|
+
arrow_drop_down_circle: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 12-4-4h8l-4 4z',
|
|
62
|
+
view_carousel: 'M7 19h10V4H7v15zm-5-2h4V6H2v11zM18 6v11h4V6h-4z',
|
|
63
|
+
grid_view: 'M3 3v8h8V3H3zm6 6H5V5h4v4zm-6 4v8h8v-8H3zm6 6H5v-4h4v4zm4-16v8h8V3h-8zm6 6h-4V5h4v4zm-6 4v8h8v-8h-8zm6 6h-4v-4h4v4z',
|
|
64
|
+
tab: 'M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h10v4h8v10z',
|
|
65
|
+
notifications: 'M12 22c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z',
|
|
66
|
+
open_in_new: 'M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z',
|
|
67
|
+
hourglass_empty: 'M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6zm10 14.5V20H8v-3.5l4-4 4 4zm-4-5-4-4V4h8v3.5l-4 4z',
|
|
68
|
+
account_circle: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 4c1.93 0 3.5 1.57 3.5 3.5S13.93 13 12 13s-3.5-1.57-3.5-3.5S10.07 6 12 6zm0 14c-2.03 0-4.43-.82-6.14-2.88C7.55 15.8 9.68 15 12 15s4.45.8 6.14 2.12C16.43 19.18 14.03 20 12 20z',
|
|
69
|
+
fiber_manual_record: 'M12 12m-8 0a8 8 0 1 0 16 0 8 8 0 1 0-16 0',
|
|
70
|
+
label: 'M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z',
|
|
71
|
+
emoji_emotions: 'M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z',
|
|
72
|
+
business: 'M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z',
|
|
73
|
+
input: 'M21 3.01H3c-1.1 0-2 .9-2 2V9h2V4.99h18v14.03H3V15H1v4.01c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98v-14c0-1.11-.9-2-2-2zM11 16l4-4-4-4v3H1v2h10v3z',
|
|
74
|
+
category: 'M12 2l-5.5 9h11L12 2zm0 3.84L13.93 9h-3.87L12 5.84zM17.5 13c-2.49 0-4.5 2.01-4.5 4.5s2.01 4.5 4.5 4.5 4.5-2.01 4.5-4.5-2.01-4.5-4.5-4.5zm0 7c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5zM3 21.5h8v-8H3v8zm2-6h4v4H5v-4z',
|
|
75
|
+
widgets: 'M13 13v8h8v-8h-8zM3 21h8v-8H3v8zM3 3v8h8V3H3zm13.66-1.31L11 7.34 16.66 13l5.66-5.66-5.66-5.65z',
|
|
76
|
+
smart_toy: 'M20 9V7c0-1.1-.9-2-2-2h-3c0-1.66-1.34-3-3-3S9 3.34 9 5H6c-1.1 0-2 .9-2 2v2c-1.66 0-3 1.34-3 3s1.34 3 3 3v4c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4c1.66 0 3-1.34 3-3s-1.34-3-3-3zM7.5 11.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5S9.83 13 9 13s-1.5-.67-1.5-1.5zM16 17H8v-2h8v2zm-1-4c-.83 0-1.5-.67-1.5-1.5S14.17 10 15 10s1.5.67 1.5 1.5S15.83 13 15 13z',
|
|
77
|
+
notification_important: 'M18 16v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2zm-6 6c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2zm1-15.06c1.77.52 3 2.14 3 4.06v5.5l1 1v.5H7v-.5l1-1V11c0-1.92 1.23-3.54 3-4.06V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5v.94zM13 11h-2v6h2v-6zm0-4h-2v2h2V7z',
|
|
78
|
+
|
|
79
|
+
// Enterprise icons
|
|
80
|
+
folder_managed: 'M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-2.06 11L15 15.28 12.06 17l.78-3.33-2.59-2.24 3.41-.29L15 8l1.34 3.14 3.41.29-2.59 2.24.78 3.33z',
|
|
81
|
+
shield: 'M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z',
|
|
82
|
+
apps: 'M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z',
|
|
83
|
+
monitoring: 'M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zM7 12h2v5H7v-5zm4-3h2v8h-2V9zm4-3h2v11h-2V6z'
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Map from alert severity to Material Symbol names
|
|
87
|
+
const SYMBOL_NAMES = {
|
|
88
|
+
check: 'check',
|
|
89
|
+
close: 'close',
|
|
90
|
+
add: 'add',
|
|
91
|
+
remove: 'remove',
|
|
92
|
+
edit: 'edit',
|
|
93
|
+
delete: 'delete',
|
|
94
|
+
search: 'search',
|
|
95
|
+
menu: 'menu',
|
|
96
|
+
chevron_right: 'chevron_right',
|
|
97
|
+
chevron_left: 'chevron_left',
|
|
98
|
+
expand_more: 'expand_more',
|
|
99
|
+
expand_less: 'expand_less',
|
|
100
|
+
home: 'home',
|
|
101
|
+
arrow_back: 'arrow_back',
|
|
102
|
+
arrow_forward: 'arrow_forward',
|
|
103
|
+
info: 'info',
|
|
104
|
+
warning: 'warning',
|
|
105
|
+
error: 'error',
|
|
106
|
+
success: 'check_circle',
|
|
107
|
+
check_circle: 'check_circle',
|
|
108
|
+
cancel: 'cancel',
|
|
109
|
+
settings: 'settings',
|
|
110
|
+
person: 'person',
|
|
111
|
+
light_mode: 'light_mode',
|
|
112
|
+
dark_mode: 'dark_mode',
|
|
113
|
+
sun: 'light_mode',
|
|
114
|
+
moon: 'dark_mode',
|
|
115
|
+
user: 'person',
|
|
116
|
+
visibility: 'visibility',
|
|
117
|
+
visibility_off: 'visibility_off',
|
|
118
|
+
// Drawer/Navigation icons
|
|
119
|
+
download: 'download',
|
|
120
|
+
smart_button: 'smart_button',
|
|
121
|
+
text_fields: 'text_fields',
|
|
122
|
+
check_box: 'check_box',
|
|
123
|
+
toggle_on: 'toggle_on',
|
|
124
|
+
radio_button_checked: 'radio_button_checked',
|
|
125
|
+
arrow_drop_down_circle: 'arrow_drop_down_circle',
|
|
126
|
+
view_carousel: 'view_carousel',
|
|
127
|
+
grid_view: 'grid_view',
|
|
128
|
+
tab: 'tab',
|
|
129
|
+
notifications: 'notifications',
|
|
130
|
+
open_in_new: 'open_in_new',
|
|
131
|
+
hourglass_empty: 'hourglass_empty',
|
|
132
|
+
account_circle: 'account_circle',
|
|
133
|
+
fiber_manual_record: 'fiber_manual_record',
|
|
134
|
+
label: 'label',
|
|
135
|
+
emoji_emotions: 'emoji_emotions',
|
|
136
|
+
business: 'business',
|
|
137
|
+
input: 'input',
|
|
138
|
+
category: 'category',
|
|
139
|
+
widgets: 'widgets',
|
|
140
|
+
smart_toy: 'smart_toy',
|
|
141
|
+
notification_important: 'notification_important',
|
|
142
|
+
// Enterprise icons
|
|
143
|
+
folder_managed: 'folder_managed',
|
|
144
|
+
shield: 'shield',
|
|
145
|
+
apps: 'apps',
|
|
146
|
+
monitoring: 'monitoring',
|
|
147
|
+
// Common aliases
|
|
148
|
+
plus: 'add',
|
|
149
|
+
minus: 'remove'
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export class MuIcon extends MuElement {
|
|
153
|
+
static baseClass = 'mu-icon';
|
|
154
|
+
static cssFile = 'icon';
|
|
155
|
+
static observedAttributes = ['name', 'size', 'svg', 'filled', 'font'];
|
|
156
|
+
|
|
157
|
+
render() {
|
|
158
|
+
const name = this.attr('name', 'info');
|
|
159
|
+
const size = this.attr('size', '24');
|
|
160
|
+
const forceFont = this.has('font'); // New: force font instead of SVG
|
|
161
|
+
const filled = this.has('filled');
|
|
162
|
+
|
|
163
|
+
// Accessibility: set role and aria-hidden (decorative by default)
|
|
164
|
+
this.setAttribute('role', 'img');
|
|
165
|
+
this.setAttribute('aria-hidden', 'true');
|
|
166
|
+
|
|
167
|
+
// Resolve aliases
|
|
168
|
+
const resolvedName = SYMBOL_NAMES[name] ? name : name;
|
|
169
|
+
const svgPath = SVG_ICONS[name] || SVG_ICONS[SYMBOL_NAMES[name]];
|
|
170
|
+
|
|
171
|
+
// SVG first (default) - eliminates 254KB font dependency for common icons
|
|
172
|
+
// Only fall back to font if: 1) force font attr, or 2) no SVG exists
|
|
173
|
+
if (!forceFont && svgPath) {
|
|
174
|
+
this.innerHTML = `
|
|
175
|
+
<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
176
|
+
<path d="${svgPath}"></path>
|
|
177
|
+
</svg>
|
|
178
|
+
`;
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Fall back to Material Symbols font (for rare icons not in SVG set)
|
|
183
|
+
const symbolName = SYMBOL_NAMES[name] || name;
|
|
184
|
+
|
|
185
|
+
// Log warning for unknown icon names (AI agent readiness)
|
|
186
|
+
if (!SYMBOL_NAMES[name] && !SVG_ICONS[name]) {
|
|
187
|
+
this.logError('UNKNOWN_ICON', `Icon name "${name}" not found in predefined icons. Using font fallback.`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
this.innerHTML = `<span class="material-symbols-outlined" aria-hidden="true">${symbolName}</span>`;
|
|
191
|
+
|
|
192
|
+
// Apply size and fill
|
|
193
|
+
const span = this.querySelector('span');
|
|
194
|
+
if (span) {
|
|
195
|
+
span.style.fontSize = `${size}px`;
|
|
196
|
+
if (filled) {
|
|
197
|
+
span.style.fontVariationSettings = "'FILL' 1";
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
update(attr, newValue, oldValue) {
|
|
203
|
+
this.render();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Export icon names for reference
|
|
208
|
+
export const IconNames = Object.keys(SYMBOL_NAMES);
|
|
209
|
+
export const SvgIconNames = Object.keys(SVG_ICONS);
|
|
210
|
+
|
|
211
|
+
define('mu-icon', MuIcon);
|