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,771 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Agent-Friendly APIs for microUI
|
|
3
|
+
*
|
|
4
|
+
* Provides structured component tree access and natural language descriptions
|
|
5
|
+
* for LLM agents interacting with microUI components.
|
|
6
|
+
*
|
|
7
|
+
* Based on research from Agent-E (2024), WebVoyager benchmark, and
|
|
8
|
+
* DOM distillation techniques for AI browser automation.
|
|
9
|
+
*
|
|
10
|
+
* @module core/agent-api
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} MuComponentInfo
|
|
15
|
+
* @property {string} tag - Component tag name (e.g., 'mu-button')
|
|
16
|
+
* @property {string|null} id - Element ID if present
|
|
17
|
+
* @property {string} label - Accessible name/label for the component
|
|
18
|
+
* @property {string} description - Human-readable description of component purpose
|
|
19
|
+
* @property {Object} state - Current component state
|
|
20
|
+
* @property {string[]} actions - Available actions (e.g., ['click', 'toggle'])
|
|
21
|
+
* @property {Object} rect - Bounding client rect {top, left, width, height}
|
|
22
|
+
* @property {boolean} interactive - Whether component accepts user input
|
|
23
|
+
* @property {boolean} visible - Whether component is in viewport
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get the accessible name of an element following ARIA naming conventions
|
|
28
|
+
* @param {HTMLElement} el - Element to get name from
|
|
29
|
+
* @returns {string} Accessible name
|
|
30
|
+
*/
|
|
31
|
+
function getAccessibleName(el) {
|
|
32
|
+
// Priority order per ARIA spec:
|
|
33
|
+
// 1. aria-labelledby
|
|
34
|
+
// 2. aria-label
|
|
35
|
+
// 3. associated label element
|
|
36
|
+
// 4. title attribute
|
|
37
|
+
// 5. text content (for certain roles)
|
|
38
|
+
// 6. placeholder (for inputs)
|
|
39
|
+
|
|
40
|
+
// aria-labelledby
|
|
41
|
+
const labelledBy = el.getAttribute('aria-labelledby');
|
|
42
|
+
if (labelledBy) {
|
|
43
|
+
const labels = labelledBy.split(' ')
|
|
44
|
+
.map(id => document.getElementById(id)?.textContent)
|
|
45
|
+
.filter(Boolean)
|
|
46
|
+
.join(' ');
|
|
47
|
+
if (labels) return labels;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// aria-label
|
|
51
|
+
const ariaLabel = el.getAttribute('aria-label');
|
|
52
|
+
if (ariaLabel) return ariaLabel;
|
|
53
|
+
|
|
54
|
+
// Associated label element
|
|
55
|
+
if (el.id) {
|
|
56
|
+
const label = document.querySelector(`label[for="${el.id}"]`);
|
|
57
|
+
if (label) return label.textContent.trim();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// title attribute
|
|
61
|
+
const title = el.getAttribute('title');
|
|
62
|
+
if (title) return title;
|
|
63
|
+
|
|
64
|
+
// Text content for buttons, links, etc.
|
|
65
|
+
const role = el.getAttribute('role') || el.tagName.toLowerCase();
|
|
66
|
+
const textRoles = ['button', 'link', 'tab', 'menuitem', 'option', 'radio', 'checkbox'];
|
|
67
|
+
if (textRoles.some(r => role.includes(r))) {
|
|
68
|
+
const text = el.textContent?.trim();
|
|
69
|
+
if (text && text.length < 100) return text;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Placeholder for inputs
|
|
73
|
+
const placeholder = el.getAttribute('placeholder');
|
|
74
|
+
if (placeholder) return placeholder;
|
|
75
|
+
|
|
76
|
+
// Value for inputs with value
|
|
77
|
+
const value = el.getAttribute('value');
|
|
78
|
+
if (value && el.tagName.includes('INPUT')) return `Input: ${value}`;
|
|
79
|
+
|
|
80
|
+
// Fallback to tag name
|
|
81
|
+
return el.tagName.toLowerCase().replace('mu-', '');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Get available actions for a component based on its type and state
|
|
86
|
+
* @param {HTMLElement} el - Component element
|
|
87
|
+
* @returns {string[]} List of available actions
|
|
88
|
+
*/
|
|
89
|
+
function getAvailableActions(el) {
|
|
90
|
+
const actions = [];
|
|
91
|
+
const tag = el.tagName.toLowerCase();
|
|
92
|
+
const disabled = el.hasAttribute('disabled');
|
|
93
|
+
|
|
94
|
+
if (disabled) return ['none (disabled)'];
|
|
95
|
+
|
|
96
|
+
// Common interactive actions
|
|
97
|
+
if (el.onclick || el.hasAttribute('onclick')) {
|
|
98
|
+
actions.push('click');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Component-specific actions
|
|
102
|
+
switch (tag) {
|
|
103
|
+
case 'mu-button':
|
|
104
|
+
actions.push('click');
|
|
105
|
+
break;
|
|
106
|
+
case 'mu-checkbox':
|
|
107
|
+
case 'mu-switch':
|
|
108
|
+
actions.push('toggle', 'check', 'uncheck');
|
|
109
|
+
break;
|
|
110
|
+
case 'mu-input':
|
|
111
|
+
case 'mu-textarea':
|
|
112
|
+
actions.push('type', 'clear', 'focus');
|
|
113
|
+
break;
|
|
114
|
+
case 'mu-dropdown':
|
|
115
|
+
actions.push('open', 'select', 'close');
|
|
116
|
+
break;
|
|
117
|
+
case 'mu-modal':
|
|
118
|
+
actions.push('open', 'close');
|
|
119
|
+
break;
|
|
120
|
+
case 'mu-tabs':
|
|
121
|
+
actions.push('select-tab');
|
|
122
|
+
break;
|
|
123
|
+
case 'mu-radio':
|
|
124
|
+
actions.push('select');
|
|
125
|
+
break;
|
|
126
|
+
case 'mu-chip':
|
|
127
|
+
actions.push('toggle', 'click');
|
|
128
|
+
break;
|
|
129
|
+
case 'mu-confirm':
|
|
130
|
+
actions.push('confirm', 'cancel');
|
|
131
|
+
break;
|
|
132
|
+
default:
|
|
133
|
+
if (el.classList.contains('mu-button') || el.getAttribute('role') === 'button') {
|
|
134
|
+
actions.push('click');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return actions.length ? actions : ['focus'];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get component state as a plain object
|
|
143
|
+
* @param {HTMLElement} el - Component element
|
|
144
|
+
* @returns {Object} Component state
|
|
145
|
+
*/
|
|
146
|
+
function getComponentState(el) {
|
|
147
|
+
const state = {};
|
|
148
|
+
const tag = el.tagName.toLowerCase();
|
|
149
|
+
|
|
150
|
+
// Common state attributes
|
|
151
|
+
if (el.hasAttribute('checked')) state.checked = true;
|
|
152
|
+
if (el.hasAttribute('disabled')) state.disabled = true;
|
|
153
|
+
if (el.hasAttribute('open')) state.open = true;
|
|
154
|
+
if (el.hasAttribute('selected')) state.selected = true;
|
|
155
|
+
if (el.hasAttribute('active')) state.active = true;
|
|
156
|
+
if (el.hasAttribute('loading')) state.loading = true;
|
|
157
|
+
if (el.hasAttribute('value')) state.value = el.getAttribute('value');
|
|
158
|
+
|
|
159
|
+
// ARIA state
|
|
160
|
+
const ariaChecked = el.getAttribute('aria-checked');
|
|
161
|
+
if (ariaChecked) state.ariaChecked = ariaChecked === 'true';
|
|
162
|
+
|
|
163
|
+
const ariaExpanded = el.getAttribute('aria-expanded');
|
|
164
|
+
if (ariaExpanded) state.expanded = ariaExpanded === 'true';
|
|
165
|
+
|
|
166
|
+
const ariaSelected = el.getAttribute('aria-selected');
|
|
167
|
+
if (ariaSelected) state.selected = ariaSelected === 'true';
|
|
168
|
+
|
|
169
|
+
// Component-specific state
|
|
170
|
+
switch (tag) {
|
|
171
|
+
case 'mu-input':
|
|
172
|
+
case 'mu-textarea':
|
|
173
|
+
const input = el.querySelector('input, textarea');
|
|
174
|
+
if (input) {
|
|
175
|
+
state.value = input.value;
|
|
176
|
+
state.placeholder = input.placeholder;
|
|
177
|
+
}
|
|
178
|
+
break;
|
|
179
|
+
case 'mu-progress':
|
|
180
|
+
state.value = parseFloat(el.getAttribute('value') || '0');
|
|
181
|
+
state.max = parseFloat(el.getAttribute('max') || '100');
|
|
182
|
+
state.percentage = (state.value / state.max) * 100;
|
|
183
|
+
break;
|
|
184
|
+
case 'mu-dropdown':
|
|
185
|
+
state.value = el.getAttribute('value');
|
|
186
|
+
state.open = el.classList.contains('is-open');
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return state;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Generate a natural language description of a component
|
|
195
|
+
* @param {HTMLElement} el - Component element
|
|
196
|
+
* @returns {string} Human-readable description
|
|
197
|
+
*/
|
|
198
|
+
function describeComponent(el) {
|
|
199
|
+
const tag = el.tagName.toLowerCase().replace('mu-', '');
|
|
200
|
+
const label = getAccessibleName(el);
|
|
201
|
+
const state = getComponentState(el);
|
|
202
|
+
const disabled = state.disabled ? ' (disabled)' : '';
|
|
203
|
+
|
|
204
|
+
const descriptions = {
|
|
205
|
+
'button': () => `Button "${label}"${disabled}. ${state.loading ? 'Currently loading.' : 'Click to activate.'}`,
|
|
206
|
+
'checkbox': () => `Checkbox "${label}"${disabled}. Currently ${state.ariaChecked || state.checked ? 'checked' : 'unchecked'}.`,
|
|
207
|
+
'switch': () => `Toggle switch "${label}"${disabled}. Currently ${state.ariaChecked || state.checked ? 'on' : 'off'}.`,
|
|
208
|
+
'input': () => `Text input "${label}"${disabled}. ${state.value ? `Current value: "${state.value}"` : 'Empty.'} ${state.placeholder ? `Placeholder: "${state.placeholder}"` : ''}`,
|
|
209
|
+
'textarea': () => `Text area "${label}"${disabled}. ${state.value ? `Contains: "${state.value.slice(0, 50)}${state.value.length > 50 ? '...' : ''}"` : 'Empty.'}`,
|
|
210
|
+
'dropdown': () => `Dropdown "${label}"${disabled}. ${state.value ? `Selected: "${state.value}"` : 'No selection.'} ${state.open ? 'Menu is open.' : 'Menu is closed.'}`,
|
|
211
|
+
'modal': () => `Modal dialog${state.open ? ' (currently open)' : ' (currently closed)'}. ${label !== 'modal' ? `Title: "${label}"` : ''}`,
|
|
212
|
+
'tabs': () => `Tab navigation with ${el.querySelectorAll('mu-tab').length} tabs.`,
|
|
213
|
+
'tab': () => `Tab "${label}". ${state.active ? 'Currently active.' : 'Inactive.'}`,
|
|
214
|
+
'progress': () => `Progress bar at ${Math.round(state.percentage || 0)}%.`,
|
|
215
|
+
'spinner': () => 'Loading spinner indicating operation in progress.',
|
|
216
|
+
'alert': () => `Alert message: "${el.textContent?.trim().slice(0, 100) || label}"`,
|
|
217
|
+
'card': () => `Card container${label !== 'card' ? ` titled "${label}"` : ''}.`,
|
|
218
|
+
'chip': () => `Chip "${label}"${disabled}. ${state.selected ? 'Selected.' : 'Not selected.'}`,
|
|
219
|
+
'badge': () => `Badge showing "${el.textContent?.trim() || 'notification'}"`,
|
|
220
|
+
'avatar': () => `User avatar${el.getAttribute('name') ? ` for "${el.getAttribute('name')}"` : ''}`,
|
|
221
|
+
'icon': () => `Icon: ${el.getAttribute('name') || 'decorative'}`,
|
|
222
|
+
'confirm': () => `Confirmation dialog. ${state.open ? 'Waiting for user response.' : 'Hidden.'}`,
|
|
223
|
+
'fetch': () => `Data fetcher${state.loading ? ' (loading)' : ''}. URL: ${el.getAttribute('url') || 'not set'}`
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const describer = descriptions[tag];
|
|
227
|
+
if (describer) return describer();
|
|
228
|
+
|
|
229
|
+
// Generic fallback
|
|
230
|
+
return `${tag} component${label ? ` "${label}"` : ''}${disabled}.`;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Check if element is visible in viewport
|
|
235
|
+
* @param {HTMLElement} el
|
|
236
|
+
* @returns {boolean}
|
|
237
|
+
*/
|
|
238
|
+
function isInViewport(el) {
|
|
239
|
+
const rect = el.getBoundingClientRect();
|
|
240
|
+
return (
|
|
241
|
+
rect.top < window.innerHeight &&
|
|
242
|
+
rect.bottom > 0 &&
|
|
243
|
+
rect.left < window.innerWidth &&
|
|
244
|
+
rect.right > 0 &&
|
|
245
|
+
rect.width > 0 &&
|
|
246
|
+
rect.height > 0
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Get a simplified component tree for agent parsing
|
|
252
|
+
* Implements DOM distillation as per Agent-E (2024) research
|
|
253
|
+
*
|
|
254
|
+
* @param {HTMLElement} [root=document.body] - Root element to scan
|
|
255
|
+
* @param {Object} [options] - Options
|
|
256
|
+
* @param {boolean} [options.visibleOnly=false] - Only include visible components
|
|
257
|
+
* @param {boolean} [options.interactiveOnly=false] - Only include interactive components
|
|
258
|
+
* @param {string[]} [options.types] - Filter to specific component types
|
|
259
|
+
* @returns {MuComponentInfo[]} Array of component info objects
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* // Get all components
|
|
263
|
+
* const tree = getMuComponentTree();
|
|
264
|
+
*
|
|
265
|
+
* // Get only visible interactive components
|
|
266
|
+
* const interactive = getMuComponentTree(document.body, {
|
|
267
|
+
* visibleOnly: true,
|
|
268
|
+
* interactiveOnly: true
|
|
269
|
+
* });
|
|
270
|
+
*
|
|
271
|
+
* // Get only buttons and inputs
|
|
272
|
+
* const forms = getMuComponentTree(document.body, {
|
|
273
|
+
* types: ['mu-button', 'mu-input', 'mu-checkbox']
|
|
274
|
+
* });
|
|
275
|
+
*/
|
|
276
|
+
export function getMuComponentTree(root = document.body, options = {}) {
|
|
277
|
+
const { visibleOnly = false, interactiveOnly = false, types = null } = options;
|
|
278
|
+
|
|
279
|
+
// Find all mu-* components
|
|
280
|
+
const selector = types
|
|
281
|
+
? types.join(',')
|
|
282
|
+
: '[class^="mu-"]:not(.mu-ripple-wave)';
|
|
283
|
+
|
|
284
|
+
const elements = root.querySelectorAll(selector);
|
|
285
|
+
const results = [];
|
|
286
|
+
|
|
287
|
+
const interactiveTags = new Set([
|
|
288
|
+
'mu-button', 'mu-checkbox', 'mu-switch', 'mu-input', 'mu-textarea',
|
|
289
|
+
'mu-dropdown', 'mu-radio', 'mu-tab', 'mu-chip', 'mu-modal', 'mu-confirm'
|
|
290
|
+
]);
|
|
291
|
+
|
|
292
|
+
for (const el of elements) {
|
|
293
|
+
const tag = el.tagName.toLowerCase();
|
|
294
|
+
|
|
295
|
+
// Skip non-mu elements that happen to match selector
|
|
296
|
+
if (!tag.startsWith('mu-')) continue;
|
|
297
|
+
|
|
298
|
+
const isInteractive = interactiveTags.has(tag);
|
|
299
|
+
const visible = isInViewport(el);
|
|
300
|
+
|
|
301
|
+
// Apply filters
|
|
302
|
+
if (visibleOnly && !visible) continue;
|
|
303
|
+
if (interactiveOnly && !isInteractive) continue;
|
|
304
|
+
|
|
305
|
+
const rect = el.getBoundingClientRect();
|
|
306
|
+
|
|
307
|
+
results.push({
|
|
308
|
+
tag,
|
|
309
|
+
id: el.id || null,
|
|
310
|
+
label: getAccessibleName(el),
|
|
311
|
+
description: describeComponent(el),
|
|
312
|
+
state: getComponentState(el),
|
|
313
|
+
actions: getAvailableActions(el),
|
|
314
|
+
rect: {
|
|
315
|
+
top: Math.round(rect.top),
|
|
316
|
+
left: Math.round(rect.left),
|
|
317
|
+
width: Math.round(rect.width),
|
|
318
|
+
height: Math.round(rect.height)
|
|
319
|
+
},
|
|
320
|
+
interactive: isInteractive,
|
|
321
|
+
visible
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return results;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Describe a single component in natural language
|
|
330
|
+
* @param {HTMLElement|string} component - Element or CSS selector
|
|
331
|
+
* @returns {string|null} Natural language description or null if not found
|
|
332
|
+
*/
|
|
333
|
+
export function describe(component) {
|
|
334
|
+
const el = typeof component === 'string'
|
|
335
|
+
? document.querySelector(component)
|
|
336
|
+
: component;
|
|
337
|
+
|
|
338
|
+
if (!el) return null;
|
|
339
|
+
return describeComponent(el);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Get a map of all registered microUI custom elements
|
|
344
|
+
* @returns {Map<string, typeof HTMLElement>} Map of tag names to constructors
|
|
345
|
+
*/
|
|
346
|
+
export function getRegisteredComponents() {
|
|
347
|
+
const components = new Map();
|
|
348
|
+
const possibleTags = [
|
|
349
|
+
'mu-button', 'mu-input', 'mu-textarea', 'mu-checkbox', 'mu-switch',
|
|
350
|
+
'mu-dropdown', 'mu-option', 'mu-radio', 'mu-radio-group', 'mu-chip',
|
|
351
|
+
'mu-card', 'mu-tabs', 'mu-tab', 'mu-alert', 'mu-badge', 'mu-progress',
|
|
352
|
+
'mu-avatar', 'mu-skeleton', 'mu-spinner', 'mu-modal', 'mu-toast',
|
|
353
|
+
'mu-tooltip', 'mu-icon', 'mu-stack', 'mu-grid', 'mu-container',
|
|
354
|
+
'mu-navbar', 'mu-sidebar', 'mu-divider', 'mu-theme-toggle',
|
|
355
|
+
'mu-virtual-list', 'mu-lazy', 'mu-repeat', 'mu-form', 'mu-table',
|
|
356
|
+
'mu-confirm', 'mu-fetch'
|
|
357
|
+
];
|
|
358
|
+
|
|
359
|
+
for (const tag of possibleTags) {
|
|
360
|
+
const constructor = customElements.get(tag);
|
|
361
|
+
if (constructor) {
|
|
362
|
+
components.set(tag, constructor);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return components;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Find components by their accessible label (fuzzy match)
|
|
371
|
+
* @param {string} labelQuery - Label text to search for
|
|
372
|
+
* @param {HTMLElement} [root=document.body] - Root to search within
|
|
373
|
+
* @returns {HTMLElement[]} Matching components
|
|
374
|
+
*/
|
|
375
|
+
export function findByLabel(labelQuery, root = document.body) {
|
|
376
|
+
const query = labelQuery.toLowerCase();
|
|
377
|
+
const tree = getMuComponentTree(root);
|
|
378
|
+
|
|
379
|
+
return tree
|
|
380
|
+
.filter(info => info.label.toLowerCase().includes(query))
|
|
381
|
+
.map(info => {
|
|
382
|
+
const selector = info.id
|
|
383
|
+
? `#${info.id}`
|
|
384
|
+
: `${info.tag}`;
|
|
385
|
+
return root.querySelector(selector);
|
|
386
|
+
})
|
|
387
|
+
.filter(Boolean);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// ============================================
|
|
391
|
+
// 2026 VISUAL MARKERS (UI-TARS Research)
|
|
392
|
+
// ============================================
|
|
393
|
+
|
|
394
|
+
let markersEnabled = false;
|
|
395
|
+
let markerContainer = null;
|
|
396
|
+
const markerMap = new Map(); // element -> marker element
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Enable visual markers on interactive elements for screenshot-based AI agents.
|
|
400
|
+
* Based on UI-TARS (2025) hybrid DOM+Vision research.
|
|
401
|
+
*
|
|
402
|
+
* Adds overlay labels like [B1], [I1], [C1] to each interactive element.
|
|
403
|
+
*
|
|
404
|
+
* @param {Object} [options] - Options
|
|
405
|
+
* @param {boolean} [options.showLabels=true] - Show text labels ([B1], etc.)
|
|
406
|
+
* @param {boolean} [options.showBoxes=true] - Show bounding boxes
|
|
407
|
+
* @param {string} [options.markerStyle='badge'] - Style: 'badge' | 'corner' | 'outline'
|
|
408
|
+
* @returns {Map<string, HTMLElement>} Map of marker IDs to elements
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* const markers = microUI.enableVisualMarkers();
|
|
412
|
+
* // Take screenshot
|
|
413
|
+
* // Agent sees: [B1] Save, [B2] Cancel, [I1] Email input
|
|
414
|
+
*/
|
|
415
|
+
export function enableVisualMarkers(options = {}) {
|
|
416
|
+
const { showLabels = true, showBoxes = true, markerStyle = 'badge' } = options;
|
|
417
|
+
|
|
418
|
+
// Disable first if already enabled
|
|
419
|
+
if (markersEnabled) disableVisualMarkers();
|
|
420
|
+
|
|
421
|
+
// Create container
|
|
422
|
+
markerContainer = document.createElement('div');
|
|
423
|
+
markerContainer.id = 'mu-visual-markers';
|
|
424
|
+
markerContainer.style.cssText = `
|
|
425
|
+
position: fixed;
|
|
426
|
+
inset: 0;
|
|
427
|
+
pointer-events: none;
|
|
428
|
+
z-index: 999999;
|
|
429
|
+
`;
|
|
430
|
+
document.body.appendChild(markerContainer);
|
|
431
|
+
|
|
432
|
+
// Counter prefixes by type
|
|
433
|
+
const counters = { B: 0, I: 0, C: 0, S: 0, D: 0, M: 0, T: 0, R: 0, O: 0 };
|
|
434
|
+
|
|
435
|
+
// Get type prefix
|
|
436
|
+
const getPrefix = (tag) => {
|
|
437
|
+
const prefixes = {
|
|
438
|
+
'mu-button': 'B',
|
|
439
|
+
'mu-input': 'I',
|
|
440
|
+
'mu-textarea': 'I',
|
|
441
|
+
'mu-checkbox': 'C',
|
|
442
|
+
'mu-switch': 'S',
|
|
443
|
+
'mu-dropdown': 'D',
|
|
444
|
+
'mu-modal': 'M',
|
|
445
|
+
'mu-tabs': 'T',
|
|
446
|
+
'mu-tab': 'T',
|
|
447
|
+
'mu-radio': 'R',
|
|
448
|
+
'mu-chip': 'C',
|
|
449
|
+
'mu-confirm': 'M'
|
|
450
|
+
};
|
|
451
|
+
return prefixes[tag] || 'O';
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
// Get interactive components
|
|
455
|
+
const tree = getMuComponentTree(document.body, { interactiveOnly: true, visibleOnly: true });
|
|
456
|
+
|
|
457
|
+
for (const info of tree) {
|
|
458
|
+
const prefix = getPrefix(info.tag);
|
|
459
|
+
counters[prefix]++;
|
|
460
|
+
const markerId = `${prefix}${counters[prefix]}`;
|
|
461
|
+
|
|
462
|
+
const el = document.querySelector(
|
|
463
|
+
info.id ? `#${info.id}` : `${info.tag}[data-mu-action="${info.state.action || ''}"]`
|
|
464
|
+
) || document.querySelector(info.tag);
|
|
465
|
+
|
|
466
|
+
if (!el) continue;
|
|
467
|
+
|
|
468
|
+
const rect = el.getBoundingClientRect();
|
|
469
|
+
|
|
470
|
+
// Create marker
|
|
471
|
+
const marker = document.createElement('div');
|
|
472
|
+
marker.className = 'mu-visual-marker';
|
|
473
|
+
marker.dataset.markerId = markerId;
|
|
474
|
+
marker.dataset.tag = info.tag;
|
|
475
|
+
marker.dataset.label = info.label;
|
|
476
|
+
|
|
477
|
+
const bgColor = {
|
|
478
|
+
'B': '#7C4DFF', // Buttons - purple
|
|
479
|
+
'I': '#00BCD4', // Inputs - cyan
|
|
480
|
+
'C': '#4CAF50', // Checkboxes - green
|
|
481
|
+
'S': '#FF9800', // Switches - orange
|
|
482
|
+
'D': '#2196F3', // Dropdowns - blue
|
|
483
|
+
'M': '#E91E63', // Modals - pink
|
|
484
|
+
'T': '#9C27B0', // Tabs - deep purple
|
|
485
|
+
'R': '#795548', // Radio - brown
|
|
486
|
+
'O': '#607D8B' // Other - grey
|
|
487
|
+
}[prefix];
|
|
488
|
+
|
|
489
|
+
if (markerStyle === 'badge') {
|
|
490
|
+
marker.style.cssText = `
|
|
491
|
+
position: fixed;
|
|
492
|
+
top: ${rect.top - 8}px;
|
|
493
|
+
left: ${rect.left - 8}px;
|
|
494
|
+
background: ${bgColor};
|
|
495
|
+
color: white;
|
|
496
|
+
font: bold 11px system-ui;
|
|
497
|
+
padding: 2px 6px;
|
|
498
|
+
border-radius: 4px;
|
|
499
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
500
|
+
white-space: nowrap;
|
|
501
|
+
`;
|
|
502
|
+
marker.textContent = showLabels ? `${markerId}` : '';
|
|
503
|
+
} else if (markerStyle === 'outline') {
|
|
504
|
+
marker.style.cssText = `
|
|
505
|
+
position: fixed;
|
|
506
|
+
top: ${rect.top}px;
|
|
507
|
+
left: ${rect.left}px;
|
|
508
|
+
width: ${rect.width}px;
|
|
509
|
+
height: ${rect.height}px;
|
|
510
|
+
border: 2px solid ${bgColor};
|
|
511
|
+
border-radius: 4px;
|
|
512
|
+
box-shadow: 0 0 0 1px rgba(255,255,255,0.5);
|
|
513
|
+
`;
|
|
514
|
+
if (showLabels) {
|
|
515
|
+
const label = document.createElement('span');
|
|
516
|
+
label.style.cssText = `
|
|
517
|
+
position: absolute;
|
|
518
|
+
top: -18px;
|
|
519
|
+
left: -2px;
|
|
520
|
+
background: ${bgColor};
|
|
521
|
+
color: white;
|
|
522
|
+
font: bold 10px system-ui;
|
|
523
|
+
padding: 1px 4px;
|
|
524
|
+
border-radius: 2px;
|
|
525
|
+
`;
|
|
526
|
+
label.textContent = markerId;
|
|
527
|
+
marker.appendChild(label);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
markerContainer.appendChild(marker);
|
|
532
|
+
markerMap.set(markerId, el);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
markersEnabled = true;
|
|
536
|
+
return markerMap;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Disable visual markers
|
|
541
|
+
*/
|
|
542
|
+
export function disableVisualMarkers() {
|
|
543
|
+
if (markerContainer) {
|
|
544
|
+
markerContainer.remove();
|
|
545
|
+
markerContainer = null;
|
|
546
|
+
}
|
|
547
|
+
markerMap.clear();
|
|
548
|
+
markersEnabled = false;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Get element by visual marker ID
|
|
553
|
+
* @param {string} markerId - Marker ID (e.g., 'B1', 'I2')
|
|
554
|
+
* @returns {HTMLElement|null}
|
|
555
|
+
*/
|
|
556
|
+
export function getMarkerElement(markerId) {
|
|
557
|
+
return markerMap.get(markerId) || null;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Get all current marker mappings
|
|
562
|
+
* @returns {Object} Object mapping marker IDs to element info
|
|
563
|
+
*/
|
|
564
|
+
export function getMarkerMap() {
|
|
565
|
+
const result = {};
|
|
566
|
+
for (const [id, el] of markerMap) {
|
|
567
|
+
result[id] = {
|
|
568
|
+
tag: el.tagName.toLowerCase(),
|
|
569
|
+
label: getAccessibleName(el),
|
|
570
|
+
actions: getAvailableActions(el)
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
return result;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// ============================================
|
|
577
|
+
// 2026 MCP ACTIONS (Anthropic/Google Standard)
|
|
578
|
+
// ============================================
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Get available actions in MCP (Model Context Protocol) compatible format.
|
|
582
|
+
* This is the emerging standard for agent-tool communication in 2026.
|
|
583
|
+
*
|
|
584
|
+
* @returns {Object} MCP-compatible action schema
|
|
585
|
+
*
|
|
586
|
+
* @example
|
|
587
|
+
* const actions = microUI.getMCPActions();
|
|
588
|
+
* // Returns:
|
|
589
|
+
* // {
|
|
590
|
+
* // name: "microui",
|
|
591
|
+
* // description: "Interact with microUI web components",
|
|
592
|
+
* // actions: [
|
|
593
|
+
* // { name: "click_button", parameters: { selector: {...} } },
|
|
594
|
+
* // { name: "fill_input", parameters: { selector: {...}, value: {...} } }
|
|
595
|
+
* // ]
|
|
596
|
+
* // }
|
|
597
|
+
*/
|
|
598
|
+
export function getMCPActions() {
|
|
599
|
+
return {
|
|
600
|
+
name: 'microui',
|
|
601
|
+
version: '3.4.0',
|
|
602
|
+
description: 'Interact with microUI Material Design 3 web components',
|
|
603
|
+
actions: [
|
|
604
|
+
{
|
|
605
|
+
name: 'click_button',
|
|
606
|
+
description: 'Click a button element',
|
|
607
|
+
parameters: {
|
|
608
|
+
selector: {
|
|
609
|
+
type: 'string',
|
|
610
|
+
description: 'CSS selector, marker ID (e.g., "B1"), or label text',
|
|
611
|
+
required: true
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
name: 'fill_input',
|
|
617
|
+
description: 'Fill an input or textarea with text',
|
|
618
|
+
parameters: {
|
|
619
|
+
selector: {
|
|
620
|
+
type: 'string',
|
|
621
|
+
description: 'CSS selector, marker ID (e.g., "I1"), or label text',
|
|
622
|
+
required: true
|
|
623
|
+
},
|
|
624
|
+
value: {
|
|
625
|
+
type: 'string',
|
|
626
|
+
description: 'Text to enter',
|
|
627
|
+
required: true
|
|
628
|
+
},
|
|
629
|
+
clear: {
|
|
630
|
+
type: 'boolean',
|
|
631
|
+
description: 'Clear existing content first',
|
|
632
|
+
default: true
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
name: 'toggle_checkbox',
|
|
638
|
+
description: 'Toggle a checkbox or switch',
|
|
639
|
+
parameters: {
|
|
640
|
+
selector: {
|
|
641
|
+
type: 'string',
|
|
642
|
+
description: 'CSS selector, marker ID, or label text',
|
|
643
|
+
required: true
|
|
644
|
+
},
|
|
645
|
+
checked: {
|
|
646
|
+
type: 'boolean',
|
|
647
|
+
description: 'Target state (true=checked, false=unchecked)',
|
|
648
|
+
required: false
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
name: 'select_option',
|
|
654
|
+
description: 'Select an option in a dropdown',
|
|
655
|
+
parameters: {
|
|
656
|
+
selector: {
|
|
657
|
+
type: 'string',
|
|
658
|
+
description: 'CSS selector for dropdown',
|
|
659
|
+
required: true
|
|
660
|
+
},
|
|
661
|
+
value: {
|
|
662
|
+
type: 'string',
|
|
663
|
+
description: 'Option value or text to select',
|
|
664
|
+
required: true
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
name: 'open_modal',
|
|
670
|
+
description: 'Open a modal dialog',
|
|
671
|
+
parameters: {
|
|
672
|
+
selector: {
|
|
673
|
+
type: 'string',
|
|
674
|
+
description: 'CSS selector for modal',
|
|
675
|
+
required: true
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
name: 'close_modal',
|
|
681
|
+
description: 'Close a modal dialog',
|
|
682
|
+
parameters: {
|
|
683
|
+
selector: {
|
|
684
|
+
type: 'string',
|
|
685
|
+
description: 'CSS selector for modal',
|
|
686
|
+
required: true
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
name: 'select_tab',
|
|
692
|
+
description: 'Select a tab by index or label',
|
|
693
|
+
parameters: {
|
|
694
|
+
tabs_selector: {
|
|
695
|
+
type: 'string',
|
|
696
|
+
description: 'CSS selector for mu-tabs container',
|
|
697
|
+
required: true
|
|
698
|
+
},
|
|
699
|
+
index: {
|
|
700
|
+
type: 'number',
|
|
701
|
+
description: 'Tab index (0-based)',
|
|
702
|
+
required: false
|
|
703
|
+
},
|
|
704
|
+
label: {
|
|
705
|
+
type: 'string',
|
|
706
|
+
description: 'Tab label text',
|
|
707
|
+
required: false
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
name: 'get_component_tree',
|
|
713
|
+
description: 'Get structured tree of all microUI components',
|
|
714
|
+
parameters: {
|
|
715
|
+
visible_only: {
|
|
716
|
+
type: 'boolean',
|
|
717
|
+
description: 'Only include visible components',
|
|
718
|
+
default: true
|
|
719
|
+
},
|
|
720
|
+
interactive_only: {
|
|
721
|
+
type: 'boolean',
|
|
722
|
+
description: 'Only include interactive components',
|
|
723
|
+
default: false
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
name: 'enable_visual_markers',
|
|
729
|
+
description: 'Enable visual markers for screenshot parsing',
|
|
730
|
+
parameters: {
|
|
731
|
+
style: {
|
|
732
|
+
type: 'string',
|
|
733
|
+
enum: ['badge', 'outline'],
|
|
734
|
+
description: 'Marker visual style',
|
|
735
|
+
default: 'badge'
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
name: 'confirm_dialog',
|
|
741
|
+
description: 'Respond to a confirmation dialog',
|
|
742
|
+
parameters: {
|
|
743
|
+
action: {
|
|
744
|
+
type: 'string',
|
|
745
|
+
enum: ['confirm', 'cancel'],
|
|
746
|
+
description: 'Whether to confirm or cancel',
|
|
747
|
+
required: true
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
]
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// Export for global access
|
|
756
|
+
export const AgentAPI = {
|
|
757
|
+
getMuComponentTree,
|
|
758
|
+
describe,
|
|
759
|
+
getRegisteredComponents,
|
|
760
|
+
findByLabel,
|
|
761
|
+
getAccessibleName,
|
|
762
|
+
getAvailableActions,
|
|
763
|
+
getComponentState,
|
|
764
|
+
// 2026 Visual Markers
|
|
765
|
+
enableVisualMarkers,
|
|
766
|
+
disableVisualMarkers,
|
|
767
|
+
getMarkerElement,
|
|
768
|
+
getMarkerMap,
|
|
769
|
+
// 2026 MCP Actions
|
|
770
|
+
getMCPActions
|
|
771
|
+
};
|