@adia-ai/web-components 0.0.27 → 0.0.28

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.
@@ -0,0 +1,121 @@
1
+ /**
2
+ * <swatch-ui> — color / style sample primitive.
3
+ *
4
+ * A small inline tile representing one visual sample — a chart series's
5
+ * legend marker, a design-token step in a color or spacing scale, a
6
+ * theme-preview pill. Replaces docs-only `<span data-swatch>` usage and
7
+ * the per-shape CSS that used to live inside chart-legend-ui.
8
+ *
9
+ * Usage:
10
+ * <swatch-ui shape="dot" color="var(--a-data-0)" label="Revenue"></swatch-ui>
11
+ * <swatch-ui shape="block" size="lg" color="var(--a-neutral-50)" label="50"></swatch-ui>
12
+ * <swatch-ui shape="line" color="#0ea5e9">Forecast</swatch-ui>
13
+ *
14
+ * Attributes:
15
+ * shape — block | dot | square | line | dashed (default square)
16
+ * size — sm | md | lg (default md). lg is the 40px-tall token-scale block.
17
+ * color — any CSS color (or var() ref). Sets --swatch-color internally.
18
+ * label — optional text label rendered beside / below the swatch
19
+ *
20
+ * Slots:
21
+ * default — rich label content; takes precedence over [label] attr
22
+ *
23
+ * Stamping is light-DOM with two children:
24
+ * <span data-tile></span> — the colored shape
25
+ * <span data-label></span> — the label text (omitted when no label/slot)
26
+ */
27
+
28
+ import { AdiaElement } from '../../core/element.js';
29
+
30
+ const SHAPES = new Set(['block', 'dot', 'square', 'line', 'dashed']);
31
+ const SIZES = new Set(['sm', 'md', 'lg']);
32
+
33
+ class AdiaSwatch extends AdiaElement {
34
+ static properties = {
35
+ shape: { type: String, default: 'square', reflect: true },
36
+ size: { type: String, default: 'md', reflect: true },
37
+ color: { type: String, default: '', reflect: true },
38
+ label: { type: String, default: '', reflect: true },
39
+ };
40
+
41
+ static template = () => null;
42
+
43
+ #tileEl = null;
44
+ #labelEl = null;
45
+ #stamped = false;
46
+
47
+ connected() {
48
+ this.#stamp();
49
+ }
50
+
51
+ render() {
52
+ this.#stamp();
53
+ this.#sync();
54
+ }
55
+
56
+ #stamp() {
57
+ if (this.#stamped) return;
58
+ // Capture pre-existing default-slot content so consumer-authored
59
+ // children (e.g. <swatch-ui>Forecast</swatch-ui>) survive stamping.
60
+ const slotted = Array.from(this.childNodes).filter(n =>
61
+ !(n.nodeType === 1 && (n.dataset?.tile !== undefined || n.dataset?.label !== undefined))
62
+ );
63
+ this.innerHTML = '';
64
+
65
+ this.#tileEl = document.createElement('span');
66
+ this.#tileEl.setAttribute('data-tile', '');
67
+ this.#tileEl.setAttribute('aria-hidden', 'true');
68
+ this.appendChild(this.#tileEl);
69
+
70
+ this.#labelEl = document.createElement('span');
71
+ this.#labelEl.setAttribute('data-label', '');
72
+ if (slotted.length) {
73
+ for (const n of slotted) this.#labelEl.appendChild(n);
74
+ }
75
+ this.appendChild(this.#labelEl);
76
+
77
+ this.#stamped = true;
78
+ }
79
+
80
+ #sync() {
81
+ if (!this.#tileEl || !this.#labelEl) return;
82
+
83
+ // Normalize enum values; fall back silently when a consumer sets a typo.
84
+ const shape = SHAPES.has(this.shape) ? this.shape : 'square';
85
+ const size = SIZES.has(this.size) ? this.size : 'md';
86
+ if (shape !== this.shape) this.setAttribute('shape', shape);
87
+ if (size !== this.size) this.setAttribute('size', size);
88
+
89
+ // Color: only write the inline custom property when [color] is set
90
+ // explicitly; otherwise leave whatever the consumer wrote via
91
+ // style="--swatch-color: …" alone.
92
+ if (this.color) {
93
+ this.style.setProperty('--swatch-color', this.color);
94
+ }
95
+
96
+ // Label: prefer slotted content (already in #labelEl from #stamp);
97
+ // when label-attr is set and the slot is empty, write the attribute.
98
+ if (!this.#labelEl.firstChild && this.label) {
99
+ this.#labelEl.textContent = this.label;
100
+ } else if (this.#labelEl.firstChild?.nodeType === 3 && this.label) {
101
+ // Pure-text node from a previous label-attr render — keep it
102
+ // synced to the current attr value.
103
+ this.#labelEl.textContent = this.label;
104
+ }
105
+
106
+ // Hide the label box when there's no content. Empty-but-stamped span
107
+ // would otherwise eat the layout gap.
108
+ const hasLabel = this.#labelEl.textContent.trim().length > 0
109
+ || (this.#labelEl.firstElementChild != null);
110
+ this.#labelEl.toggleAttribute('hidden', !hasLabel);
111
+ }
112
+
113
+ disconnected() {
114
+ this.#tileEl = null;
115
+ this.#labelEl = null;
116
+ this.#stamped = false;
117
+ }
118
+ }
119
+
120
+ customElements.define('swatch-ui', AdiaSwatch);
121
+ export { AdiaSwatch };
@@ -0,0 +1,101 @@
1
+ $schema: ../../../../scripts/schemas/component.yaml.schema.json
2
+ name: AdiaSwatch
3
+ tag: swatch-ui
4
+ component: Swatch
5
+ category: display
6
+ version: 1
7
+ description: |
8
+ Color/style swatch primitive — a small inline tile representing a single
9
+ visual sample. Renders as block, dot, square, line, or dashed depending on
10
+ shape; pairs with an optional label slot or attribute. Composed by chart-
11
+ legend-ui's per-row swatch and consumed directly by the token-colors /
12
+ spacing demo pages.
13
+ props:
14
+ shape:
15
+ description: Visual shape — block (filled tile), dot (small circle), square (small filled square), line (solid hairline), dashed (dashed hairline).
16
+ type: string
17
+ default: square
18
+ reflect: true
19
+ enum:
20
+ - block
21
+ - dot
22
+ - square
23
+ - line
24
+ - dashed
25
+ size:
26
+ description: Size preset — sm / md / lg. Drives the swatch's intrinsic dimensions; lg is reserved for the token-scale demo (40 px tall).
27
+ type: string
28
+ default: md
29
+ reflect: true
30
+ enum:
31
+ - sm
32
+ - md
33
+ - lg
34
+ color:
35
+ description: Swatch color. Accepts any CSS color value or var() reference. Sets the internal --swatch-color custom property; consumers can also set --swatch-color via inline style.
36
+ type: string
37
+ default: ""
38
+ reflect: true
39
+ label:
40
+ description: Optional label rendered next to (or below, for shape="block") the swatch. Use the default slot for richer content.
41
+ type: string
42
+ default: ""
43
+ reflect: true
44
+ events: {}
45
+ slots:
46
+ default:
47
+ description: Optional rich label content. When present, replaces the [label] attribute's text.
48
+ states:
49
+ - name: idle
50
+ description: Default, ready for display.
51
+ traits: []
52
+ tokens:
53
+ --swatch-color:
54
+ description: Resolved color of the swatch fill / line. Wins over the [color] attr if set inline.
55
+ a2ui:
56
+ rules: []
57
+ anti_patterns: []
58
+ examples:
59
+ - name: basic-swatch
60
+ description: A single dot swatch with text label, e.g. as a chart-legend row.
61
+ a2ui: >-
62
+ [
63
+ {
64
+ "id": "root",
65
+ "component": "Swatch",
66
+ "shape": "dot",
67
+ "color": "var(--a-data-0)",
68
+ "label": "Revenue"
69
+ }
70
+ ]
71
+ - name: token-block
72
+ description: Block swatch for a token-scale step.
73
+ a2ui: >-
74
+ [
75
+ {
76
+ "id": "root",
77
+ "component": "Swatch",
78
+ "shape": "block",
79
+ "size": "lg",
80
+ "color": "var(--a-neutral-50)",
81
+ "label": "50"
82
+ }
83
+ ]
84
+ keywords:
85
+ - swatch
86
+ - color
87
+ - chip
88
+ - sample
89
+ - palette
90
+ - legend
91
+ - step
92
+ - token
93
+ synonyms:
94
+ color-chip:
95
+ - swatch
96
+ - chip
97
+ color-sample:
98
+ - swatch
99
+ related:
100
+ - chart-legend-ui
101
+ - tag-ui
@@ -347,7 +347,11 @@ agent-reasoning-ui timeline-ui:not([orientation="horizontal"]),
347
347
  :scope > [data-timeline-toggle] {
348
348
  position: absolute;
349
349
  inset-inline-end: 0;
350
- top: calc((1.4em - 1em) / 2);
350
+ /* Place the chevron's icon-center on row 1's optical center.
351
+ The button has --a-space-0-5 vertical padding, so the icon
352
+ sits that much lower inside the box; we subtract that so the
353
+ icon (not the box) lines up with the time-slot text center. */
354
+ top: calc((1.4em - 1em) / 2 - var(--a-space-0-5));
351
355
  background: none;
352
356
  border: none;
353
357
  padding: var(--a-space-0-5) var(--timeline-item-toggle-px);
@@ -140,7 +140,7 @@
140
140
  width: var(--tooltip-indicator-size);
141
141
  height: var(--tooltip-indicator-size);
142
142
  border-radius: 50%;
143
- background: var(--tooltip-indicator-color, var(--chart-0));
143
+ background: var(--tooltip-indicator-color, var(--a-data-0));
144
144
  flex-shrink: 0;
145
145
  }
146
146
 
@@ -148,14 +148,14 @@
148
148
  display: inline-block;
149
149
  width: calc(var(--tooltip-indicator-size) * 1.6);
150
150
  height: 2px;
151
- background: var(--tooltip-indicator-color, var(--chart-0));
151
+ background: var(--tooltip-indicator-color, var(--a-data-0));
152
152
  flex-shrink: 0;
153
153
  }
154
154
 
155
155
  .tooltip-popup[data-follows="pointer"][data-indicator="dashed"] [data-indicator] {
156
156
  display: inline-block;
157
157
  width: calc(var(--tooltip-indicator-size) * 1.6);
158
- border-top: 2px dashed var(--tooltip-indicator-color, var(--chart-0));
158
+ border-top: 2px dashed var(--tooltip-indicator-color, var(--a-data-0));
159
159
  flex-shrink: 0;
160
160
  }
161
161
 
package/core/provider.js CHANGED
@@ -236,6 +236,7 @@ export class AdiaRouter extends AdiaProvider {
236
236
  }
237
237
 
238
238
  this.innerHTML = html;
239
+ this.scrollTo(0, 0);
239
240
  (this.closest('section') || this.parentElement)?.scrollTo(0, 0);
240
241
 
241
242
  if (route.title) document.title = route.title;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-components",
3
- "version": "0.0.27",
3
+ "version": "0.0.28",
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": {
@@ -50,6 +50,7 @@
50
50
  @import "../components/alert/alert.css";
51
51
  @import "../components/kbd/kbd.css";
52
52
  @import "../components/tag/tag.css";
53
+ @import "../components/swatch/swatch.css";
53
54
  @import "../components/col/col.css";
54
55
  @import "../components/field/field.css";
55
56
  @import "../components/row/row.css";