@adia-ai/web-modules 0.3.6 → 0.4.1
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 +44 -0
- package/README.md +29 -15
- package/chat/chat-shell/chat-shell.js +28 -40
- package/chat/chat-shell/css/chat-shell.empty.css +3 -3
- package/chat/chat-shell/css/chat-shell.layout.css +2 -2
- package/editor/editor-canvas/editor-canvas.examples.html +65 -0
- package/editor/editor-canvas/editor-canvas.html +43 -0
- package/editor/editor-canvas-empty/editor-canvas-empty.examples.html +65 -0
- package/editor/editor-canvas-empty/editor-canvas-empty.html +42 -0
- package/editor/editor-shell/css/editor-shell.bespoke.css +67 -2
- package/editor/editor-shell/css/editor-shell.layout.css +6 -6
- package/editor/editor-shell/editor-shell.js +19 -17
- package/editor/editor-sidebar/editor-sidebar.a2ui.json +5 -0
- package/editor/editor-sidebar/editor-sidebar.examples.html +65 -0
- package/editor/editor-sidebar/editor-sidebar.html +43 -0
- package/editor/editor-sidebar/editor-sidebar.js +30 -6
- package/editor/editor-sidebar/editor-sidebar.test.js +19 -0
- package/editor/editor-sidebar/editor-sidebar.yaml +8 -0
- package/editor/editor-statusbar/editor-statusbar.examples.html +65 -0
- package/editor/editor-statusbar/editor-statusbar.html +42 -0
- package/editor/editor-toolbar/editor-toolbar.examples.html +65 -0
- package/editor/editor-toolbar/editor-toolbar.html +43 -0
- package/index.js +1 -0
- package/package.json +8 -5
- package/shell/admin-shell/admin-shell.js +27 -243
- package/shell/admin-shell/css/admin-shell.bespoke.css +22 -26
- package/shell/admin-shell/css/admin-shell.main.css +2 -2
- package/shell/admin-shell/css/admin-shell.shell.css +2 -2
- package/shell/admin-shell/css/admin-shell.sidebar.css +35 -33
- package/simple/index.js +2 -0
- package/simple/simple-content/simple-content.a2ui.json +67 -0
- package/simple/simple-content/simple-content.css +29 -0
- package/simple/simple-content/simple-content.examples.html +13 -0
- package/simple/simple-content/simple-content.html +42 -0
- package/simple/simple-content/simple-content.yaml +54 -0
- package/simple/simple-hero/simple-hero.a2ui.json +76 -0
- package/simple/simple-hero/simple-hero.css +45 -0
- package/simple/simple-hero/simple-hero.examples.html +33 -0
- package/simple/simple-hero/simple-hero.html +42 -0
- package/simple/simple-hero/simple-hero.yaml +57 -0
- package/simple/simple-shell/simple-shell.a2ui.json +87 -0
- package/simple/simple-shell/simple-shell.css +40 -0
- package/simple/simple-shell/simple-shell.examples.html +42 -0
- package/simple/simple-shell/simple-shell.html +42 -0
- package/simple/simple-shell/simple-shell.js +47 -0
- package/simple/simple-shell/simple-shell.test.js +83 -0
- package/simple/simple-shell/simple-shell.yaml +78 -0
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,50 @@ Built from `@adia-ai/web-components` primitives.
|
|
|
11
11
|
|
|
12
12
|
_No pending changes._
|
|
13
13
|
|
|
14
|
+
## [0.4.1] - 2026-05-10
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **simple cluster — 4th bespoke shell family** per ADR-0023. Minimal shell for marketing / landing / error pages:
|
|
19
|
+
- `<simple-shell>` (host) — behavior-only orchestrator. 2 reflected attributes: `[centered]` (vertical center), `[full-bleed]` (drops max-width).
|
|
20
|
+
- `<simple-content>` (CSS-only) — article body container with token-correct vertical rhythm.
|
|
21
|
+
- `<simple-hero>` (CSS-only) — optional top strip with 3 named slots (`heading`, `lede`, `actions`).
|
|
22
|
+
- Subpath export: `@adia-ai/web-modules/simple`.
|
|
23
|
+
- 10 unit tests for `<simple-shell>`.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Catalog count: 118 → 121 yamls (+3 from simple cluster children).
|
|
28
|
+
|
|
29
|
+
## [0.4.0] - 2026-05-10
|
|
30
|
+
|
|
31
|
+
**⚠️ BREAKING** — first non-patch release in the 0.x line. Closes the ADR-0023 arc per [ADR-0024](../../.brain/adrs/0024-legacy-shell-shapes-retired.md). All 6 in-repo consumers migrated in v0.3.6; this release retires the legacy authoring shapes from the shell hosts.
|
|
32
|
+
|
|
33
|
+
### Removed (BREAKING)
|
|
34
|
+
|
|
35
|
+
- **`<admin-shell>`** no longer reads `<aside-ui slot="leading|trailing">`, `<aside data-sidebar>`, `<dialog data-command>`, or `[data-resize]` external handle children. Use `<admin-sidebar slot resizable collapsible>` + `<admin-command>` instead.
|
|
36
|
+
- **`<chat-shell>`** no longer reads `<section data-chat-messages>`, `<chat-input-ui data-chat-input>`, `<empty-state-ui data-chat-empty>`, `<header>` with `[data-chat-name]` / `[data-chat-status]`. Use `<chat-thread>` + `<chat-composer>` + `<chat-empty>` + `<chat-header>` + `<chat-status>` instead.
|
|
37
|
+
- **`<editor-shell>`** no longer reads `<header>` toolbar, `<div data-editor-body>` wrapper, `<pane-ui data-left|data-right>`, `<div data-canvas>`, `<footer>` statusbar. Use `<editor-toolbar>` + `<editor-canvas>` + `<editor-sidebar slot>` + `<editor-statusbar>` + `<editor-canvas-empty>` instead.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- **`admin-shell.js` host** — 305 → 87 LOC (-71%). The host now does only `[mode]` reflection + 2 attribute-forwarding handlers. All resize / collapse / persistence / dialog wiring is owned by `<admin-sidebar>` and `<admin-command>` per ADR-0023.
|
|
42
|
+
- **`chat-shell.js` host** — `connected()` simplified; only `composer-submit` event recognized (no longer falls back to `submit`).
|
|
43
|
+
- **`editor-shell.js` host** — `connected()` drops dual-shape fallbacks.
|
|
44
|
+
- **CSS layered files** — all `:is(legacy, bespoke)` lifts collapsed to bespoke-only in `admin-shell.sidebar.css`, `admin-shell.shell.css`, `admin-shell.main.css`, `chat-shell.empty.css`, `chat-shell.layout.css`, `editor-shell.layout.css`.
|
|
45
|
+
- **CSS bridge files** — `admin-shell.bespoke.css` / `chat-shell.bespoke.css` / `editor-shell.bespoke.css` updated to canonical-styling commentary (no longer "bridge to existing selectors").
|
|
46
|
+
|
|
47
|
+
### Verification
|
|
48
|
+
|
|
49
|
+
- Bespoke children unit tests: **78/78** pass (admin 19 + chat 27 + editor 32)
|
|
50
|
+
- `npm run smoke:consumers` Playwright probe: **6/6** pass
|
|
51
|
+
- `npm run build:site`: clean
|
|
52
|
+
- `check-links --all`: 0 broken
|
|
53
|
+
|
|
54
|
+
### Migration
|
|
55
|
+
|
|
56
|
+
See root [CHANGELOG.md `## [0.4.0]`](../../CHANGELOG.md) for the full diff-style migration recipe. The 6 in-repo consumers (`apps/app-shell/`, `site/index.html`, `apps/chat/`, `apps/genui/gen-ui/`, `apps/construct-canvas/`, `apps/genui/a2ui-editor/`) were all migrated in v0.3.6 — see commit `c477d371`.
|
|
57
|
+
|
|
14
58
|
## [0.3.6] - 2026-05-10
|
|
15
59
|
|
|
16
60
|
### Added
|
package/README.md
CHANGED
|
@@ -5,6 +5,10 @@ Composite custom elements built from
|
|
|
5
5
|
into clusters by use case; each cluster ships as a subpath export so
|
|
6
6
|
consumers install only what they need.
|
|
7
7
|
|
|
8
|
+
Each cluster carries a **shell host** (behavior-only orchestrator) plus
|
|
9
|
+
a **family of bespoke shell-tier children** (cluster-namespaced custom
|
|
10
|
+
elements with state-as-attribute semantics) per [ADR-0023](../../.brain/adrs/0023-bespoke-shell-tier-children.md). The bespoke vocabulary is the only recognized authoring shape since v0.4.0 ([ADR-0024](../../.brain/adrs/0024-legacy-shell-shapes-retired.md)).
|
|
11
|
+
|
|
8
12
|
> The patterns directory lived inside `@adia-ai/web-components` as
|
|
9
13
|
> `patterns/` until this package was extracted (see
|
|
10
14
|
> [ADR-0012](../../.brain/adrs/0012-three-tier-architecture-modules.md)).
|
|
@@ -13,16 +17,17 @@ consumers install only what they need.
|
|
|
13
17
|
|
|
14
18
|
## Clusters
|
|
15
19
|
|
|
16
|
-
| Cluster |
|
|
17
|
-
|
|
18
|
-
| `shell` | `<admin-shell>` (
|
|
19
|
-
| `chat` | `<chat-shell>` | Conversational surface — messages,
|
|
20
|
-
| `editor` | `<editor-shell>` |
|
|
21
|
-
| `runtime` | `<gen-root>`, `<a2ui-root>` | Render roots that turn JSON or gen-UI intents into live DOM. |
|
|
20
|
+
| Cluster | Host | Bespoke children | What's inside |
|
|
21
|
+
|---|---|---|---|
|
|
22
|
+
| `shell` | `<admin-shell>` | `<admin-sidebar>`, `<admin-command>` (JS-bearing); `<admin-content>`, `<admin-topbar>`, `<admin-statusbar>`, `<admin-scroll>`, `<admin-page>`, `<admin-page-header>`, `<admin-page-body>` (CSS-only); 9 children total | Admin-shell composition: sidebars, command palette, page chrome. Resize/collapse/persistence on `<admin-sidebar>`; Cmd+K palette on `<admin-command>`. |
|
|
23
|
+
| `chat` | `<chat-shell>` | `<chat-thread>`, `<chat-composer>`, `<chat-sidebar>` (JS-bearing); `<chat-empty>`, `<chat-header>`, `<chat-status>` (CSS-only); 6 children total | Conversational surface — streaming messages, composer with `[disabled]` propagation, scroll-to-bottom thread, `[streaming]` reflected. |
|
|
24
|
+
| `editor` | `<editor-shell>` | `<editor-toolbar>`, `<editor-canvas>`, `<editor-sidebar>` (JS-bearing); `<editor-statusbar>`, `<editor-canvas-empty>` (CSS-only); 5 children total | Design-tool surface — toolbar with `[full-screen]`, central canvas with `[focused]`/`[empty]`, sidebar wraps `<pane-ui resizable>` for delegation. |
|
|
25
|
+
| `runtime` | `<gen-root>`, `<a2ui-root>` | — | Render roots that turn JSON or gen-UI intents into live DOM. |
|
|
22
26
|
|
|
23
27
|
Future clusters on the strategic horizon: `data` (kanban, filters,
|
|
24
|
-
table-toolbar), `agent` (agent-trace, reasoning panels)
|
|
25
|
-
|
|
28
|
+
table-toolbar), `agent` (agent-trace, reasoning panels).
|
|
29
|
+
|
|
30
|
+
See [`bespoke-shell-children` skill](../../.agents/skills/bespoke-shell-children/SKILL.md) for the canonical decomposition recipe used by all three families.
|
|
26
31
|
|
|
27
32
|
## Quick start
|
|
28
33
|
|
|
@@ -35,17 +40,26 @@ table-toolbar), `agent` (agent-trace, reasoning panels), `admin`
|
|
|
35
40
|
|
|
36
41
|
<script type="module">
|
|
37
42
|
import '@adia-ai/web-components'; // primitives + nav family
|
|
38
|
-
import '@adia-ai/web-modules/shell'; // admin-shell
|
|
39
|
-
import '@adia-ai/web-modules/chat'; //
|
|
40
|
-
import '@adia-ai/web-modules/
|
|
43
|
+
import '@adia-ai/web-modules/shell'; // admin-shell + bespoke children
|
|
44
|
+
import '@adia-ai/web-modules/chat'; // chat-shell + bespoke children
|
|
45
|
+
import '@adia-ai/web-modules/editor'; // editor-shell + bespoke children
|
|
46
|
+
import '@adia-ai/web-modules/runtime'; // gen-root, a2ui-root
|
|
41
47
|
</script>
|
|
42
48
|
|
|
49
|
+
<!-- Bespoke shape (canonical since v0.4.0): -->
|
|
43
50
|
<admin-shell mode="rounded">
|
|
44
|
-
<
|
|
45
|
-
<header-ui
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
<admin-sidebar slot="leading" resizable collapsible>
|
|
52
|
+
<header-ui>
|
|
53
|
+
<span slot="heading">App</span>
|
|
54
|
+
</header-ui>
|
|
55
|
+
<section-ui>
|
|
56
|
+
<nav-ui>…</nav-ui>
|
|
57
|
+
</section-ui>
|
|
58
|
+
</admin-sidebar>
|
|
48
59
|
<main>…</main>
|
|
60
|
+
<admin-command>
|
|
61
|
+
<command-ui placeholder="Search..."></command-ui>
|
|
62
|
+
</admin-command>
|
|
49
63
|
</admin-shell>
|
|
50
64
|
```
|
|
51
65
|
|
|
@@ -15,20 +15,22 @@ let msgId = 0;
|
|
|
15
15
|
* Behavior-only orchestrator: stamps no HTML of its own.
|
|
16
16
|
* The author writes the structure; chat-shell wires the behaviors.
|
|
17
17
|
*
|
|
18
|
-
* Structure:
|
|
18
|
+
* Structure (bespoke vocabulary per ADR-0023; **bespoke-only since v0.4.0**):
|
|
19
19
|
* <chat-shell proxy-url="/api/chat" model="claude-sonnet-4-20250514">
|
|
20
|
-
* <header>
|
|
21
|
-
* <span
|
|
22
|
-
* <
|
|
23
|
-
* </header>
|
|
24
|
-
* <
|
|
25
|
-
* <
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
20
|
+
* <chat-header>
|
|
21
|
+
* <span slot="name">Claude</span>
|
|
22
|
+
* <chat-status slot="status"></chat-status>
|
|
23
|
+
* </chat-header>
|
|
24
|
+
* <chat-thread>
|
|
25
|
+
* <chat-empty>
|
|
26
|
+
* <empty-state-ui icon="chat-circle"
|
|
27
|
+
* heading="Hello!" description="Ask me anything.">
|
|
28
|
+
* </empty-state-ui>
|
|
29
|
+
* </chat-empty>
|
|
30
|
+
* </chat-thread>
|
|
31
|
+
* <chat-composer>
|
|
32
|
+
* <chat-input-ui placeholder="Message..."></chat-input-ui>
|
|
33
|
+
* </chat-composer>
|
|
32
34
|
* </chat-shell>
|
|
33
35
|
*
|
|
34
36
|
* Two modes:
|
|
@@ -79,36 +81,22 @@ class ChatShell extends UIElement {
|
|
|
79
81
|
// ── Lifecycle ──
|
|
80
82
|
|
|
81
83
|
connected() {
|
|
82
|
-
//
|
|
83
|
-
// (chat-
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this.#
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
this.#
|
|
94
|
-
|| this.querySelector('[data-chat-status]');
|
|
95
|
-
|
|
96
|
-
// Bespoke <chat-composer> emits 'composer-submit' instead of 'submit'
|
|
97
|
-
// (so the legacy 'submit' event from inside <chat-input-ui> doesn't
|
|
98
|
-
// double-fire). Listen for both depending on which shape is present.
|
|
99
|
-
if (this.#inputEl?.tagName?.toLowerCase() === 'chat-composer') {
|
|
100
|
-
this.#inputEl.addEventListener('composer-submit', this.#onSubmit);
|
|
101
|
-
} else {
|
|
102
|
-
this.#inputEl?.addEventListener('submit', this.#onSubmit);
|
|
103
|
-
}
|
|
84
|
+
// **Bespoke-only since v0.4.0** (ADR-0023 Phase 3). The legacy
|
|
85
|
+
// shapes (<section data-chat-messages>, <chat-input-ui data-chat-input>,
|
|
86
|
+
// <empty-state-ui data-chat-empty>, [data-chat-status>, [data-chat-name>)
|
|
87
|
+
// are no longer recognized. Consumers MUST use the bespoke vocabulary.
|
|
88
|
+
this.#messagesEl = this.querySelector('chat-thread');
|
|
89
|
+
this.#inputEl = this.querySelector('chat-composer');
|
|
90
|
+
this.#emptyEl = this.querySelector('chat-empty');
|
|
91
|
+
this.#statusEl = this.querySelector('chat-status');
|
|
92
|
+
|
|
93
|
+
// <chat-composer> forwards inner <chat-input-ui> submit as
|
|
94
|
+
// composer-submit (bespoke event name prevents double-fire).
|
|
95
|
+
this.#inputEl?.addEventListener('composer-submit', this.#onSubmit);
|
|
104
96
|
}
|
|
105
97
|
|
|
106
98
|
disconnected() {
|
|
107
|
-
|
|
108
|
-
this.#inputEl.removeEventListener('composer-submit', this.#onSubmit);
|
|
109
|
-
} else {
|
|
110
|
-
this.#inputEl?.removeEventListener('submit', this.#onSubmit);
|
|
111
|
-
}
|
|
99
|
+
this.#inputEl?.removeEventListener('composer-submit', this.#onSubmit);
|
|
112
100
|
this.abort();
|
|
113
101
|
}
|
|
114
102
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
chat-shell — Empty state
|
|
3
3
|
═══════════════════════════════════════════════════════════════ */
|
|
4
4
|
|
|
5
|
-
chat-shell
|
|
5
|
+
chat-shell chat-empty {
|
|
6
6
|
margin: auto;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
chat-shell[streaming]
|
|
10
|
-
chat-shell:has([data-role])
|
|
9
|
+
chat-shell[streaming] chat-empty,
|
|
10
|
+
chat-shell:has([data-role]) chat-empty {
|
|
11
11
|
display: none;
|
|
12
12
|
}
|
|
@@ -29,14 +29,14 @@ chat-shell > header [data-chat-name] {
|
|
|
29
29
|
font-size: var(--chat-header-name-font);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
chat-shell > header
|
|
32
|
+
chat-shell > header chat-status {
|
|
33
33
|
font-size: var(--chat-header-status-font);
|
|
34
34
|
color: var(--chat-header-status-fg);
|
|
35
35
|
margin-inline-start: auto;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/* Messages scroll container */
|
|
39
|
-
chat-shell >
|
|
39
|
+
chat-shell > chat-thread,
|
|
40
40
|
chat-shell > section {
|
|
41
41
|
flex: 1;
|
|
42
42
|
overflow-y: auto;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<div>
|
|
3
|
+
<h1>Editor Canvas</h1>
|
|
4
|
+
<div data-actions>
|
|
5
|
+
<tag-ui size="sm">editor-canvas</tag-ui>
|
|
6
|
+
<tag-ui size="sm" variant="ghost">JS-bearing</tag-ui>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
<p>Module-tier editor canvas surface — replaces legacy <div data-canvas>. Owns scroll/zoom container, [empty] + [focused] reflected.</p>
|
|
10
|
+
</header>
|
|
11
|
+
|
|
12
|
+
<section data-section>
|
|
13
|
+
<h2 variant="section">Role</h2>
|
|
14
|
+
<p>Per <a href="../../../../.brain/adrs/0023-bespoke-shell-tier-children.md">ADR-0023</a>, the editor cluster's bespoke family — <code><editor-shell></code> (host), <code><editor-toolbar></code>, <code><editor-canvas></code>, <code><editor-sidebar></code> (JS-bearing) + <code><editor-statusbar></code>, <code><editor-canvas-empty></code> (CSS-only). Confirms the family pattern is canonical across 3 archetypes (admin/chat/editor).</p>
|
|
15
|
+
</section>
|
|
16
|
+
|
|
17
|
+
<section data-section>
|
|
18
|
+
<h2 variant="section">Composition</h2>
|
|
19
|
+
<p>Typical placement inside <code><editor-shell></code>:</p>
|
|
20
|
+
<code-ui language="html"><editor-shell>
|
|
21
|
+
<editor-toolbar>
|
|
22
|
+
<span slot="title">Untitled.fig</span>
|
|
23
|
+
<button-ui slot="action" icon="gear"></button-ui>
|
|
24
|
+
</editor-toolbar>
|
|
25
|
+
|
|
26
|
+
<editor-sidebar slot="leading" collapsible>
|
|
27
|
+
<pane-ui resizable>
|
|
28
|
+
<header>Navigator</header>
|
|
29
|
+
<section>…layers…</section>
|
|
30
|
+
</pane-ui>
|
|
31
|
+
</editor-sidebar>
|
|
32
|
+
|
|
33
|
+
<editor-canvas>
|
|
34
|
+
<editor-canvas-empty>
|
|
35
|
+
<empty-state-ui icon="square" heading="New document" description="Drop content to begin."></empty-state-ui>
|
|
36
|
+
</editor-canvas-empty>
|
|
37
|
+
</editor-canvas>
|
|
38
|
+
|
|
39
|
+
<editor-sidebar slot="trailing" collapsible>
|
|
40
|
+
<pane-ui resizable>
|
|
41
|
+
<header>Inspector</header>
|
|
42
|
+
<section>…properties…</section>
|
|
43
|
+
</pane-ui>
|
|
44
|
+
</editor-sidebar>
|
|
45
|
+
|
|
46
|
+
<editor-statusbar>
|
|
47
|
+
<span slot="status">Saved</span>
|
|
48
|
+
<span slot="zoom">100%</span>
|
|
49
|
+
</editor-statusbar>
|
|
50
|
+
</editor-shell></code-ui>
|
|
51
|
+
</section>
|
|
52
|
+
|
|
53
|
+
<section data-section>
|
|
54
|
+
<h2 variant="section">State as attribute</h2>
|
|
55
|
+
<code-ui language="css">/* Hide all chrome in focus mode */
|
|
56
|
+
editor-shell[focus-mode] :is(editor-toolbar, editor-statusbar, editor-sidebar) {
|
|
57
|
+
display: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Visual treatment for empty canvas */
|
|
61
|
+
editor-canvas[empty] { /* placeholder UI */ }
|
|
62
|
+
|
|
63
|
+
/* Highlight focused canvas */
|
|
64
|
+
editor-canvas[focused] { outline: 2px solid var(--a-accent); }</code-ui>
|
|
65
|
+
</section>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="auto">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Editor Canvas — AdiaUI</title>
|
|
7
|
+
|
|
8
|
+
<link rel="stylesheet" href="../../../web-components/styles/resets.css">
|
|
9
|
+
<link rel="stylesheet" href="../../../web-components/styles/tokens.css">
|
|
10
|
+
<link rel="stylesheet" href="../editor-shell/editor-shell.css">
|
|
11
|
+
<link rel="stylesheet" href="../../../web-components/components/code/code.css">
|
|
12
|
+
<link rel="stylesheet" href="../../../web-components/components/tag/tag.css">
|
|
13
|
+
|
|
14
|
+
<script type="module" src="../editor-shell/editor-shell.js"></script>
|
|
15
|
+
<script type="module" src="./editor-canvas.js"></script>
|
|
16
|
+
<script type="module" src="../../../web-components/components/code/code.js"></script>
|
|
17
|
+
<script type="module" src="../../../web-components/components/tag/tag.js"></script>
|
|
18
|
+
|
|
19
|
+
<style>
|
|
20
|
+
:where(html, body) { margin: 0; min-height: 100vh; background: var(--a-bg); color: var(--a-fg); font-family: var(--a-font); }
|
|
21
|
+
main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
|
|
22
|
+
</style>
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
|
|
26
|
+
<main id="demo-root">
|
|
27
|
+
<p>Loading examples…</p>
|
|
28
|
+
</main>
|
|
29
|
+
|
|
30
|
+
<script type="module">
|
|
31
|
+
const root = document.getElementById('demo-root');
|
|
32
|
+
try {
|
|
33
|
+
const res = await fetch('./editor-canvas.examples.html');
|
|
34
|
+
if (!res.ok) throw new Error(`fetch failed (${res.status})`);
|
|
35
|
+
root.innerHTML = await res.text();
|
|
36
|
+
} catch (err) {
|
|
37
|
+
root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load editor-canvas.examples.html — ${err.message}</p>`;
|
|
38
|
+
console.error('[editor-canvas.html]', err);
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
</body>
|
|
43
|
+
</html>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<div>
|
|
3
|
+
<h1>Editor Canvas Empty</h1>
|
|
4
|
+
<div data-actions>
|
|
5
|
+
<tag-ui size="sm">editor-canvas-empty</tag-ui>
|
|
6
|
+
<tag-ui size="sm" variant="ghost">CSS-only</tag-ui>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
<p>Module-tier editor canvas empty state. CSS-only. Visibility driven by parent <editor-canvas>[empty].</p>
|
|
10
|
+
</header>
|
|
11
|
+
|
|
12
|
+
<section data-section>
|
|
13
|
+
<h2 variant="section">Role</h2>
|
|
14
|
+
<p>Per <a href="../../../../.brain/adrs/0023-bespoke-shell-tier-children.md">ADR-0023</a>, the editor cluster's bespoke family — <code><editor-shell></code> (host), <code><editor-toolbar></code>, <code><editor-canvas></code>, <code><editor-sidebar></code> (JS-bearing) + <code><editor-statusbar></code>, <code><editor-canvas-empty></code> (CSS-only). Confirms the family pattern is canonical across 3 archetypes (admin/chat/editor).</p>
|
|
15
|
+
</section>
|
|
16
|
+
|
|
17
|
+
<section data-section>
|
|
18
|
+
<h2 variant="section">Composition</h2>
|
|
19
|
+
<p>Typical placement inside <code><editor-shell></code>:</p>
|
|
20
|
+
<code-ui language="html"><editor-shell>
|
|
21
|
+
<editor-toolbar>
|
|
22
|
+
<span slot="title">Untitled.fig</span>
|
|
23
|
+
<button-ui slot="action" icon="gear"></button-ui>
|
|
24
|
+
</editor-toolbar>
|
|
25
|
+
|
|
26
|
+
<editor-sidebar slot="leading" collapsible>
|
|
27
|
+
<pane-ui resizable>
|
|
28
|
+
<header>Navigator</header>
|
|
29
|
+
<section>…layers…</section>
|
|
30
|
+
</pane-ui>
|
|
31
|
+
</editor-sidebar>
|
|
32
|
+
|
|
33
|
+
<editor-canvas>
|
|
34
|
+
<editor-canvas-empty>
|
|
35
|
+
<empty-state-ui icon="square" heading="New document" description="Drop content to begin."></empty-state-ui>
|
|
36
|
+
</editor-canvas-empty>
|
|
37
|
+
</editor-canvas>
|
|
38
|
+
|
|
39
|
+
<editor-sidebar slot="trailing" collapsible>
|
|
40
|
+
<pane-ui resizable>
|
|
41
|
+
<header>Inspector</header>
|
|
42
|
+
<section>…properties…</section>
|
|
43
|
+
</pane-ui>
|
|
44
|
+
</editor-sidebar>
|
|
45
|
+
|
|
46
|
+
<editor-statusbar>
|
|
47
|
+
<span slot="status">Saved</span>
|
|
48
|
+
<span slot="zoom">100%</span>
|
|
49
|
+
</editor-statusbar>
|
|
50
|
+
</editor-shell></code-ui>
|
|
51
|
+
</section>
|
|
52
|
+
|
|
53
|
+
<section data-section>
|
|
54
|
+
<h2 variant="section">State as attribute</h2>
|
|
55
|
+
<code-ui language="css">/* Hide all chrome in focus mode */
|
|
56
|
+
editor-shell[focus-mode] :is(editor-toolbar, editor-statusbar, editor-sidebar) {
|
|
57
|
+
display: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Visual treatment for empty canvas */
|
|
61
|
+
editor-canvas[empty] { /* placeholder UI */ }
|
|
62
|
+
|
|
63
|
+
/* Highlight focused canvas */
|
|
64
|
+
editor-canvas[focused] { outline: 2px solid var(--a-accent); }</code-ui>
|
|
65
|
+
</section>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="auto">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Editor Canvas Empty — AdiaUI</title>
|
|
7
|
+
|
|
8
|
+
<link rel="stylesheet" href="../../../web-components/styles/resets.css">
|
|
9
|
+
<link rel="stylesheet" href="../../../web-components/styles/tokens.css">
|
|
10
|
+
<link rel="stylesheet" href="../editor-shell/editor-shell.css">
|
|
11
|
+
<link rel="stylesheet" href="../../../web-components/components/code/code.css">
|
|
12
|
+
<link rel="stylesheet" href="../../../web-components/components/tag/tag.css">
|
|
13
|
+
|
|
14
|
+
<script type="module" src="../editor-shell/editor-shell.js"></script>
|
|
15
|
+
<script type="module" src="../../../web-components/components/code/code.js"></script>
|
|
16
|
+
<script type="module" src="../../../web-components/components/tag/tag.js"></script>
|
|
17
|
+
|
|
18
|
+
<style>
|
|
19
|
+
:where(html, body) { margin: 0; min-height: 100vh; background: var(--a-bg); color: var(--a-fg); font-family: var(--a-font); }
|
|
20
|
+
main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
|
|
25
|
+
<main id="demo-root">
|
|
26
|
+
<p>Loading examples…</p>
|
|
27
|
+
</main>
|
|
28
|
+
|
|
29
|
+
<script type="module">
|
|
30
|
+
const root = document.getElementById('demo-root');
|
|
31
|
+
try {
|
|
32
|
+
const res = await fetch('./editor-canvas-empty.examples.html');
|
|
33
|
+
if (!res.ok) throw new Error(`fetch failed (${res.status})`);
|
|
34
|
+
root.innerHTML = await res.text();
|
|
35
|
+
} catch (err) {
|
|
36
|
+
root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load editor-canvas-empty.examples.html — ${err.message}</p>`;
|
|
37
|
+
console.error('[editor-canvas-empty.html]', err);
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|
|
@@ -129,11 +129,76 @@ editor-sidebar > pane-ui {
|
|
|
129
129
|
flex-direction: column;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
/*
|
|
133
|
-
|
|
132
|
+
/* ── editor-sidebar collapsed-mode polish ──
|
|
133
|
+
When collapsed: pane shrinks to icon-rail width (48px); section
|
|
134
|
+
content hides; header narrows to icon-only with horizontal-center;
|
|
135
|
+
smooth width transition on uncollapse. Mirrors the rail-pattern
|
|
136
|
+
established by admin-sidebar's collapsed state.
|
|
137
|
+
═══════════════════════════════════════════════════════════════ */
|
|
138
|
+
|
|
139
|
+
editor-sidebar {
|
|
140
|
+
transition: width var(--editor-sidebar-duration, var(--a-duration, 180ms))
|
|
141
|
+
var(--editor-sidebar-easing, var(--a-easing, ease));
|
|
142
|
+
container-type: inline-size;
|
|
143
|
+
container-name: editor-sidebar;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* Inner pane animates the visible width */
|
|
147
|
+
editor-sidebar > pane-ui {
|
|
148
|
+
transition: width var(--editor-sidebar-duration, var(--a-duration, 180ms))
|
|
149
|
+
var(--editor-sidebar-easing, var(--a-easing, ease));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* Collapsed state — hide section/footer content; preserve header icons */
|
|
153
|
+
editor-sidebar[collapsed] > pane-ui {
|
|
154
|
+
width: var(--editor-sidebar-collapsed-width, 48px) !important;
|
|
155
|
+
min-width: var(--editor-sidebar-collapsed-width, 48px);
|
|
156
|
+
overflow: hidden;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
editor-sidebar[collapsed] > pane-ui > section,
|
|
160
|
+
editor-sidebar[collapsed] > pane-ui > footer {
|
|
161
|
+
display: none;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* Collapsed header — center icons horizontally; hide text labels */
|
|
165
|
+
editor-sidebar[collapsed] > pane-ui > header {
|
|
166
|
+
display: flex;
|
|
167
|
+
flex-direction: column;
|
|
168
|
+
align-items: center;
|
|
169
|
+
justify-content: flex-start;
|
|
170
|
+
gap: var(--a-space-1);
|
|
171
|
+
padding: var(--a-space-2) 0;
|
|
172
|
+
/* Hide direct text nodes via opacity-0 + descendant text containers */
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Collapsed header — hide text labels next to icons */
|
|
176
|
+
editor-sidebar[collapsed] > pane-ui > header :is(
|
|
177
|
+
span:not([data-icon]):not([slot]),
|
|
178
|
+
label,
|
|
179
|
+
h1, h2, h3
|
|
180
|
+
) {
|
|
134
181
|
display: none;
|
|
135
182
|
}
|
|
136
183
|
|
|
184
|
+
/* Provide a visual rail affordance */
|
|
185
|
+
editor-sidebar[collapsed] {
|
|
186
|
+
background: var(--editor-sidebar-rail-bg, var(--a-bg-subtle, var(--a-bg)));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* Container query — child elements can adapt to narrow mode */
|
|
190
|
+
@container editor-sidebar (max-width: 96px) {
|
|
191
|
+
/* Children can hide labels / shrink icons via [data-narrow] */
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* When resizing — disable transitions to feel responsive */
|
|
195
|
+
editor-sidebar[resizing] {
|
|
196
|
+
transition: none;
|
|
197
|
+
}
|
|
198
|
+
editor-sidebar[resizing] > pane-ui {
|
|
199
|
+
transition: none;
|
|
200
|
+
}
|
|
201
|
+
|
|
137
202
|
/* ── editor-statusbar — bottom chrome bar ── */
|
|
138
203
|
editor-shell > editor-statusbar {
|
|
139
204
|
display: flex;
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
Structure:
|
|
5
5
|
editor-shell
|
|
6
6
|
header — topbar
|
|
7
|
-
|
|
7
|
+
— flex row: pane | canvas | pane
|
|
8
8
|
pane-ui — left navigator
|
|
9
|
-
|
|
9
|
+
editor-canvas — center canvas
|
|
10
10
|
pane-ui — right inspector
|
|
11
11
|
footer — bottombar
|
|
12
12
|
═══════════════════════════════════════════════════════════════ */
|
|
@@ -82,7 +82,7 @@ editor-shell > header > [slot="action-leading"] {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/* ── Body: pane | canvas | pane ── */
|
|
85
|
-
editor-shell >
|
|
85
|
+
editor-shell > {
|
|
86
86
|
display: flex;
|
|
87
87
|
flex: 1;
|
|
88
88
|
min-width: 0;
|
|
@@ -90,7 +90,7 @@ editor-shell > [data-editor-body] {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/* ── Canvas ── */
|
|
93
|
-
editor-shell
|
|
93
|
+
editor-shell editor-canvas {
|
|
94
94
|
flex: 1;
|
|
95
95
|
min-width: 0;
|
|
96
96
|
display: flex;
|
|
@@ -107,11 +107,11 @@ editor-shell pane-ui {
|
|
|
107
107
|
flex-shrink: 0;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
editor-shell
|
|
110
|
+
editor-shell editor-sidebar[slot="leading"] > pane-ui {
|
|
111
111
|
width: var(--editor-pane-width-left);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
editor-shell
|
|
114
|
+
editor-shell editor-sidebar[slot="trailing"] > pane-ui {
|
|
115
115
|
width: var(--editor-pane-width-right);
|
|
116
116
|
}
|
|
117
117
|
|
|
@@ -2,26 +2,27 @@ import { UIElement } from '../../../web-components/core/element.js';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* <editor-shell focus-mode?>
|
|
5
|
-
* <editor-toolbar>...</editor-toolbar>
|
|
6
|
-
* <editor-sidebar slot="leading">
|
|
5
|
+
* <editor-toolbar>...</editor-toolbar>
|
|
6
|
+
* <editor-sidebar slot="leading">
|
|
7
7
|
* <pane-ui resizable>...</pane-ui>
|
|
8
8
|
* </editor-sidebar>
|
|
9
|
-
* <editor-canvas>...</editor-canvas>
|
|
10
|
-
* <editor-sidebar slot="trailing">
|
|
9
|
+
* <editor-canvas>...</editor-canvas>
|
|
10
|
+
* <editor-sidebar slot="trailing">
|
|
11
11
|
* <pane-ui resizable>...</pane-ui>
|
|
12
12
|
* </editor-sidebar>
|
|
13
|
-
* <editor-statusbar>...</editor-statusbar>
|
|
13
|
+
* <editor-statusbar>...</editor-statusbar>
|
|
14
14
|
* </editor-shell>
|
|
15
15
|
*
|
|
16
16
|
* Behavior-only orchestrator for design-tool UIs:
|
|
17
17
|
* topbar, navigator pane, center canvas, inspector pane, bottombar.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* the
|
|
23
|
-
* 2 CSS-only structural stubs —
|
|
24
|
-
* resize and the editor doesn't need
|
|
19
|
+
* **Bespoke-only since v0.4.0** (ADR-0023 Phase 3). The legacy shapes
|
|
20
|
+
* (<header>, <div data-editor-body>, <pane-ui data-left|data-right>,
|
|
21
|
+
* <div data-canvas>, <footer>) are no longer recognized. The editor
|
|
22
|
+
* cluster has the smallest bespoke family of the three (admin / chat /
|
|
23
|
+
* editor) — only 3 JS-bearing children + 2 CSS-only structural stubs —
|
|
24
|
+
* because <pane-ui> already owns resize and the editor doesn't need
|
|
25
|
+
* a command palette.
|
|
25
26
|
*
|
|
26
27
|
* Reflected attributes:
|
|
27
28
|
* [focus-mode] — distraction-free / canvas-focus mode; consumers
|
|
@@ -48,13 +49,14 @@ class EditorShell extends UIElement {
|
|
|
48
49
|
#onToolbarAction = null;
|
|
49
50
|
|
|
50
51
|
connected() {
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
// **Bespoke-only since v0.4.0** (ADR-0023 Phase 3). The legacy
|
|
53
|
+
// shapes (<header>, <div data-canvas>, <div data-editor-body>,
|
|
54
|
+
// <pane-ui data-left|data-right>, <footer>) are no longer
|
|
55
|
+
// recognized. Consumers MUST use the bespoke vocabulary.
|
|
56
|
+
this.#toolbarEl = this.querySelector('editor-toolbar');
|
|
57
|
+
this.#canvasEl = this.querySelector('editor-canvas');
|
|
56
58
|
|
|
57
|
-
// Wire select options
|
|
59
|
+
// Wire select options inside the toolbar / sidebars
|
|
58
60
|
this.#wireSelects();
|
|
59
61
|
|
|
60
62
|
// Listen for toolbar-action bubbling from <editor-toolbar>
|