@adia-ai/web-components 0.0.6 → 0.0.7

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.
@@ -29,7 +29,7 @@
29
29
  * close — fired after the modal finishes closing
30
30
  */
31
31
 
32
- import { AdiaElement, html } from '../../core/element.js';
32
+ import { AdiaElement } from '../../core/element.js';
33
33
 
34
34
  class AdiaModal extends AdiaElement {
35
35
  #bound = false;
@@ -55,7 +55,10 @@ class AdiaModal extends AdiaElement {
55
55
  footer: '<footer slot="footer"></footer>',
56
56
  };
57
57
 
58
- static template = () => html``;
58
+ // No template modal composes from authored light-DOM children. An empty
59
+ // html`` result would trigger stamp() → replaceChildren(), wiping authored
60
+ // [slot=body|footer] before render() can migrate them into the panel.
61
+ // (Same rationale as drawer.js — parallel pattern.)
59
62
 
60
63
  #onPress = (e) => {
61
64
  if (e.target.closest('[slot="close"]')) this.open = false;
package/core/icons.js CHANGED
@@ -53,14 +53,17 @@ export function listIcons() {
53
53
 
54
54
  // Vite resolves each glob at build time into a map of path → module.
55
55
  // One glob per weight so the bundler can tree-shake what isn't referenced.
56
- const weightModules = {
56
+ // In non-Vite environments (e.g. plain static serving) `import.meta.glob`
57
+ // is undefined — fall back to empty maps so consumers using registerIcon()
58
+ // still work.
59
+ const weightModules = typeof import.meta.glob === 'function' ? {
57
60
  regular: import.meta.glob('/node_modules/@phosphor-icons/core/assets/regular/*.svg', { query: '?raw', import: 'default' }),
58
61
  thin: import.meta.glob('/node_modules/@phosphor-icons/core/assets/thin/*.svg', { query: '?raw', import: 'default' }),
59
62
  light: import.meta.glob('/node_modules/@phosphor-icons/core/assets/light/*.svg', { query: '?raw', import: 'default' }),
60
63
  bold: import.meta.glob('/node_modules/@phosphor-icons/core/assets/bold/*.svg', { query: '?raw', import: 'default' }),
61
64
  fill: import.meta.glob('/node_modules/@phosphor-icons/core/assets/fill/*.svg', { query: '?raw', import: 'default' }),
62
65
  duotone: import.meta.glob('/node_modules/@phosphor-icons/core/assets/duotone/*.svg', { query: '?raw', import: 'default' }),
63
- };
66
+ } : { regular: {}, thin: {}, light: {}, bold: {}, fill: {}, duotone: {} };
64
67
 
65
68
  /**
66
69
  * Phosphor filename convention: `star.svg` for regular, `star-fill.svg` for
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-components",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "AdiaUI web components — vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-utils.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -26,6 +26,10 @@
26
26
  "component": {
27
27
  "const": "A2UIRoot"
28
28
  },
29
+ "doc": {
30
+ "description": "Author-driven mode — set to an array of A2UI messages and the renderer resets + replays them. No network/transport involvement. Setting to a new array triggers a full re-render. Use this for editors, previews, tests, and any static-doc authoring loop. When both `src` and `doc` are set, `doc` wins (the stream is not opened). Pass as a JS property; not reflected to an attribute.",
31
+ "type": "array"
32
+ },
29
33
  "loading": {
30
34
  "description": "True while the stream is connecting.",
31
35
  "type": "boolean",
@@ -71,6 +75,9 @@
71
75
  },
72
76
  "a2ui-message": {
73
77
  "description": "Fired for each A2UI message received. detail: { message }"
78
+ },
79
+ "doc-replaced": {
80
+ "description": "Fired after a full doc reset + replay in author-driven mode. detail: { count }"
74
81
  }
75
82
  },
76
83
  "examples": [],
@@ -5,12 +5,24 @@
5
5
  * <a2ui-root src="/api/agent" transport="sse"></a2ui-root>
6
6
  * <a2ui-root src="ws://localhost:8080" transport="ws"></a2ui-root>
7
7
  *
8
+ * Static / author-driven mode — set the `doc` property (array of A2UI messages)
9
+ * and the renderer resets + replays them. Editors and previews can drive the
10
+ * surface without opening a transport. Setting `doc` to a new array re-renders
11
+ * from scratch (reset() + processAll()).
12
+ *
13
+ * const root = document.querySelector('a2ui-root');
14
+ * root.doc = [
15
+ * { type: 'createSurface', surfaceId: 'root', root: 'c-1' },
16
+ * { type: 'updateComponents', components: [{ id: 'c-1', component: 'Heading', text: 'Hi' }] },
17
+ * ];
18
+ *
8
19
  * Events:
9
20
  * a2ui-connected — stream connected
10
21
  * a2ui-message — each message received (detail: { message })
11
22
  * a2ui-error — stream error (detail: { error })
12
23
  * a2ui-closed — stream ended
13
24
  * a2ui-action — user interaction (detail: { name, sourceComponentId, context })
25
+ * doc-replaced — fired after a full doc reset + replay (author-driven mode)
14
26
  */
15
27
 
16
28
  import { AdiaElement } from '../../core/element.js';
@@ -36,6 +48,7 @@ class AdiaA2UIRoot extends AdiaElement {
36
48
 
37
49
  #renderer = null;
38
50
  #abortCtrl = null;
51
+ #doc = null;
39
52
 
40
53
  connected() {
41
54
  this.#renderer = new A2UIRenderer(this, registry, { batch: this.batch });
@@ -136,6 +149,20 @@ class AdiaA2UIRoot extends AdiaElement {
136
149
  for (const msg of messages) this.process(msg);
137
150
  }
138
151
 
152
+ get doc() { return this.#doc; }
153
+ set doc(messages) {
154
+ this.#doc = Array.isArray(messages) ? messages : [];
155
+ if (!this.#renderer) {
156
+ this.#renderer = new A2UIRenderer(this, registry);
157
+ }
158
+ this.#renderer.reset();
159
+ for (const msg of this.#doc) this.#renderer.process(msg);
160
+ this.dispatchEvent(new CustomEvent('doc-replaced', {
161
+ bubbles: true,
162
+ detail: { count: this.#doc.length },
163
+ }));
164
+ }
165
+
139
166
  reset() {
140
167
  this.#renderer?.reset();
141
168
  }
@@ -35,6 +35,15 @@ props:
35
35
  description: Batch renderer updates via requestAnimationFrame for large fan-in.
36
36
  type: boolean
37
37
  default: false
38
+ doc:
39
+ description: >-
40
+ Author-driven mode — set to an array of A2UI messages and the renderer
41
+ resets + replays them. No network/transport involvement. Setting to a
42
+ new array triggers a full re-render. Use this for editors, previews,
43
+ tests, and any static-doc authoring loop. When both `src` and `doc` are
44
+ set, `doc` wins (the stream is not opened). Pass as a JS property; not
45
+ reflected to an attribute.
46
+ type: array
38
47
  events:
39
48
  a2ui-connected:
40
49
  description: Fired when the stream is established.
@@ -46,6 +55,8 @@ events:
46
55
  description: "Fired when the stream errors. detail: { error }"
47
56
  a2ui-closed:
48
57
  description: Fired when the stream ends.
58
+ doc-replaced:
59
+ description: "Fired after a full doc reset + replay in author-driven mode. detail: { count }"
49
60
  slots:
50
61
  default:
51
62
  description: The rendered surface. Children are stamped by the A2UI renderer.