@adia-ai/web-components 0.5.10 → 0.5.12
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/CHANGELOG.md +2207 -0
- package/USAGE.md +29 -0
- package/color/index.d.ts +121 -0
- package/color/index.js +252 -0
- package/components/color-input/class.js +186 -0
- package/components/color-input/color-input.a2ui.json +172 -0
- package/components/color-input/color-input.css +47 -0
- package/components/color-input/color-input.d.ts +71 -0
- package/components/color-input/color-input.js +26 -0
- package/components/color-input/color-input.yaml +145 -0
- package/components/index.js +1 -0
- package/components/stat/stat-ui.d.ts +38 -0
- package/components/swatch/class.js +8 -0
- package/components/swatch/swatch.a2ui.json +10 -1
- package/components/swatch/swatch.css +32 -0
- package/components/swatch/swatch.d.ts +13 -3
- package/components/swatch/swatch.yaml +21 -3
- package/core/template.js +19 -0
- package/core/template.test.js +97 -0
- package/package.json +9 -2
- package/styles/components.css +1 -0
package/core/template.js
CHANGED
|
@@ -175,6 +175,25 @@ function scan(fragment, count) {
|
|
|
175
175
|
} else if (name[0] === '.') {
|
|
176
176
|
n.removeAttribute(name);
|
|
177
177
|
parts[i] = { t: 'p', n, name: name.slice(1), c: undefined, _fx: null };
|
|
178
|
+
} else if (name[0] === '?') {
|
|
179
|
+
// §250 (v0.5.11, FEEDBACK-27): Lit-style boolean attribute syntax
|
|
180
|
+
// (`?attr=${bool}`) is NOT supported. Without this branch, the
|
|
181
|
+
// attribute name registers verbatim including the `?` — silent
|
|
182
|
+
// inert binding. Strip the bogus attribute, warn loudly + degrade
|
|
183
|
+
// to a no-op text-node part so nothing reaches the DOM.
|
|
184
|
+
// Consumers should use `.attr=${bool}` (property binding); AdiaUI
|
|
185
|
+
// primitives reflect properties to DOM attributes automatically.
|
|
186
|
+
// Parallel structural fix to v0.5.3 §152 partial-interpolation warn.
|
|
187
|
+
n.removeAttribute(name);
|
|
188
|
+
// eslint-disable-next-line no-console
|
|
189
|
+
console.warn(
|
|
190
|
+
`[template] Lit-style boolean attribute "${name}=" is not supported.\n` +
|
|
191
|
+
` Element: <${n.tagName.toLowerCase()}>\n` +
|
|
192
|
+
` Use .${name.slice(1)}=\${value} (property binding) instead — ` +
|
|
193
|
+
`the primitive reflects the property to the DOM attribute for you.\n` +
|
|
194
|
+
` See USAGE.md § Template parser — invariants + unsupported syntaxes.`
|
|
195
|
+
);
|
|
196
|
+
parts[i] = { t: 'n', n: document.createTextNode(''), c: undefined, _fx: null };
|
|
178
197
|
} else {
|
|
179
198
|
parts[i] = { t: 'a', n, name, c: undefined, _fx: null };
|
|
180
199
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/template.js — focused tests for the §250 (v0.5.11) `?attr=${bool}`
|
|
3
|
+
* silent-failure-trap close. Surfaced by FEEDBACK-27 against v0.5.10 source.
|
|
4
|
+
*
|
|
5
|
+
* Pre-§250: `?disabled=${true}` registered a literal `?disabled` DOM
|
|
6
|
+
* attribute with no console warning. Consumer ergonomics gap — Lit-familiar
|
|
7
|
+
* developers reach for the most ergonomic syntax + ship inert bindings.
|
|
8
|
+
*
|
|
9
|
+
* Post-§250: scan-time `console.warn` fires + the bogus part is degraded to
|
|
10
|
+
* a no-op text-node, so nothing reaches the DOM. Migration path is
|
|
11
|
+
* `.attr=${bool}` (property binding) — primitives reflect properties to DOM
|
|
12
|
+
* attributes automatically.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
16
|
+
import { html, stamp } from './template.js';
|
|
17
|
+
|
|
18
|
+
describe('html template — §250 (v0.5.11) ?attr=${bool} silent-failure trap', () => {
|
|
19
|
+
let container;
|
|
20
|
+
let warnSpy;
|
|
21
|
+
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
container = document.createElement('div');
|
|
24
|
+
document.body.appendChild(container);
|
|
25
|
+
warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
container.remove();
|
|
30
|
+
warnSpy.mockRestore();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('fires console.warn at scan time when ?attr=${bool} is encountered', () => {
|
|
34
|
+
const tpl = html`<div ?disabled=${true}></div>`;
|
|
35
|
+
stamp(tpl, container);
|
|
36
|
+
|
|
37
|
+
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
38
|
+
const msg = warnSpy.mock.calls[0][0];
|
|
39
|
+
expect(msg).toMatch(/Lit-style boolean attribute/);
|
|
40
|
+
expect(msg).toMatch(/\?disabled=/);
|
|
41
|
+
expect(msg).toMatch(/\.disabled=/); // migration path mentioned
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('does NOT register a literal "?attr" attribute on the DOM node', () => {
|
|
45
|
+
const tpl = html`<div ?disabled=${true} data-test="probe"></div>`;
|
|
46
|
+
stamp(tpl, container);
|
|
47
|
+
|
|
48
|
+
const node = container.querySelector('[data-test="probe"]');
|
|
49
|
+
expect(node).not.toBeNull();
|
|
50
|
+
expect(node.getAttribute('?disabled')).toBeNull();
|
|
51
|
+
expect(node.hasAttribute('?disabled')).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('does NOT set the matching DOM attribute either (no Lit-attr semantics)', () => {
|
|
55
|
+
// AdiaUI intentionally does not implement `?attr=${bool}` semantics.
|
|
56
|
+
// The warn + degrade-to-no-op path means truthy `?disabled` does NOT
|
|
57
|
+
// add `[disabled]` to the DOM. Consumer must use `.disabled=` for that.
|
|
58
|
+
const tpl = html`<div ?disabled=${true} data-test="probe"></div>`;
|
|
59
|
+
stamp(tpl, container);
|
|
60
|
+
|
|
61
|
+
const node = container.querySelector('[data-test="probe"]');
|
|
62
|
+
expect(node.hasAttribute('disabled')).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('fires the warn even when the bound value is falsy', () => {
|
|
66
|
+
// Lit's `?attr=${false}` removes the attribute. AdiaUI's contract is
|
|
67
|
+
// "this syntax is not supported, period" — warn fires regardless of
|
|
68
|
+
// truthiness to maximize visibility of the authoring error.
|
|
69
|
+
const tpl = html`<div ?disabled=${false}></div>`;
|
|
70
|
+
stamp(tpl, container);
|
|
71
|
+
|
|
72
|
+
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('does not warn on canonical .prop=${val} (no false positive)', () => {
|
|
76
|
+
// Make sure the new `?`-prefix branch doesn't accidentally fire on
|
|
77
|
+
// adjacent canonical syntaxes.
|
|
78
|
+
const tpl = html`<div .className=${'x'}></div>`;
|
|
79
|
+
stamp(tpl, container);
|
|
80
|
+
|
|
81
|
+
expect(warnSpy).not.toHaveBeenCalled();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('does not warn on canonical @event=${handler} (no false positive)', () => {
|
|
85
|
+
const tpl = html`<div @click=${() => {}}></div>`;
|
|
86
|
+
stamp(tpl, container);
|
|
87
|
+
|
|
88
|
+
expect(warnSpy).not.toHaveBeenCalled();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('does not warn on canonical attr=${value} (no false positive)', () => {
|
|
92
|
+
const tpl = html`<div data-id=${'42'}></div>`;
|
|
93
|
+
stamp(tpl, container);
|
|
94
|
+
|
|
95
|
+
expect(warnSpy).not.toHaveBeenCalled();
|
|
96
|
+
});
|
|
97
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adia-ai/web-components",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.12",
|
|
4
4
|
"description": "AdiaUI web components — vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -33,10 +33,15 @@
|
|
|
33
33
|
"./styles/*": "./styles/*",
|
|
34
34
|
"./traits": "./traits/index.js",
|
|
35
35
|
"./traits/*": "./traits/*.js",
|
|
36
|
+
"./color": {
|
|
37
|
+
"types": "./color/index.d.ts",
|
|
38
|
+
"default": "./color/index.js"
|
|
39
|
+
},
|
|
36
40
|
"./package.json": "./package.json"
|
|
37
41
|
},
|
|
38
42
|
"files": [
|
|
39
43
|
"core/",
|
|
44
|
+
"color/",
|
|
40
45
|
"components/",
|
|
41
46
|
"!components/**/*.html",
|
|
42
47
|
"!components/**/*.examples.js",
|
|
@@ -50,7 +55,9 @@
|
|
|
50
55
|
"index.js",
|
|
51
56
|
"index.css",
|
|
52
57
|
"index.d.ts",
|
|
53
|
-
"USAGE.md"
|
|
58
|
+
"USAGE.md",
|
|
59
|
+
"README.md",
|
|
60
|
+
"CHANGELOG.md"
|
|
54
61
|
],
|
|
55
62
|
"sideEffects": [
|
|
56
63
|
"*.css",
|
package/styles/components.css
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
@import "../components/breadcrumb/breadcrumb.css";
|
|
41
41
|
@import "../components/command/command.css";
|
|
42
42
|
@import "../components/color-picker/color-picker.css";
|
|
43
|
+
@import "../components/color-input/color-input.css";
|
|
43
44
|
@import "../components/noodles/noodles.css";
|
|
44
45
|
@import "../components/table/table.css";
|
|
45
46
|
@import "../components/table-toolbar/table-toolbar.css";
|