@adia-ai/web-modules 0.8.24 → 0.8.25

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-modules",
3
- "version": "0.8.24",
3
+ "version": "0.8.25",
4
4
  "description": "AdiaUI composite custom elements — shell, chat, editor, runtime clusters built from @adia-ai/web-components primitives. Subpath exports per cluster.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -270,9 +270,9 @@
270
270
  "./theme/**/*.js"
271
271
  ],
272
272
  "peerDependencies": {
273
- "@adia-ai/web-components": "0.8.24",
274
- "@adia-ai/a2ui-runtime": "0.8.24",
275
- "@adia-ai/llm": "0.8.24"
273
+ "@adia-ai/web-components": "0.8.25",
274
+ "@adia-ai/a2ui-runtime": "0.8.25",
275
+ "@adia-ai/llm": "0.8.25"
276
276
  },
277
277
  "publishConfig": {
278
278
  "access": "public",
@@ -24,7 +24,7 @@
24
24
  * [register] renders the Scale row — one of the six
25
25
  * [scale] tiers (ui-sm/ui-md/ui-lg/
26
26
  * content-sm/content-md/content-lg)
27
- * [scheme-toggle] renders an integrated light/dark segmented-ui
27
+ * [scheme-toggle] renders an integrated System/Light/Dark segmented-ui
28
28
  * [persist] writes selections to localStorage
29
29
  * [storage-prefix="adia-theme-"] LS key namespace
30
30
  * [target=":root"] CSS selector for theme target (default <html>)
@@ -109,6 +109,7 @@ class ThemePanel extends UIElement {
109
109
  if (this.#stamped) return;
110
110
  this.#stamp();
111
111
  this.#stamped = true;
112
+ this.#syncParametricScope();
112
113
  this.#initState();
113
114
  this.#wirePrefersColorScheme();
114
115
  }
@@ -117,6 +118,7 @@ class ThemePanel extends UIElement {
117
118
  for (const cleanup of this.#cleanups) cleanup();
118
119
  this.#cleanups = [];
119
120
  this.#detachPcm();
121
+ if (this.parametric) this.#resolveTarget().removeAttribute('data-parametric-scope');
120
122
  }
121
123
 
122
124
  // ── Public API ──────────────────────────────────────────────────────
@@ -150,10 +152,11 @@ class ThemePanel extends UIElement {
150
152
  this.activeDensity = '';
151
153
  this.activeRadius = '';
152
154
  this.activeScale = '';
153
- // Resolved scheme falls back to prefers-color-scheme
154
- const resolved = this.#resolvePrefersScheme();
155
- this.activeScheme = resolved;
156
- if (this.#schemeEl) this.#schemeEl.value = resolved;
155
+ // Resolved scheme falls back to prefers-color-scheme; reset always
156
+ // returns the RAW intent to auto (System) regardless of resolution.
157
+ this.scheme = 'auto';
158
+ this.activeScheme = this.#resolvePrefersScheme();
159
+ if (this.#schemeEl) this.#schemeEl.value = 'auto';
157
160
  if (this.#densityEl) this.#densityEl.value = 1;
158
161
  if (this.#radiusEl) this.#radiusEl.value = 1;
159
162
  if (this.#scaleEl) this.#scaleEl.value = '';
@@ -172,13 +175,16 @@ class ThemePanel extends UIElement {
172
175
  scheme.setAttribute('part', 'scheme');
173
176
  const seg = document.createElement('segmented-ui');
174
177
  seg.id = `${this.#uid}-scheme`;
178
+ const segAuto = document.createElement('segment-ui');
179
+ segAuto.setAttribute('value', 'auto');
180
+ segAuto.setAttribute('text', 'System');
175
181
  const segLight = document.createElement('segment-ui');
176
182
  segLight.setAttribute('value', 'light');
177
183
  segLight.setAttribute('text', 'Light');
178
184
  const segDark = document.createElement('segment-ui');
179
185
  segDark.setAttribute('value', 'dark');
180
186
  segDark.setAttribute('text', 'Dark');
181
- seg.append(segLight, segDark);
187
+ seg.append(segAuto, segLight, segDark);
182
188
  scheme.appendChild(seg);
183
189
  frag.appendChild(scheme);
184
190
  this.#schemeEl = seg;
@@ -400,7 +406,7 @@ class ThemePanel extends UIElement {
400
406
  if (this.#schemeEl) {
401
407
  const handler = (e) => {
402
408
  const v = e.detail?.value ?? this.#schemeEl.value;
403
- if (v === 'light' || v === 'dark') this.#apply({ scheme: v }, 'scheme');
409
+ if (v === 'light' || v === 'dark' || v === 'auto') this.#apply({ scheme: v }, 'scheme');
404
410
  };
405
411
  this.#schemeEl.addEventListener('change', handler);
406
412
  this.#cleanups.push(() => this.#schemeEl.removeEventListener('change', handler));
@@ -501,6 +507,7 @@ class ThemePanel extends UIElement {
501
507
  const s = partial.scheme;
502
508
  if (s === 'auto') {
503
509
  target.style.removeProperty('color-scheme');
510
+ this.scheme = 'auto';
504
511
  this.activeScheme = this.#resolvePrefersScheme();
505
512
  if (this.persist) {
506
513
  try { localStorage.removeItem(`${this.storagePrefix}scheme`); } catch {}
@@ -508,6 +515,7 @@ class ThemePanel extends UIElement {
508
515
  this.#attachPcm();
509
516
  } else if (s === 'light' || s === 'dark') {
510
517
  target.style.setProperty('color-scheme', s);
518
+ this.scheme = s;
511
519
  this.activeScheme = s;
512
520
  if (this.persist) {
513
521
  try { localStorage.setItem(`${this.storagePrefix}scheme`, s); } catch {}
@@ -515,7 +523,9 @@ class ThemePanel extends UIElement {
515
523
  // User chose explicitly — PCM listener becomes a no-op
516
524
  this.#detachPcm();
517
525
  }
518
- if (this.#schemeEl) this.#schemeEl.value = this.activeScheme;
526
+ // Segment reflects the RAW intent (System stays selected even though
527
+ // it resolves to a concrete light/dark paint), not the resolved value.
528
+ if (this.#schemeEl) this.#schemeEl.value = this.scheme;
519
529
  }
520
530
 
521
531
  if (partial.scale !== undefined) {
@@ -583,6 +593,7 @@ class ThemePanel extends UIElement {
583
593
  // Apply scheme
584
594
  if (scheme === 'light' || scheme === 'dark') {
585
595
  target.style.setProperty('color-scheme', scheme);
596
+ this.scheme = scheme;
586
597
  this.activeScheme = scheme;
587
598
  if (this.#schemeEl) this.#schemeEl.value = scheme;
588
599
  } else {
@@ -592,9 +603,10 @@ class ThemePanel extends UIElement {
592
603
  target.style.setProperty('color-scheme', attr);
593
604
  this.activeScheme = attr;
594
605
  } else {
606
+ this.scheme = 'auto';
595
607
  this.activeScheme = this.#resolvePrefersScheme();
596
608
  }
597
- if (this.#schemeEl) this.#schemeEl.value = this.activeScheme;
609
+ if (this.#schemeEl) this.#schemeEl.value = this.scheme;
598
610
  }
599
611
 
600
612
  // Apply parametric values
@@ -659,7 +671,9 @@ class ThemePanel extends UIElement {
659
671
  this.#mqlHandler = () => {
660
672
  const resolved = this.#mql.matches ? 'dark' : 'light';
661
673
  this.activeScheme = resolved;
662
- if (this.#schemeEl) this.#schemeEl.value = resolved;
674
+ // Segment stays on System — only the resolved paint changed, the
675
+ // user's raw intent (auto) didn't.
676
+ if (this.#schemeEl) this.#schemeEl.value = 'auto';
663
677
  this.#emit('scheme');
664
678
  };
665
679
  this.#mql.addEventListener('change', this.#mqlHandler);
@@ -686,6 +700,22 @@ class ThemePanel extends UIElement {
686
700
  }
687
701
  }
688
702
 
703
+ // The parametric k-multiplier derived tokens (--a-radius-*, --a-space-*,
704
+ // --a-size-*) are declared once, on `:root, [data-parametric-scope]` —
705
+ // gh#570: a scoped element overriding --a-density/--a-radius-k never
706
+ // re-derives those tokens unless it ALSO matches the selector that
707
+ // declares them (custom properties resolve their calc()/clamp() formula
708
+ // at the DECLARING element's own cascade, then inherit the already-
709
+ // resolved value down — a descendant override doesn't retrigger it).
710
+ // [parametric] on a non-root target opts that element into re-derivation.
711
+ // documentElement is exempt: it always matches `:root` already.
712
+ #syncParametricScope() {
713
+ const target = this.#resolveTarget();
714
+ if (target === document.documentElement) return;
715
+ if (this.parametric) target.setAttribute('data-parametric-scope', '');
716
+ else target.removeAttribute('data-parametric-scope');
717
+ }
718
+
689
719
  // ── Internal — uid for nested element ids ───────────────────────────
690
720
 
691
721
  get #uid() {