microui-wc 0.1.1 → 0.1.2
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/AGENTS.md +71 -71
- package/CHANGELOG.md +1 -1
- package/README.md +14 -9
- package/dist/AGENTS.md +71 -71
- package/dist/README.md +14 -9
- package/dist/microui.css +1 -1
- package/dist/microui.esm.js.map +1 -1
- package/dist/microui.min.js.map +1 -1
- package/docs/getting-started.md +3 -3
- package/package.json +39 -11
- package/src/components/mu-schema-form.js +1 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -33
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
- package/.github/workflows/ci.yml +0 -42
- package/.github/workflows/deploy-pages.yml +0 -112
- package/CODE_OF_CONDUCT.md +0 -59
- package/CONTRIBUTING.md +0 -156
- package/SECURITY.md +0 -58
- package/app/.generated/routes/alerts.js +0 -8
- package/app/.generated/routes/avatars.js +0 -8
- package/app/.generated/routes/badges.js +0 -8
- package/app/.generated/routes/buttons.js +0 -10
- package/app/.generated/routes/cards.js +0 -10
- package/app/.generated/routes/checkboxes.js +0 -9
- package/app/.generated/routes/chips.js +0 -8
- package/app/.generated/routes/dropdowns.js +0 -9
- package/app/.generated/routes/home.js +0 -7
- package/app/.generated/routes/icons.js +0 -9
- package/app/.generated/routes/inputs.js +0 -10
- package/app/.generated/routes/installation.js +0 -7
- package/app/.generated/routes/layout.js +0 -9
- package/app/.generated/routes/modals.js +0 -9
- package/app/.generated/routes/navbar.js +0 -7
- package/app/.generated/routes/progress.js +0 -9
- package/app/.generated/routes/radios.js +0 -9
- package/app/.generated/routes/switches.js +0 -9
- package/app/.generated/routes/tabs.js +0 -8
- package/app/.generated/routes/toasts.js +0 -9
- package/app/index.html +0 -67
- package/app/pages/alerts.html +0 -23
- package/app/pages/avatars.html +0 -22
- package/app/pages/badges.html +0 -22
- package/app/pages/buttons.html +0 -71
- package/app/pages/cards.html +0 -54
- package/app/pages/checkboxes.html +0 -39
- package/app/pages/chips.html +0 -23
- package/app/pages/dropdowns.html +0 -41
- package/app/pages/home.html +0 -59
- package/app/pages/icons.html +0 -29
- package/app/pages/inputs.html +0 -66
- package/app/pages/installation.html +0 -34
- package/app/pages/layout.html +0 -30
- package/app/pages/modals.html +0 -21
- package/app/pages/navbar.html +0 -22
- package/app/pages/progress.html +0 -35
- package/app/pages/radios.html +0 -40
- package/app/pages/switches.html +0 -39
- package/app/pages/tabs.html +0 -30
- package/app/pages/toasts.html +0 -22
- package/app-dist/index.html +0 -67
- package/app-dist/pages/alerts.html +0 -23
- package/app-dist/pages/avatars.html +0 -22
- package/app-dist/pages/badges.html +0 -22
- package/app-dist/pages/buttons.html +0 -71
- package/app-dist/pages/cards.html +0 -54
- package/app-dist/pages/checkboxes.html +0 -39
- package/app-dist/pages/chips.html +0 -23
- package/app-dist/pages/dropdowns.html +0 -41
- package/app-dist/pages/home.html +0 -59
- package/app-dist/pages/icons.html +0 -29
- package/app-dist/pages/inputs.html +0 -66
- package/app-dist/pages/installation.html +0 -34
- package/app-dist/pages/layout.html +0 -30
- package/app-dist/pages/modals.html +0 -21
- package/app-dist/pages/navbar.html +0 -22
- package/app-dist/pages/progress.html +0 -35
- package/app-dist/pages/radios.html +0 -40
- package/app-dist/pages/switches.html +0 -39
- package/app-dist/pages/tabs.html +0 -30
- package/app-dist/pages/toasts.html +0 -22
- package/app-dist/pages.json +0 -217
- package/app-dist/routes/alerts.js +0 -5
- package/app-dist/routes/avatars.js +0 -1
- package/app-dist/routes/badges.js +0 -1
- package/app-dist/routes/buttons.js +0 -1
- package/app-dist/routes/cards.js +0 -1
- package/app-dist/routes/checkboxes.js +0 -9
- package/app-dist/routes/chips.js +0 -4
- package/app-dist/routes/chunk-019e5e2f.js +0 -5
- package/app-dist/routes/chunk-0m4j19yd.js +0 -2
- package/app-dist/routes/chunk-0tmmp5q0.js +0 -1
- package/app-dist/routes/chunk-10xn709r.js +0 -1
- package/app-dist/routes/chunk-15m2qcda.js +0 -2
- package/app-dist/routes/chunk-1bh8g23n.js +0 -1
- package/app-dist/routes/chunk-1vg0v937.js +0 -1
- package/app-dist/routes/chunk-1zvcgy3j.js +0 -1
- package/app-dist/routes/chunk-2afb0861.js +0 -1
- package/app-dist/routes/chunk-2c6ttpzt.js +0 -5
- package/app-dist/routes/chunk-3dy30fhs.js +0 -1
- package/app-dist/routes/chunk-426dnces.js +0 -13
- package/app-dist/routes/chunk-44kgxery.js +0 -1
- package/app-dist/routes/chunk-47fdnejd.js +0 -33
- package/app-dist/routes/chunk-49a6t2vq.js +0 -1
- package/app-dist/routes/chunk-4fe1rm5b.js +0 -1
- package/app-dist/routes/chunk-4ggmvkta.js +0 -33
- package/app-dist/routes/chunk-4vkz81q7.js +0 -33
- package/app-dist/routes/chunk-4w4tmj8f.js +0 -31
- package/app-dist/routes/chunk-532s62kr.js +0 -31
- package/app-dist/routes/chunk-5hm3bssy.js +0 -33
- package/app-dist/routes/chunk-5vrh24hc.js +0 -1
- package/app-dist/routes/chunk-61pcg25a.js +0 -1
- package/app-dist/routes/chunk-6nfhygvf.js +0 -1
- package/app-dist/routes/chunk-700e7je6.js +0 -33
- package/app-dist/routes/chunk-7fsn17kg.js +0 -1
- package/app-dist/routes/chunk-7k789b32.js +0 -1
- package/app-dist/routes/chunk-7r46q0ys.js +0 -36
- package/app-dist/routes/chunk-86fmc1fr.js +0 -5
- package/app-dist/routes/chunk-8qth37vw.js +0 -1
- package/app-dist/routes/chunk-924wv8n0.js +0 -1
- package/app-dist/routes/chunk-9mbhgxk9.js +0 -1
- package/app-dist/routes/chunk-a216hyd9.js +0 -1
- package/app-dist/routes/chunk-akzxykh9.js +0 -33
- package/app-dist/routes/chunk-b3dcvy8c.js +0 -1
- package/app-dist/routes/chunk-b74zahz5.js +0 -31
- package/app-dist/routes/chunk-bftj53p2.js +0 -5
- package/app-dist/routes/chunk-c01hnz3e.js +0 -1
- package/app-dist/routes/chunk-d8pvv5km.js +0 -1
- package/app-dist/routes/chunk-dev0aezr.js +0 -2
- package/app-dist/routes/chunk-dh6vnv0e.js +0 -1
- package/app-dist/routes/chunk-dn2cbpva.js +0 -36
- package/app-dist/routes/chunk-dvn0my90.js +0 -1
- package/app-dist/routes/chunk-dvq8mnve.js +0 -36
- package/app-dist/routes/chunk-e8c2gc4d.js +0 -5
- package/app-dist/routes/chunk-ejf9ak2x.js +0 -1
- package/app-dist/routes/chunk-f083m55s.js +0 -1
- package/app-dist/routes/chunk-fnrj28s1.js +0 -31
- package/app-dist/routes/chunk-fvg3yjdp.js +0 -31
- package/app-dist/routes/chunk-g7k381n1.js +0 -1
- package/app-dist/routes/chunk-h01kq2ae.js +0 -13
- package/app-dist/routes/chunk-h4dk761v.js +0 -5
- package/app-dist/routes/chunk-hmx91z2x.js +0 -5
- package/app-dist/routes/chunk-hxbg4m42.js +0 -36
- package/app-dist/routes/chunk-jbjnfp2b.js +0 -2
- package/app-dist/routes/chunk-jxtz5vv6.js +0 -36
- package/app-dist/routes/chunk-jxzcs0ey.js +0 -36
- package/app-dist/routes/chunk-kt7wwhcx.js +0 -1
- package/app-dist/routes/chunk-kzptszyc.js +0 -33
- package/app-dist/routes/chunk-mhgca4w4.js +0 -2
- package/app-dist/routes/chunk-mhswxa20.js +0 -1
- package/app-dist/routes/chunk-n8zfeex6.js +0 -1
- package/app-dist/routes/chunk-pee47b2r.js +0 -1
- package/app-dist/routes/chunk-pesmw829.js +0 -1
- package/app-dist/routes/chunk-pgc4c6f3.js +0 -36
- package/app-dist/routes/chunk-q8egegm1.js +0 -1
- package/app-dist/routes/chunk-q9mn2qyq.js +0 -36
- package/app-dist/routes/chunk-qh0rtaf3.js +0 -5
- package/app-dist/routes/chunk-qqhmk6ye.js +0 -2
- package/app-dist/routes/chunk-qrxygmf7.js +0 -33
- package/app-dist/routes/chunk-r46yzksx.js +0 -36
- package/app-dist/routes/chunk-rgpbw2w0.js +0 -5
- package/app-dist/routes/chunk-rnpzv3d8.js +0 -2
- package/app-dist/routes/chunk-s5v8cv05.js +0 -2
- package/app-dist/routes/chunk-sbwn5bpc.js +0 -1
- package/app-dist/routes/chunk-sqbg8jbt.js +0 -33
- package/app-dist/routes/chunk-sv8dqnf7.js +0 -1
- package/app-dist/routes/chunk-t67sw3za.js +0 -1
- package/app-dist/routes/chunk-tjdpqwdf.js +0 -31
- package/app-dist/routes/chunk-tq2mfghg.js +0 -1
- package/app-dist/routes/chunk-ttn10vt6.js +0 -1
- package/app-dist/routes/chunk-v2hzpjxr.js +0 -1
- package/app-dist/routes/chunk-wfjjkw9y.js +0 -1
- package/app-dist/routes/chunk-wt8cxzmf.js +0 -31
- package/app-dist/routes/chunk-x45d372k.js +0 -5
- package/app-dist/routes/chunk-y3wsazkt.js +0 -1
- package/app-dist/routes/chunk-y7pmgc7t.js +0 -33
- package/app-dist/routes/chunk-zefdt2q3.js +0 -31
- package/app-dist/routes/dropdowns.js +0 -6
- package/app-dist/routes/home.js +0 -1
- package/app-dist/routes/icons.js +0 -1
- package/app-dist/routes/inputs.js +0 -12
- package/app-dist/routes/installation.js +0 -1
- package/app-dist/routes/layout.js +0 -1
- package/app-dist/routes/modals.js +0 -7
- package/app-dist/routes/navbar.js +0 -1
- package/app-dist/routes/progress.js +0 -1
- package/app-dist/routes/radios.js +0 -6
- package/app-dist/routes/switches.js +0 -6
- package/app-dist/routes/tabs.js +0 -1
- package/app-dist/routes/toasts.js +0 -16
- 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 +0 -312
- package/bunfig.toml +0 -4
- package/custom-elements.json +0 -1916
- package/demo/api/sample-data.json +0 -38
- package/demo/content/alerts.html +0 -115
- package/demo/content/avatars.html +0 -70
- package/demo/content/badges.html +0 -65
- package/demo/content/buttons.html +0 -188
- package/demo/content/callouts.html +0 -91
- package/demo/content/cards.html +0 -121
- package/demo/content/checkboxes.html +0 -178
- package/demo/content/chips.html +0 -67
- package/demo/content/codeblocks.html +0 -101
- package/demo/content/confirms.html +0 -115
- package/demo/content/datatables.html +0 -149
- package/demo/content/dividers.html +0 -119
- package/demo/content/dropdowns.html +0 -89
- package/demo/content/enterprise.html +0 -252
- package/demo/content/home.html +0 -149
- package/demo/content/icons.html +0 -89
- package/demo/content/inputs.html +0 -135
- package/demo/content/installation.html +0 -16
- package/demo/content/layout.html +0 -136
- package/demo/content/modals.html +0 -141
- package/demo/content/navbar.html +0 -70
- package/demo/content/progress.html +0 -119
- package/demo/content/radios.html +0 -88
- package/demo/content/skeletons.html +0 -109
- package/demo/content/spinners.html +0 -96
- package/demo/content/switches.html +0 -84
- package/demo/content/tables.html +0 -124
- package/demo/content/tabs.html +0 -85
- package/demo/content/toasts.html +0 -116
- package/demo/content/tooltips.html +0 -107
- package/demo/content/virtual-lists.html +0 -233
- package/demo/favicon.ico +0 -0
- package/demo/favicon.png +0 -0
- package/demo/full.html +0 -52
- package/demo/iife.html +0 -46
- package/demo/manifest.json +0 -34
- package/demo/pages/datatable-demo.html +0 -237
- package/demo/pages/prompt-ui-demo.html +0 -218
- package/demo/pages/responsive-demo.html +0 -122
- package/demo/pages/schema-form-demo.html +0 -270
- package/demo/robots.txt +0 -6
- package/demo/shell.html +0 -712
- package/demo/sw.js +0 -387
- package/lighthouse-audit.mjs +0 -113
- package/scripts/analyze-components.js +0 -105
- package/scripts/build-app.js +0 -193
- package/scripts/build-framework.js +0 -444
- package/scripts/build-utils.js +0 -101
- package/scripts/test-isolated.js +0 -151
- package/server.js +0 -256
- package/tests/agents/agent-integration.test.js +0 -76
- package/tests/benchmark.html +0 -296
- package/tests/build/scan-components.test.js +0 -173
- package/tests/components/all-components.test.js +0 -245
- package/tests/components/all-missing-components.test.js +0 -574
- package/tests/components/mu-alert.test.js +0 -113
- package/tests/components/mu-avatar.test.js +0 -148
- package/tests/components/mu-badge.test.js +0 -92
- package/tests/components/mu-button.test.js +0 -112
- package/tests/components/mu-card.test.js +0 -89
- package/tests/components/mu-checkbox.test.js +0 -158
- package/tests/components/mu-chip.test.js +0 -118
- package/tests/components/mu-container.test.js +0 -120
- package/tests/components/mu-divider.test.js +0 -98
- package/tests/components/mu-drawer-item.test.js +0 -199
- package/tests/components/mu-drawer.test.js +0 -96
- package/tests/components/mu-dropdown.test.js +0 -125
- package/tests/components/mu-form.test.js +0 -138
- package/tests/components/mu-grid.test.js +0 -135
- package/tests/components/mu-icon.test.js +0 -110
- package/tests/components/mu-input.test.js +0 -131
- package/tests/components/mu-lazy.test.js +0 -103
- package/tests/components/mu-modal.test.js +0 -275
- package/tests/components/mu-navbar.test.js +0 -101
- package/tests/components/mu-progress.test.js +0 -115
- package/tests/components/mu-radio.test.js +0 -114
- package/tests/components/mu-repeat.test.js +0 -106
- package/tests/components/mu-sidebar.test.js +0 -126
- package/tests/components/mu-skeleton.test.js +0 -162
- package/tests/components/mu-stack.test.js +0 -143
- package/tests/components/mu-switch.test.js +0 -292
- package/tests/components/mu-table.test.js +0 -124
- package/tests/components/mu-tabs.test.js +0 -104
- package/tests/components/mu-textarea.test.js +0 -115
- package/tests/components/mu-toast.test.js +0 -321
- package/tests/components/mu-tooltip.test.js +0 -133
- package/tests/components/mu-virtual-list.test.js +0 -109
- package/tests/core/MuElement.test.js +0 -120
- package/tests/core/agent-api.test.js +0 -125
- package/tests/core/all-core-modules.test.js +0 -442
- package/tests/core/bus.test.js +0 -364
- package/tests/core/component-schema.test.js +0 -160
- package/tests/core/feature-registry.test.js +0 -198
- package/tests/core/form-state.test.js +0 -167
- package/tests/core/http.test.js +0 -119
- package/tests/core/keyboard.test.js +0 -319
- package/tests/core/layers.test.js +0 -129
- package/tests/core/namespaced-stores.test.js +0 -114
- package/tests/core/render.test.js +0 -121
- package/tests/core/ripple.test.js +0 -131
- package/tests/core/router.test.js +0 -89
- package/tests/core/scheduler.test.js +0 -121
- package/tests/core/signals.test.js +0 -128
- package/tests/core/store.test.js +0 -171
- package/tests/core/transitions.test.js +0 -82
- package/tests/e2e/accessibility-harness.html +0 -58
- package/tests/e2e/accessibility.test.js +0 -401
- package/tests/e2e/agent-features.test.js +0 -372
- package/tests/e2e/card-spacing.test.js +0 -287
- package/tests/e2e/components.test.js +0 -439
- package/tests/e2e/demo-routes.test.js +0 -478
- package/tests/e2e/layout-css-fallback.test.js +0 -334
- package/tests/e2e/mu-alert.e2e.test.js +0 -111
- package/tests/e2e/mu-checkbox.test.js +0 -489
- package/tests/e2e/mu-chip.test.js +0 -347
- package/tests/e2e/mu-form.test.js +0 -499
- package/tests/e2e/mu-icon.test.js +0 -114
- package/tests/e2e/mu-radio.test.js +0 -113
- package/tests/e2e/mu-skeleton.test.js +0 -140
- package/tests/e2e/mu-switch.test.js +0 -415
- package/tests/e2e/mu-tabs.test.js +0 -494
- package/tests/e2e/mu-textarea.test.js +0 -242
- package/tests/e2e/mu-virtual-list.test.js +0 -427
- package/tests/e2e/perf-memory.test.js +0 -161
- package/tests/e2e/puppeteer-helper.js +0 -137
- package/tests/e2e/puppeteer.test.js +0 -226
- package/tests/e2e/pwa.test.js +0 -261
- package/tests/e2e/test-harness.html +0 -319
- package/tests/manual/test-components.html +0 -120
- package/tests/memory-test.html +0 -309
- package/tests/setup-dom.js +0 -93
- package/tests/visual-test.html +0 -301
package/AGENTS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **SOTA reference for AI coding assistants.** This document is optimized for LLMs generating microUI code.
|
|
4
4
|
|
|
5
|
-
## 🚨
|
|
5
|
+
## 🚨 MANDATORY RULES
|
|
6
6
|
|
|
7
7
|
> [!CAUTION]
|
|
8
8
|
> These rules can NEVER be violated. Any code that violates these rules must be rejected.
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
### ❌ NO SHADOW DOM
|
|
11
11
|
|
|
12
12
|
**microUI must NEVER use Shadow DOM.** All components must:
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
13
|
+
- Use Light DOM (normal DOM)
|
|
14
|
+
- Insert elements directly into the document
|
|
15
|
+
- Use CSS classes with `mu-` prefix for encapsulation
|
|
16
|
+
- Never use `this.attachShadow()` or `this.shadowRoot`
|
|
17
17
|
|
|
18
18
|
```javascript
|
|
19
|
-
// ❌ FORBIDDEN -
|
|
19
|
+
// ❌ FORBIDDEN - Never use this
|
|
20
20
|
this.attachShadow({ mode: 'open' });
|
|
21
21
|
this.shadowRoot.innerHTML = '...';
|
|
22
22
|
|
|
@@ -25,12 +25,12 @@ this.innerHTML = '...';
|
|
|
25
25
|
this.classList.add('mu-component');
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
### 🧪 TEST ISOLATION
|
|
28
|
+
### 🧪 MANDATORY TEST ISOLATION
|
|
29
29
|
|
|
30
|
-
**Tests MUST be run with `test-isolated.js`**, never with `bun test`
|
|
30
|
+
**Tests MUST be run with `test-isolated.js`**, never with `bun test` directly.
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
# ❌
|
|
33
|
+
# ❌ WRONG - Tests fail due to linkedom globalThis pollution
|
|
34
34
|
bun test tests/components
|
|
35
35
|
|
|
36
36
|
# ✅ CORRECT - Each test in separate process
|
|
@@ -40,15 +40,15 @@ bun run scripts/test-isolated.js
|
|
|
40
40
|
bun run test:e2e
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
**Why?** linkedom (used to simulate DOM in unit tests) pollutes `globalThis`
|
|
43
|
+
**Why?** linkedom (used to simulate DOM in unit tests) pollutes `globalThis` and the custom elements registry. When tests are run in parallel in the same process, the registrations conflict.
|
|
44
44
|
|
|
45
45
|
---
|
|
46
46
|
|
|
47
47
|
## 🛠️ COMPONENT DEVELOPMENT GUIDELINES
|
|
48
48
|
|
|
49
|
-
> **
|
|
49
|
+
> **Mandatory guidelines for creating new microUI components.** Following these rules prevents memory leaks, crashes, and ensures consistency with the framework.
|
|
50
50
|
|
|
51
|
-
### 📋
|
|
51
|
+
### 📋 Complete Component Template
|
|
52
52
|
|
|
53
53
|
```javascript
|
|
54
54
|
/**
|
|
@@ -59,7 +59,7 @@ bun run test:e2e
|
|
|
59
59
|
*/
|
|
60
60
|
|
|
61
61
|
import { MuElement, define } from '../core/MuElement.js';
|
|
62
|
-
import { escapeHTML } from '../core/utils.js'; //
|
|
62
|
+
import { escapeHTML } from '../core/utils.js'; // For user-facing content
|
|
63
63
|
|
|
64
64
|
export class MuExample extends MuElement {
|
|
65
65
|
static get observedAttributes() {
|
|
@@ -75,17 +75,17 @@ export class MuExample extends MuElement {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// ========================
|
|
78
|
-
// LIFECYCLE (
|
|
78
|
+
// LIFECYCLE (MANDATORY)
|
|
79
79
|
// ========================
|
|
80
80
|
|
|
81
81
|
connectedCallback() {
|
|
82
|
-
super.connectedCallback(); // ⚠️
|
|
82
|
+
super.connectedCallback(); // ⚠️ MANDATORY - Initializes AbortController
|
|
83
83
|
this.render();
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
disconnectedCallback() {
|
|
87
|
-
super.disconnectedCallback(); // ⚠️
|
|
88
|
-
// Cleanup subscriptions
|
|
87
|
+
super.disconnectedCallback(); // ⚠️ MANDATORY if using timer/subscriptions
|
|
88
|
+
// Cleanup manual subscriptions (e.g. breakpoints.subscribe)
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
attributeChangedCallback(name, oldVal, newVal) {
|
|
@@ -115,7 +115,7 @@ export class MuExample extends MuElement {
|
|
|
115
115
|
// ========================
|
|
116
116
|
|
|
117
117
|
render() {
|
|
118
|
-
// ✅
|
|
118
|
+
// ✅ ALWAYS escape user-facing content
|
|
119
119
|
this.innerHTML = `
|
|
120
120
|
<div class="mu-example">
|
|
121
121
|
<label>${escapeHTML(this.label)}</label>
|
|
@@ -174,7 +174,7 @@ export class MuExample extends MuElement {
|
|
|
174
174
|
|
|
175
175
|
_validate() {
|
|
176
176
|
if (!this.label) {
|
|
177
|
-
// ✅
|
|
177
|
+
// ✅ Report errors for AI agent debugging
|
|
178
178
|
this.logError('MISSING_LABEL', 'mu-example requires a label attribute');
|
|
179
179
|
}
|
|
180
180
|
}
|
|
@@ -189,57 +189,57 @@ if (!customElements.get('mu-example')) {
|
|
|
189
189
|
### ⚠️ ANTI-PATTERN: What NEVER to Do
|
|
190
190
|
|
|
191
191
|
```javascript
|
|
192
|
-
// ❌ FORBIDDEN: addEventListener
|
|
192
|
+
// ❌ FORBIDDEN: Direct addEventListener (memory leak)
|
|
193
193
|
this.querySelector('button').addEventListener('click', handler);
|
|
194
194
|
|
|
195
195
|
// ❌ FORBIDDEN: setTimeout/setInterval raw (memory leak)
|
|
196
196
|
setTimeout(() => this.update(), 1000);
|
|
197
197
|
setInterval(() => this.poll(), 5000);
|
|
198
198
|
|
|
199
|
-
// ❌ FORBIDDEN:
|
|
199
|
+
// ❌ FORBIDDEN: No super.connectedCallback() (AbortController not initialized)
|
|
200
200
|
connectedCallback() {
|
|
201
|
-
this.render(); // this.listen()
|
|
201
|
+
this.render(); // this.listen() won't work!
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
// ❌ FORBIDDEN: innerHTML
|
|
204
|
+
// ❌ FORBIDDEN: innerHTML without escaping (XSS vulnerability)
|
|
205
205
|
this.innerHTML = `<div>${userInput}</div>`;
|
|
206
206
|
|
|
207
|
-
// ❌ FORBIDDEN: removeEventListener
|
|
207
|
+
// ❌ FORBIDDEN: removeEventListener with arrow function (never works)
|
|
208
208
|
window.removeEventListener('resize', () => this.handleResize());
|
|
209
209
|
|
|
210
|
-
// ❌ FORBIDDEN: Temporal dead zone
|
|
210
|
+
// ❌ FORBIDDEN: Temporal dead zone with setTimeout
|
|
211
211
|
const id = setTimeout(() => { this._timers.delete(id); }, delay);
|
|
212
212
|
|
|
213
213
|
// ❌ FORBIDDEN: Shadow DOM
|
|
214
214
|
this.attachShadow({ mode: 'open' });
|
|
215
215
|
|
|
216
|
-
// ❌ FORBIDDEN: DOM Teleportation
|
|
216
|
+
// ❌ FORBIDDEN: DOM Teleportation without resetting listener flag (Bug Jan 2026)
|
|
217
217
|
// When a component moves ITSELF in the DOM (e.g. appendChild(this)),
|
|
218
|
-
// disconnectedCallback
|
|
218
|
+
// disconnectedCallback aborts listeners but the flag prevents re-registration
|
|
219
219
|
connectedCallback() {
|
|
220
|
-
if (!this._listenerSetup) { // ⚠️
|
|
220
|
+
if (!this._listenerSetup) { // ⚠️ Flag stays true after disconnect!
|
|
221
221
|
this._listenerSetup = true;
|
|
222
|
-
this.listen(this, 'click', handler); //
|
|
222
|
+
this.listen(this, 'click', handler); // Lost after teleportation
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
|
-
// ✅ CORRECT: Reset
|
|
225
|
+
// ✅ CORRECT: Reset flag in disconnectedCallback
|
|
226
226
|
disconnectedCallback() {
|
|
227
227
|
super.disconnectedCallback();
|
|
228
|
-
this._listenerSetup = false; //
|
|
228
|
+
this._listenerSetup = false; // Allows re-registration after move
|
|
229
229
|
}
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
-
### ✅
|
|
232
|
+
### ✅ MANDATORY PATTERNS
|
|
233
233
|
|
|
234
234
|
| Pattern | Method | Why |
|
|
235
235
|
|---------|--------|--------|
|
|
236
236
|
| **Event Listeners** | `this.listen(target, type, handler)` | Auto-cleanup via AbortController |
|
|
237
|
-
| **Timers** | `this.setTimeout()` / `this.setInterval()` | Auto-cleanup
|
|
238
|
-
| **XSS Prevention** | `escapeHTML(userInput)` |
|
|
239
|
-
| **Keyboard A11y** | `this.setupActivation(callback)` |
|
|
240
|
-
| **AI Debugging** | `this.logError(code, message)` |
|
|
241
|
-
| **Lifecycle** | `super.connectedCallback()` |
|
|
242
|
-
| **DOM Teleportation** | Reset flag in `disconnectedCallback()` |
|
|
237
|
+
| **Timers** | `this.setTimeout()` / `this.setInterval()` | Auto-cleanup on disconnectedCallback |
|
|
238
|
+
| **XSS Prevention** | `escapeHTML(userInput)` | Prevents injection in innerHTML |
|
|
239
|
+
| **Keyboard A11y** | `this.setupActivation(callback)` | Handles Enter/Space for interactive elements |
|
|
240
|
+
| **AI Debugging** | `this.logError(code, message)` | Structured errors for AI agents |
|
|
241
|
+
| **Lifecycle** | `super.connectedCallback()` | Initializes AbortController for this.listen() |
|
|
242
|
+
| **DOM Teleportation** | Reset flag in `disconnectedCallback()` | Prevents orphan listeners after move |
|
|
243
243
|
|
|
244
244
|
### 🚀 SOTA Patterns (Feb 2026)
|
|
245
245
|
|
|
@@ -247,15 +247,15 @@ Modern patterns that should be used for new components and migrations.
|
|
|
247
247
|
|
|
248
248
|
#### ✅ Performance CSS (Implemented)
|
|
249
249
|
|
|
250
|
-
|
|
250
|
+
The framework applies **by default** the following optimizations:
|
|
251
251
|
|
|
252
|
-
|
|
|
252
|
+
| Technique | File | Benefit |
|
|
253
253
|
|---------|------|-----------|
|
|
254
|
-
| `will-change` | animations.css | GPU compositor hints
|
|
255
|
-
| `CSS contain` | layout.css, components.css |
|
|
256
|
-
| `content-visibility: auto` | components.css | Skip rendering off-screen
|
|
257
|
-
| Speculation Rules API | shell.html |
|
|
258
|
-
| View Transitions API | shell.html |
|
|
254
|
+
| `will-change` | animations.css | GPU compositor hints for 13+ animation classes |
|
|
255
|
+
| `CSS contain` | layout.css, components.css | Isolates repaint scope for mu-layout, modals |
|
|
256
|
+
| `content-visibility: auto` | components.css | Skip rendering off-screen for mu-example |
|
|
257
|
+
| Speculation Rules API | shell.html | Predictive route bundle prefetch |
|
|
258
|
+
| View Transitions API | shell.html | Smooth page transitions in SPA |
|
|
259
259
|
|
|
260
260
|
**Lighthouse Score**: 98/100 Performance, 100/100 Accessibility/BP/SEO
|
|
261
261
|
|
|
@@ -276,37 +276,37 @@ mu-layout {
|
|
|
276
276
|
}
|
|
277
277
|
```
|
|
278
278
|
|
|
279
|
-
#### ✅ Native `<dialog>`
|
|
280
|
-
**mu-modal**
|
|
281
|
-
-
|
|
282
|
-
-
|
|
283
|
-
- ESC key
|
|
284
|
-
- `::backdrop`
|
|
285
|
-
- `margin: auto`
|
|
279
|
+
#### ✅ Native `<dialog>` for Modal (COMPLETED)
|
|
280
|
+
**mu-modal** now uses native `<dialog>` with `showModal()`:
|
|
281
|
+
- Automatic top-layer (no manual z-index)
|
|
282
|
+
- Built-in focus trap
|
|
283
|
+
- Native ESC key handling
|
|
284
|
+
- Animated `::backdrop` scrim
|
|
285
|
+
- `margin: auto` for centering
|
|
286
286
|
|
|
287
287
|
```javascript
|
|
288
288
|
// ✅ SOTA: Native dialog
|
|
289
289
|
this.#dialog = document.createElement('dialog');
|
|
290
290
|
this.#dialog.showModal();
|
|
291
291
|
|
|
292
|
-
// ❌
|
|
292
|
+
// ❌ OLD: Position fixed + z-index + manual focus trap
|
|
293
293
|
this.style.cssText = 'position:fixed;z-index:9999;';
|
|
294
294
|
document.body.appendChild(this);
|
|
295
295
|
```
|
|
296
296
|
|
|
297
|
-
#### 🔜 Popover API (
|
|
298
|
-
|
|
297
|
+
#### 🔜 Popover API (CANDIDATES)
|
|
298
|
+
The following components could benefit from the **Popover API**:
|
|
299
299
|
|
|
300
|
-
|
|
|
300
|
+
| Component | Current Pattern | SOTA Migration |
|
|
301
301
|
|------------|----------------|----------------|
|
|
302
302
|
| `mu-dropdown` | Portal container + z-index | `popover` attribute |
|
|
303
303
|
| `mu-tooltip` | Position fixed + z-index | `popover` attribute |
|
|
304
304
|
|
|
305
|
-
**
|
|
306
|
-
-
|
|
307
|
-
- Top-layer (
|
|
305
|
+
**Popover API Benefits**:
|
|
306
|
+
- Automatic light-dismiss (click outside)
|
|
307
|
+
- Top-layer (no z-index issues)
|
|
308
308
|
- `showPopover()` / `hidePopover()` / `togglePopover()`
|
|
309
|
-
-
|
|
309
|
+
- Built-in keyboard accessibility
|
|
310
310
|
|
|
311
311
|
```html
|
|
312
312
|
<!-- SOTA: Declarative popover -->
|
|
@@ -316,27 +316,27 @@ I seguenti componenti potrebbero beneficiare della **Popover API**:
|
|
|
316
316
|
|
|
317
317
|
### 🔒 Security Checklist
|
|
318
318
|
|
|
319
|
-
|
|
319
|
+
Before completing a component, verify:
|
|
320
320
|
|
|
321
|
-
- [ ]
|
|
321
|
+
- [ ] All user-facing content uses `escapeHTML()`
|
|
322
322
|
- [ ] Interpolated attributes in innerHTML are escaped
|
|
323
323
|
- [ ] Slot content controlled (developer-provided) or escaped
|
|
324
|
-
- [ ]
|
|
324
|
+
- [ ] No `eval()`, `Function()`, `document.write()`
|
|
325
325
|
|
|
326
326
|
### ♿ Accessibility Checklist
|
|
327
327
|
|
|
328
|
-
- [ ]
|
|
329
|
-
- [ ]
|
|
330
|
-
- [ ] `setupActivation()`
|
|
331
|
-
- [ ] `aria-label`
|
|
332
|
-
- [ ]
|
|
328
|
+
- [ ] Interactive elements have `tabindex="0"`
|
|
329
|
+
- [ ] Appropriate ARIA role (`role="button"`, `role="menuitem"`, etc.)
|
|
330
|
+
- [ ] `setupActivation()` for keyboard activation (Enter/Space)
|
|
331
|
+
- [ ] `aria-label` or associated label for screen readers
|
|
332
|
+
- [ ] States (`aria-checked`, `aria-expanded`, etc.) dynamically updated
|
|
333
333
|
|
|
334
334
|
### 🧪 Testing Checklist
|
|
335
335
|
|
|
336
|
-
- [ ] Unit test
|
|
337
|
-
- [ ] E2E test
|
|
336
|
+
- [ ] Unit test with `bun run scripts/test-isolated.js`
|
|
337
|
+
- [ ] E2E test for real browser interactions
|
|
338
338
|
- [ ] Coverage ≥97%
|
|
339
|
-
- [ ] Test memory leak:
|
|
339
|
+
- [ ] Test memory leak: component added/removed from DOM leaves no listeners
|
|
340
340
|
|
|
341
341
|
---
|
|
342
342
|
|
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -6,15 +6,20 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>The AI-First Web Components Framework</strong><br>
|
|
9
|
-
<sub>49 Components •
|
|
9
|
+
<sub>49 Components • 868 Tests Passing • 100% Lighthouse • Zero Config</sub>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
|
-
<img src="https://img.shields.io/
|
|
13
|
+
<a href="https://www.npmjs.com/package/microui-wc"><img src="https://img.shields.io/npm/v/microui-wc?color=blue&label=npm" alt="npm version"></a>
|
|
14
|
+
<a href="https://github.com/GiuseppeScottoLavina/microUI/actions"><img src="https://img.shields.io/github/actions/workflow/status/GiuseppeScottoLavina/microUI/ci.yml?label=CI" alt="CI Status"></a>
|
|
14
15
|
<img src="https://img.shields.io/badge/lighthouse-100%25-brightgreen" alt="100% Lighthouse">
|
|
15
|
-
<img src="https://img.shields.io/
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
<a href="https://github.com/GiuseppeScottoLavina/microUI/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/microui-wc" alt="License"></a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
<a href="https://giuseppescottolavina.github.io/microUI/"><strong>🚀 Live Demo</strong></a> •
|
|
21
|
+
<a href="./docs/getting-started.md"><strong>📖 Docs</strong></a> •
|
|
22
|
+
<a href="./AGENTS.md"><strong>🤖 Agent Guide</strong></a>
|
|
18
23
|
</p>
|
|
19
24
|
|
|
20
25
|
---
|
|
@@ -27,7 +32,7 @@
|
|
|
27
32
|
| Native Web Components | ✅ | ❌ | ❌ | ❌ |
|
|
28
33
|
| AI Agent optimized | ✅ | ❌ | ❌ | ❌ |
|
|
29
34
|
| Config required | None | Babel, Webpack | Vite/CLI | Rollup |
|
|
30
|
-
|
|
|
35
|
+
| Bundle (gzipped) | **~59 KB** | ~44 KB | ~34 KB | ~4 KB |
|
|
31
36
|
| Learning curve | HTML | JSX + Hooks | SFC + Composition | Runes |
|
|
32
37
|
|
|
33
38
|
> **Stop reinventing the wheel.** microUI gives you production-ready components with Material Design 3, full accessibility, and perfect Lighthouse scores—out of the box.
|
|
@@ -177,7 +182,7 @@ if (breakpoints.isCompact) {
|
|
|
177
182
|
|
|
178
183
|
| Metric | Value |
|
|
179
184
|
|--------|-------|
|
|
180
|
-
| Unit tests | **
|
|
185
|
+
| Unit tests | **868 passing** |
|
|
181
186
|
| Test coverage | Components: 100% |
|
|
182
187
|
| Lighthouse Performance | **100** |
|
|
183
188
|
| Lighthouse Accessibility | **100** |
|
|
@@ -191,10 +196,10 @@ if (breakpoints.isCompact) {
|
|
|
191
196
|
|
|
192
197
|
```bash
|
|
193
198
|
# npm
|
|
194
|
-
npm install microui
|
|
199
|
+
npm install microui-wc
|
|
195
200
|
|
|
196
201
|
# bun (recommended)
|
|
197
|
-
bun add microui
|
|
202
|
+
bun add microui-wc
|
|
198
203
|
|
|
199
204
|
# CDN (no install)
|
|
200
205
|
<script type="module" src="https://unpkg.com/microui-wc/dist/microui.esm.js"></script>
|