@adia-ai/web-modules 0.8.3 → 0.8.5
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 +24 -0
- package/README.md +11 -0
- package/chat/chat-shell/chat-shell.js +28 -8
- package/chat/chat-sidebar/chat-sidebar.js +2 -0
- package/chat/chat-thread/chat-thread.js +2 -0
- package/dist/chat/chat-shell.min.js +26 -26
- package/dist/editor/editor-shell.min.js +7 -7
- package/dist/everything.min.js +142 -141
- package/dist/shell/admin-shell.min.js +2 -2
- package/dist/simple/simple-shell.min.js +6 -6
- package/dist/web-modules.min.css +1 -1
- package/dist/web-modules.sheet.js +1 -1
- package/editor/editor-canvas/editor-canvas.js +2 -0
- package/editor/editor-sidebar/editor-sidebar.js +15 -12
- package/package.json +1 -25
- package/shell/admin-sidebar/admin-sidebar.js +24 -3
- package/shell/admin-sidebar/admin-sidebar.test.js +50 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
# Changelog — @adia-ai/web-modules
|
|
2
|
+
|
|
3
|
+
## [0.8.5] — 2026-07-17
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **`scripts/verify/exports-wildcard-resolution.mjs`** (gh#296, shared with `@adia-ai/web-components`): live-resolution regression gate asserting every documented short-form CSS/JS subpath specifier resolves to a real on-disk file. Removed 6 dead exports-map keys (`./shell/*/*.css`, `./chat/*/*.css`, `./editor/*/*.css`, `./simple/*/*.css`, `./runtime/*/*.css`, `./theme/*/*.css`) — confirmed via live `import.meta.resolve()` testing that these never actually resolved (Node's pattern matching always picked the single-wildcard sibling key instead), so they provided no real "nested form" support despite looking like they did. Documented the underlying trap (a redundant nested specifier like `shell/admin-command/admin-command.css` silently resolves to a garbage, nonexistent quadrupled path instead of throwing) in `README.md` — not fixable in the exports map itself, since Node's `*` matches across `/` with no way to constrain it to one path segment.
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- **`shell/admin-sidebar`: a zero-rect connect no longer snaps the sidebar collapsed (gh#286)**: `connectedCallback` read `getBoundingClientRect().width` synchronously and derived `[collapsed]` from it unconditionally — SSR shims (no layout engine) and any early-connect case (an ancestor `display:none`) always return 0×0, which unconditionally satisfied the collapse threshold. A zero width is now treated as "unknown," not "collapsed" — `#syncCollapsedFromWidth()` no-ops on a 0 read; the existing per-host `ResizeObserver` now also derives `[collapsed]` from its first tick as the deferred correction. 3 new tests cover the zero-rect connect, a persisted-width survival case, and the `ResizeObserver` self-correction in both directions.
|
|
10
|
+
- **Browser-only API call sites guarded for SSR (gh#285, shared with `@adia-ai/web-components`)**: `chat/chat-sidebar`, `chat/chat-thread`, `dashboard/dashboard-layout`, `editor/editor-canvas`, `editor/editor-sidebar`, and `shell/admin-sidebar` had unconditional `ResizeObserver`/`IntersectionObserver`/`MutationObserver` construction sites, now feature-detected — same audit and fix shape as `@adia-ai/web-components`; see `packages/web-components/CHANGELOG.md#085--2026-07-17` for the framework-wide detail.
|
|
11
|
+
|
|
12
|
+
### Maintenance
|
|
13
|
+
- **`dist/` bundles rebuilt** (`chat/chat-shell.min.js`, `editor/editor-shell.min.js`, `shell/admin-shell.min.js`, `simple/simple-shell.min.js`, `everything.min.js`) — picks up the gh#285/gh#286 source fixes above.
|
|
14
|
+
|
|
15
|
+
## [0.8.4] — 2026-07-16
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **`chat-shell.appendMessage({ html: true })`** — assistant messages can carry trusted app-authored component markup (light-DOM upgrade in place); the `render` (markdown) path escapes inline HTML by design, which made gen-ui's error bubbles show raw `<col-ui …>` source text. The html mode persists on the message record and survives `stopStreaming()` and `conversation` getter/setter round-trips.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- **`billing/payment-method-list` row focus ring double-drew the edge** — the focused row kept its 1px card border under the ring (`outline` + `outline-offset`); `border-color: transparent` while focused, per the framework-wide focus-ring pairing ruling (2026-07-16).
|
|
22
|
+
|
|
23
|
+
### Maintenance
|
|
24
|
+
- **`dist/` bundles rebuilt** (`chat/chat-shell.min.js`, `everything.min.js` — the chat-shell change plus the inlined @adia-ai/llm provider-routing fixes).
|
|
25
|
+
|
|
2
26
|
## [0.8.3] — 2026-07-16
|
|
3
27
|
|
|
4
28
|
### Maintenance
|
package/README.md
CHANGED
|
@@ -168,6 +168,17 @@ import '@adia-ai/web-modules/runtime/gen-root.css';
|
|
|
168
168
|
|
|
169
169
|
> **For pre-v0.4.5 consumers:** if you were importing CSS via the relative `node_modules` path (`'../node_modules/@adia-ai/web-modules/editor/editor-shell/editor-shell.css'`), switch to the package-specifier form above. The relative-path form is fragile under pnpm, Yarn PnP, and npm hoisting; the new package-specifier form works under all three.
|
|
170
170
|
|
|
171
|
+
> **Don't repeat the directory name.** Every cluster child lives at
|
|
172
|
+
> `<cluster>/<name>/<name>.css` on disk (e.g. `shell/admin-command/admin-command.css`),
|
|
173
|
+
> so `@adia-ai/web-modules/shell/admin-command/admin-command.css` looks like
|
|
174
|
+
> the natural specifier — it is NOT. Use the short form,
|
|
175
|
+
> `@adia-ai/web-modules/shell/admin-command.css`, exactly as shown above.
|
|
176
|
+
> The nested form silently resolves to a garbage, nonexistent path
|
|
177
|
+
> (the directory name quadrupled) instead of a clear "not found" error —
|
|
178
|
+
> Node's exports-map wildcards match across `/` with no way to prevent
|
|
179
|
+
> this, so it can't be fixed in the package. Tracked as
|
|
180
|
+
> [gh#296](https://github.com/adiahealth/gen-ui-kit/issues/296).
|
|
181
|
+
|
|
171
182
|
## Import: JS + CSS in one line (`/with-css`)
|
|
172
183
|
|
|
173
184
|
For the `shell` cluster, the `/with-css` opt-in collapses the JS + CSS
|
|
@@ -66,13 +66,15 @@ class ChatShell extends UIElement {
|
|
|
66
66
|
get conversation() {
|
|
67
67
|
return this.#messages
|
|
68
68
|
.filter(m => m.role === 'user' || m.role === 'assistant')
|
|
69
|
-
.map(m => ({ role: m.role, content: m.content }));
|
|
69
|
+
.map(m => (m.html ? { role: m.role, content: m.content, html: true } : { role: m.role, content: m.content }));
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
set conversation(msgs) {
|
|
73
73
|
this.clear();
|
|
74
74
|
for (const m of msgs) {
|
|
75
|
-
|
|
75
|
+
// Round-trip the html mode — re-rendering an html message through
|
|
76
|
+
// the markdown path would escape its component markup.
|
|
77
|
+
this.appendMessage({ role: m.role, content: m.content, render: !m.html, html: !!m.html });
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
|
|
@@ -122,9 +124,22 @@ class ChatShell extends UIElement {
|
|
|
122
124
|
|
|
123
125
|
// ── Message management ──
|
|
124
126
|
|
|
125
|
-
|
|
127
|
+
/**
|
|
128
|
+
* @param {object} msg
|
|
129
|
+
* @param {string} msg.role — 'user' | 'assistant' | 'error'
|
|
130
|
+
* @param {string} [msg.content]
|
|
131
|
+
* @param {boolean} [msg.render] — treat content as MARKDOWN (inline HTML
|
|
132
|
+
* is escaped — component markup shows as literal text under this flag)
|
|
133
|
+
* @param {boolean} [msg.html] — assistant only: insert content as raw
|
|
134
|
+
* HTML (light-DOM component markup upgrades in place). TRUSTED
|
|
135
|
+
* app-authored strings only — never LLM output or user input; the
|
|
136
|
+
* caller owns escaping of any interpolated values.
|
|
137
|
+
*/
|
|
138
|
+
appendMessage({ role, content = '', render: renderMd = false, html = false }) {
|
|
126
139
|
const id = `msg_${++msgId}`;
|
|
127
|
-
|
|
140
|
+
// html persists on the record: stopStreaming() and the conversation
|
|
141
|
+
// setter must never push an html message back through the markdown path.
|
|
142
|
+
this.#messages.push({ id, role, content, html });
|
|
128
143
|
|
|
129
144
|
const el = document.createElement('div');
|
|
130
145
|
el.setAttribute('data-role', role);
|
|
@@ -133,10 +148,13 @@ class ChatShell extends UIElement {
|
|
|
133
148
|
if (role === 'user') {
|
|
134
149
|
el.innerHTML = `<div data-bubble>${escapeHTML(content)}</div>`;
|
|
135
150
|
} else if (role === 'assistant') {
|
|
136
|
-
const
|
|
151
|
+
const done = renderMd || html;
|
|
152
|
+
const rendered = html ? content
|
|
153
|
+
: renderMd && content ? renderMarkdown(content)
|
|
154
|
+
: escapeHTML(content);
|
|
137
155
|
el.innerHTML = `
|
|
138
156
|
<span data-avatar>AI</span>
|
|
139
|
-
<div data-bubble><div data-content>${rendered}</div>${!
|
|
157
|
+
<div data-bubble><div data-content>${rendered}</div>${!done ? '<span data-cursor></span>' : ''}</div>
|
|
140
158
|
`;
|
|
141
159
|
} else if (role === 'error') {
|
|
142
160
|
el.innerHTML = `<icon-ui name="warning"></icon-ui><span>${escapeHTML(content)}</span>`;
|
|
@@ -202,9 +220,11 @@ class ChatShell extends UIElement {
|
|
|
202
220
|
// Remove cursor
|
|
203
221
|
this.#messagesEl?.querySelector('[data-role]:last-child [data-cursor]')?.remove();
|
|
204
222
|
|
|
205
|
-
// Render markdown in last assistant bubble
|
|
223
|
+
// Render markdown in last assistant bubble — never an html-mode
|
|
224
|
+
// message: its component markup is already live DOM, and the markdown
|
|
225
|
+
// path would re-escape it to source text.
|
|
206
226
|
const last = this.#messages[this.#messages.length - 1];
|
|
207
|
-
if (last?.role === 'assistant' && last.content) {
|
|
227
|
+
if (last?.role === 'assistant' && last.content && !last.html) {
|
|
208
228
|
const contentEl = this.#messagesEl?.querySelector('[data-role]:last-child [data-content]');
|
|
209
229
|
if (contentEl) {
|
|
210
230
|
contentEl.innerHTML = renderMarkdown(last.content);
|
|
@@ -202,6 +202,8 @@ class ChatSidebar extends UIElement {
|
|
|
202
202
|
// ── Child ResizeObserver — flips select-ui placement in narrow mode ──
|
|
203
203
|
|
|
204
204
|
#setupChildResizeObserver() {
|
|
205
|
+
// gh#285 — SSR DOM shims (linkedom) have no ResizeObserver global.
|
|
206
|
+
if (typeof ResizeObserver === 'undefined') return;
|
|
205
207
|
this.#childRO = new ResizeObserver((entries) => {
|
|
206
208
|
for (const entry of entries) {
|
|
207
209
|
const narrow = entry.contentBoxSize[0].inlineSize <= SNAP_THRESHOLD;
|
|
@@ -81,6 +81,8 @@ class ChatThread extends UIElement {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
#setupChildObserver() {
|
|
84
|
+
// gh#285 — SSR DOM shims (linkedom) have no MutationObserver global.
|
|
85
|
+
if (typeof MutationObserver === 'undefined') return;
|
|
84
86
|
this.#childObserver = new MutationObserver(() => {
|
|
85
87
|
this.#syncEmptyFromChildren();
|
|
86
88
|
// New message added — scroll to bottom if user is at bottom
|