@adia-ai/web-modules 0.3.4 → 0.3.6

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/chat/chat-composer/chat-composer.a2ui.json +94 -0
  3. package/chat/chat-composer/chat-composer.examples.html +28 -0
  4. package/chat/chat-composer/chat-composer.html +43 -0
  5. package/chat/chat-composer/chat-composer.js +107 -0
  6. package/chat/chat-composer/chat-composer.test.js +112 -0
  7. package/chat/chat-composer/chat-composer.yaml +91 -0
  8. package/chat/chat-empty/chat-empty.a2ui.json +68 -0
  9. package/chat/chat-empty/chat-empty.examples.html +34 -0
  10. package/chat/chat-empty/chat-empty.html +42 -0
  11. package/chat/chat-empty/chat-empty.yaml +58 -0
  12. package/chat/chat-header/chat-header.a2ui.json +77 -0
  13. package/chat/chat-header/chat-header.examples.html +30 -0
  14. package/chat/chat-header/chat-header.html +42 -0
  15. package/chat/chat-header/chat-header.yaml +68 -0
  16. package/chat/chat-shell/chat-shell.css +1 -0
  17. package/chat/chat-shell/chat-shell.examples.html +43 -2
  18. package/chat/chat-shell/chat-shell.js +35 -7
  19. package/chat/chat-shell/css/chat-shell.bespoke.css +196 -0
  20. package/chat/chat-sidebar/chat-sidebar.a2ui.json +136 -0
  21. package/chat/chat-sidebar/chat-sidebar.examples.html +36 -0
  22. package/chat/chat-sidebar/chat-sidebar.html +43 -0
  23. package/chat/chat-sidebar/chat-sidebar.js +227 -0
  24. package/chat/chat-sidebar/chat-sidebar.test.js +110 -0
  25. package/chat/chat-sidebar/chat-sidebar.yaml +140 -0
  26. package/chat/chat-status/chat-status.a2ui.json +63 -0
  27. package/chat/chat-status/chat-status.examples.html +29 -0
  28. package/chat/chat-status/chat-status.html +42 -0
  29. package/chat/chat-status/chat-status.yaml +52 -0
  30. package/chat/chat-thread/chat-thread.a2ui.json +91 -0
  31. package/chat/chat-thread/chat-thread.examples.html +36 -0
  32. package/chat/chat-thread/chat-thread.html +43 -0
  33. package/chat/chat-thread/chat-thread.js +106 -0
  34. package/chat/chat-thread/chat-thread.test.js +82 -0
  35. package/chat/chat-thread/chat-thread.yaml +89 -0
  36. package/chat/index.js +3 -0
  37. package/editor/editor-canvas/editor-canvas.a2ui.json +87 -0
  38. package/editor/editor-canvas/editor-canvas.js +103 -0
  39. package/editor/editor-canvas/editor-canvas.test.js +100 -0
  40. package/editor/editor-canvas/editor-canvas.yaml +88 -0
  41. package/editor/editor-canvas-empty/editor-canvas-empty.a2ui.json +69 -0
  42. package/editor/editor-canvas-empty/editor-canvas-empty.yaml +56 -0
  43. package/editor/editor-shell/css/editor-shell.bespoke.css +172 -0
  44. package/editor/editor-shell/editor-shell.css +1 -0
  45. package/editor/editor-shell/editor-shell.js +85 -30
  46. package/editor/editor-sidebar/editor-sidebar.a2ui.json +88 -0
  47. package/editor/editor-sidebar/editor-sidebar.js +173 -0
  48. package/editor/editor-sidebar/editor-sidebar.test.js +126 -0
  49. package/editor/editor-sidebar/editor-sidebar.yaml +83 -0
  50. package/editor/editor-statusbar/editor-statusbar.a2ui.json +76 -0
  51. package/editor/editor-statusbar/editor-statusbar.yaml +57 -0
  52. package/editor/editor-toolbar/editor-toolbar.a2ui.json +96 -0
  53. package/editor/editor-toolbar/editor-toolbar.js +58 -0
  54. package/editor/editor-toolbar/editor-toolbar.test.js +99 -0
  55. package/editor/editor-toolbar/editor-toolbar.yaml +81 -0
  56. package/editor/index.js +3 -0
  57. package/package.json +1 -1
@@ -0,0 +1,57 @@
1
+ # Edit this file; run `npm run build:components` to regenerate a2ui.json.
2
+ $schema: ../../../../scripts/schemas/component.yaml.schema.json
3
+ name: EditorStatusbar
4
+ tag: editor-statusbar
5
+ component: EditorStatusbar
6
+ category: layout
7
+ version: 1
8
+ description: |
9
+ Module-tier editor statusbar — bottom chrome bar inside
10
+ <editor-shell>. CSS-only, no behavior, no JS. Holds save/sync
11
+ state, zoom indicator, cursor position, and tertiary actions
12
+ via slot vocabulary.
13
+
14
+ Replaces the legacy <footer> with positional content per ADR-0023.
15
+
16
+ props: {}
17
+
18
+ events: {}
19
+
20
+ slots:
21
+ default:
22
+ description: Default — ad-hoc inline content (legacy positional layout).
23
+ status:
24
+ description: Save/sync state indicator.
25
+ cursor:
26
+ description: Cursor position / selection indicator.
27
+ zoom:
28
+ description: Zoom level indicator.
29
+ action:
30
+ description: Trailing action cluster (e.g., toggle full-screen).
31
+
32
+ states:
33
+ - name: idle
34
+ description: Default, the only state.
35
+
36
+ traits: []
37
+
38
+ a2ui:
39
+ rules:
40
+ - >-
41
+ editor-statusbar replaces legacy <footer> chrome bar inside
42
+ <editor-shell>. Use named slots for canonical clusters; ad-hoc
43
+ content goes in the default slot.
44
+
45
+ keywords:
46
+ - editor-statusbar
47
+ - statusbar
48
+ - bottom-bar
49
+ - editor-footer
50
+
51
+ synonyms:
52
+ editor-statusbar: [statusbar, footer-bar, bottom-bar]
53
+
54
+ related:
55
+ - EditorShell
56
+ - EditorToolbar
57
+ - EditorCanvas
@@ -0,0 +1,96 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://adiaui.dev/a2ui/v0_9/components/EditorToolbar.json",
4
+ "title": "EditorToolbar",
5
+ "description": "Module-tier editor toolbar — replaces legacy <header> chrome bar\ninside <editor-shell> per ADR-0023. Owns the [full-screen] reflected\nattribute (set when host enters focus mode), click-bubble for\n[data-toolbar-action] buttons, and slot vocabulary routing.\n\nSits at the top of <editor-shell>. Authors compose actions + status\nvia slot vocabulary. The host (<editor-shell>) reads either\n<editor-toolbar> or <header> via :is() selector for backwards compat.\n",
6
+ "type": "object",
7
+ "allOf": [
8
+ {
9
+ "$ref": "common_types.json#/$defs/ComponentCommon"
10
+ },
11
+ {
12
+ "$ref": "common_types.json#/$defs/CatalogComponentCommon"
13
+ }
14
+ ],
15
+ "properties": {
16
+ "component": {
17
+ "const": "EditorToolbar"
18
+ },
19
+ "fullScreen": {
20
+ "description": "Reflected — set when editor is in distraction-free / focus mode.",
21
+ "type": "boolean",
22
+ "default": false
23
+ }
24
+ },
25
+ "required": [
26
+ "component"
27
+ ],
28
+ "unevaluatedProperties": false,
29
+ "x-adiaui": {
30
+ "anti_patterns": [],
31
+ "category": "layout",
32
+ "events": {
33
+ "toolbar-action": {
34
+ "description": "Bubbles when a child element with [data-toolbar-action] is clicked. Detail carries the action name from the clicked element's attribute.",
35
+ "detail": {
36
+ "name": "string"
37
+ }
38
+ }
39
+ },
40
+ "examples": [],
41
+ "keywords": [
42
+ "editor-toolbar",
43
+ "editor-titlebar",
44
+ "editor-chrome",
45
+ "app-header",
46
+ "editor-actions"
47
+ ],
48
+ "name": "EditorToolbar",
49
+ "related": [
50
+ "EditorShell",
51
+ "EditorCanvas",
52
+ "EditorSidebar",
53
+ "EditorStatusbar"
54
+ ],
55
+ "slots": {
56
+ "title": {
57
+ "description": "Editor / document title cluster."
58
+ },
59
+ "default": {
60
+ "description": "Default — ad-hoc inline content (legacy positional layout)."
61
+ },
62
+ "action": {
63
+ "description": "Trailing action cluster (settings, share, more)."
64
+ },
65
+ "action-leading": {
66
+ "description": "Leading action cluster (back, switcher, undo/redo)."
67
+ },
68
+ "status": {
69
+ "description": "Status indicator (saving, dirty, synced, etc.)."
70
+ }
71
+ },
72
+ "states": [
73
+ {
74
+ "description": "Default editor mode.",
75
+ "name": "idle"
76
+ },
77
+ {
78
+ "description": "Distraction-free / focus mode active.",
79
+ "attribute": "full-screen",
80
+ "name": "full-screen"
81
+ }
82
+ ],
83
+ "synonyms": {
84
+ "editor-toolbar": [
85
+ "editor-header",
86
+ "app-header",
87
+ "navbar",
88
+ "titlebar"
89
+ ]
90
+ },
91
+ "tag": "editor-toolbar",
92
+ "tokens": {},
93
+ "traits": [],
94
+ "version": 1
95
+ }
96
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * <editor-toolbar full-screen?>
3
+ * <span slot="title">Editor</span>
4
+ * <button-ui slot="action" icon="gear"></button-ui>
5
+ * </editor-toolbar>
6
+ *
7
+ * Module-tier editor toolbar — replaces legacy <header> with [data-title]
8
+ * + [data-spacer] + ad-hoc action children inside <editor-shell>. Owns:
9
+ *
10
+ * - [full-screen] reflected attribute (set when host enters focus mode)
11
+ * - Slot vocabulary routing (title / status / action / action-leading)
12
+ * - Click-bubble for [data-toolbar-action="<name>"] buttons → fires
13
+ * 'toolbar-action' event with the action name
14
+ *
15
+ * Reflected attributes:
16
+ * [full-screen] — true when editor is in distraction-free / focus mode
17
+ *
18
+ * Events:
19
+ * toolbar-action — bubbles. detail: { name } from clicked button's
20
+ * [data-toolbar-action] attribute
21
+ *
22
+ * The host (<editor-shell>) reads either <editor-toolbar> or <header>
23
+ * via :is() selector for backwards compat. Default-slot children fall
24
+ * back to legacy positional layout if no named slots are used.
25
+ */
26
+
27
+ import { UIElement } from '../../../web-components/core/element.js';
28
+
29
+ class EditorToolbar extends UIElement {
30
+ static properties = {
31
+ fullScreen: { type: Boolean, default: false, reflect: true, attribute: 'full-screen' },
32
+ };
33
+
34
+ static template = () => null;
35
+
36
+ #onClick = null;
37
+
38
+ connected() {
39
+ this.#onClick = (e) => {
40
+ const btn = e.target.closest('[data-toolbar-action]');
41
+ if (!btn || !this.contains(btn)) return;
42
+ const name = btn.getAttribute('data-toolbar-action');
43
+ this.dispatchEvent(new CustomEvent('toolbar-action', {
44
+ bubbles: true,
45
+ detail: { name },
46
+ }));
47
+ };
48
+ this.addEventListener('click', this.#onClick);
49
+ }
50
+
51
+ disconnected() {
52
+ if (this.#onClick) this.removeEventListener('click', this.#onClick);
53
+ this.#onClick = null;
54
+ }
55
+ }
56
+
57
+ customElements.define('editor-toolbar', EditorToolbar);
58
+ export { EditorToolbar };
@@ -0,0 +1,99 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ import '../../../web-components/core/element.js';
3
+ import './editor-toolbar.js';
4
+
5
+ const tick = () => new Promise((r) => queueMicrotask(r));
6
+
7
+ function mount(html) {
8
+ const wrap = document.createElement('div');
9
+ wrap.innerHTML = html;
10
+ document.body.appendChild(wrap);
11
+ return wrap.firstElementChild;
12
+ }
13
+
14
+ beforeEach(() => {
15
+ document.body.innerHTML = '';
16
+ });
17
+
18
+ describe('editor-toolbar', () => {
19
+ it('registers editor-toolbar as a custom element', () => {
20
+ expect(customElements.get('editor-toolbar')).toBeDefined();
21
+ });
22
+
23
+ it('defaults to fullScreen=false', () => {
24
+ const t = mount('<editor-toolbar></editor-toolbar>');
25
+ expect(t.fullScreen).toBe(false);
26
+ });
27
+
28
+ it('reflects [full-screen] via property assignment', async () => {
29
+ const t = mount('<editor-toolbar></editor-toolbar>');
30
+ t.fullScreen = true;
31
+ await tick();
32
+ expect(t.hasAttribute('full-screen')).toBe(true);
33
+ });
34
+
35
+ it('honors initial [full-screen] attribute on connect', () => {
36
+ const t = mount('<editor-toolbar full-screen></editor-toolbar>');
37
+ expect(t.fullScreen).toBe(true);
38
+ });
39
+
40
+ it('bubbles toolbar-action event from [data-toolbar-action] children', async () => {
41
+ const wrap = document.createElement('div');
42
+ wrap.innerHTML = `<editor-toolbar>
43
+ <button data-toolbar-action="save">Save</button>
44
+ <button data-toolbar-action="undo">Undo</button>
45
+ </editor-toolbar>`;
46
+ document.body.appendChild(wrap);
47
+ const toolbar = wrap.firstElementChild;
48
+ const saveBtn = toolbar.querySelector('[data-toolbar-action="save"]');
49
+
50
+ const onAction = vi.fn();
51
+ toolbar.addEventListener('toolbar-action', onAction);
52
+
53
+ saveBtn.click();
54
+ await tick();
55
+
56
+ expect(onAction).toHaveBeenCalledTimes(1);
57
+ expect(onAction.mock.calls[0][0].detail).toEqual({ name: 'save' });
58
+ });
59
+
60
+ it('does not fire toolbar-action for clicks outside [data-toolbar-action]', async () => {
61
+ const wrap = document.createElement('div');
62
+ wrap.innerHTML = `<editor-toolbar>
63
+ <span>Title</span>
64
+ <button>Plain button</button>
65
+ </editor-toolbar>`;
66
+ document.body.appendChild(wrap);
67
+ const toolbar = wrap.firstElementChild;
68
+ const plainBtn = toolbar.querySelector('button');
69
+
70
+ const onAction = vi.fn();
71
+ toolbar.addEventListener('toolbar-action', onAction);
72
+
73
+ plainBtn.click();
74
+ await tick();
75
+
76
+ expect(onAction).not.toHaveBeenCalled();
77
+ });
78
+
79
+ it('cleanup on disconnect — removes click listener', () => {
80
+ const t = mount('<editor-toolbar></editor-toolbar>');
81
+ const removeSpy = vi.spyOn(t, 'removeEventListener');
82
+ t.remove();
83
+ const removedTypes = removeSpy.mock.calls.map((args) => args[0]);
84
+ expect(removedTypes).toContain('click');
85
+ });
86
+
87
+ it('event bubbles up beyond the toolbar', async () => {
88
+ const outer = document.createElement('div');
89
+ document.body.appendChild(outer);
90
+ outer.innerHTML = `<editor-toolbar>
91
+ <button data-toolbar-action="settings"></button>
92
+ </editor-toolbar>`;
93
+ const onOuterAction = vi.fn();
94
+ outer.addEventListener('toolbar-action', onOuterAction);
95
+ outer.querySelector('button').click();
96
+ await tick();
97
+ expect(onOuterAction).toHaveBeenCalled();
98
+ });
99
+ });
@@ -0,0 +1,81 @@
1
+ # Edit this file; run `npm run build:components` to regenerate a2ui.json.
2
+ $schema: ../../../../scripts/schemas/component.yaml.schema.json
3
+ name: EditorToolbar
4
+ tag: editor-toolbar
5
+ component: EditorToolbar
6
+ category: layout
7
+ version: 1
8
+ description: |
9
+ Module-tier editor toolbar — replaces legacy <header> chrome bar
10
+ inside <editor-shell> per ADR-0023. Owns the [full-screen] reflected
11
+ attribute (set when host enters focus mode), click-bubble for
12
+ [data-toolbar-action] buttons, and slot vocabulary routing.
13
+
14
+ Sits at the top of <editor-shell>. Authors compose actions + status
15
+ via slot vocabulary. The host (<editor-shell>) reads either
16
+ <editor-toolbar> or <header> via :is() selector for backwards compat.
17
+
18
+ props:
19
+ fullScreen:
20
+ description: Reflected — set when editor is in distraction-free / focus mode.
21
+ type: boolean
22
+ default: false
23
+ reflect: true
24
+ attribute: full-screen
25
+
26
+ events:
27
+ toolbar-action:
28
+ description: >-
29
+ Bubbles when a child element with [data-toolbar-action] is clicked.
30
+ Detail carries the action name from the clicked element's attribute.
31
+ detail:
32
+ name: string
33
+
34
+ slots:
35
+ default:
36
+ description: Default — ad-hoc inline content (legacy positional layout).
37
+ title:
38
+ description: Editor / document title cluster.
39
+ status:
40
+ description: Status indicator (saving, dirty, synced, etc.).
41
+ action:
42
+ description: Trailing action cluster (settings, share, more).
43
+ action-leading:
44
+ description: Leading action cluster (back, switcher, undo/redo).
45
+
46
+ states:
47
+ - name: idle
48
+ description: Default editor mode.
49
+ - name: full-screen
50
+ attribute: full-screen
51
+ description: Distraction-free / focus mode active.
52
+
53
+ traits: []
54
+
55
+ a2ui:
56
+ rules:
57
+ - >-
58
+ editor-toolbar replaces legacy <header> chrome bar inside
59
+ <editor-shell>. Use named slots (title / status / action /
60
+ action-leading) for canonical clusters; ad-hoc inline content
61
+ goes in the default slot.
62
+ - >-
63
+ Buttons that should trigger named actions get
64
+ [data-toolbar-action="<name>"]. The toolbar bubbles a single
65
+ 'toolbar-action' event up to the host with the name in detail.
66
+
67
+ keywords:
68
+ - editor-toolbar
69
+ - editor-titlebar
70
+ - editor-chrome
71
+ - app-header
72
+ - editor-actions
73
+
74
+ synonyms:
75
+ editor-toolbar: [editor-header, app-header, navbar, titlebar]
76
+
77
+ related:
78
+ - EditorShell
79
+ - EditorCanvas
80
+ - EditorSidebar
81
+ - EditorStatusbar
package/editor/index.js CHANGED
@@ -1 +1,4 @@
1
1
  export { EditorShell } from './editor-shell/editor-shell.js';
2
+ export { EditorToolbar } from './editor-toolbar/editor-toolbar.js';
3
+ export { EditorCanvas } from './editor-canvas/editor-canvas.js';
4
+ export { EditorSidebar } from './editor-sidebar/editor-sidebar.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-modules",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "AdiaUI composite custom elements \u2014 shell, chat, editor, runtime clusters built from @adia-ai/web-components primitives. Subpath exports per cluster.",
5
5
  "type": "module",
6
6
  "exports": {