@adia-ai/web-components 0.5.19 → 0.5.20

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 CHANGED
@@ -11,6 +11,19 @@ runtime ships in the sibling `@adia-ai/a2ui-runtime` package
11
11
 
12
12
  _No pending changes._
13
13
 
14
+ ## [0.5.20] - 2026-05-18
15
+
16
+ ### Added — §353 (v0.5.20) — `<pane-ui>` + `<tabs-ui>` bar-rule alignment
17
+
18
+ Both primitives' header/tablist bars converted from `border-bottom` to `box-shadow: inset 0 -1px 0`. Header height fixed at `--pane-bar-height` / `--tabs-button-height` (was `min-height` + the border added a pixel). Pane header gains `box-sizing: border-box` + `justify-content: flex-start`. Collapsed pane header drops the box-shadow. Visually identical to consumers; measurable change in computed height (1px shorter than border-bearing version). Brings these two primitives in line with the rest of the catalog using box-shadow for bar rules.
19
+
20
+ ### Docs
21
+ - §351 (FB-53 #2) — USAGE.md `§349 Event handling inside reactive lists` section gains a `CSS child-combinator caveat` paragraph. Calls out that `display:contents` wrapper-spans ARE in the DOM tree, so the CSS child combinator (`>`) walks past them: `.parent > .my-item` will NOT match items inside `repeat()` because the wrapper-span sits between. Recommends descendant combinator (single space) instead. Same caveat extended to `:nth-child` / positional pseudo-classes. Closes the post-Lane-AA1 migration docs gap surfaced by Tokens Studio.
22
+ - §352 (FB-53 #3) — USAGE.md `§345 .map() vs repeat() for reactive lists` section gains a `Sizing heuristic` paragraph. Two cases where `repeat()` pays for itself: (a) ≥20 items re-rendering on every signal change, OR (b) any-size list whose items host custom elements with internal state (chrome slots, focus, scroll). Discourages reflexive `.map()` → `repeat()` migration when neither threshold applies.
23
+
24
+ ### Fixed
25
+ - §-headers (v0.5.20) — USAGE.md headers for `§345` and `§349` renumbered from `§-TBD (v0.5.19)` to `§345 (v0.5.19)` / `§349 (v0.5.19)` — peer-agent's v0.5.19 pre-cut docs sweep renumbered the CHANGELOG but missed the USAGE.md section headers. Sync restored so the section anchors match between CHANGELOG and USAGE.md.
26
+
14
27
  ## [0.5.19] - 2026-05-17
15
28
 
16
29
  ### Added
package/USAGE.md CHANGED
@@ -1086,7 +1086,7 @@ Why AdiaUI doesn't implement `?attr=`: custom elements declare their reflective
1086
1086
  - HTML comments containing quoted attributes (`<!-- attr="value" -->`) — same fix (v0.5.3 §155).
1087
1087
  - Backticks inside HTML comments — see §221i above (JS-spec footgun; not a parser bug).
1088
1088
 
1089
- ### §-TBD (v0.5.19) — `.map()` vs `repeat()` for reactive lists (FB-47)
1089
+ ### §345 (v0.5.19) — `.map()` vs `repeat()` for reactive lists (FB-47)
1090
1090
 
1091
1091
  Use **`repeat(items, keyFn, tplFn)`** for any list whose items are signal-driven and should preserve identity across re-renders. Plain `.map()` returns an `Array` of template results, which the template engine materializes via `container.replaceChildren()` on every parent update — correct, but per-item DOM is re-created from scratch.
1092
1092
 
@@ -1118,7 +1118,9 @@ html`
1118
1118
 
1119
1119
  **Key selection:** pick a stable consumer-supplied identifier (database id, slot.key, etc.), NOT array index. Array indices are unstable under insert/remove and defeat the keyed-reuse contract.
1120
1120
 
1121
- ### §-TBD (v0.5.19) Event handling inside reactive lists (FB-49)
1121
+ **Sizing heuristic (FB-53 #3):** `.map()` is fine for static lists of ≤10 items that don't re-render or only re-render at navigation boundaries. `repeat()` adds per-render bookkeeping (Map lookups, key comparison, DOM reuse) that pays for itself in two cases: (a) lists of ≥20 items that re-render on every signal change (e.g. a palette grid with 66 swatches updating on every slider drag), or (b) any-size list whose items host custom elements with internal state (chrome slots, focus position, scroll offset). Don't migrate every `.map()` reflexively — migrate when one of those two thresholds applies.
1122
+
1123
+ ### §349 (v0.5.19) — Event handling inside reactive lists (FB-49)
1122
1124
 
1123
1125
  Custom-element children rendered inside `repeat()` (or as an `${array}` interpolation) are each wrapped in a `<span style="display:contents">` by the template engine. These wrapper spans generate no boxes (`display:contents`) and cannot be click targets, but they ARE in the DOM tree.
1124
1126
 
@@ -1154,6 +1156,32 @@ host.addEventListener('click', (e) => {
1154
1156
 
1155
1157
  **Don't reach for `composedPath()` reflexively** — it rebuilds the full path on every call and is slower than `closest()`. Default to `closest()` for direct bubble-phase handlers; use `composedPath()` only when one of the three cases above applies.
1156
1158
 
1159
+ **CSS child-combinator caveat (FB-53 #2):** `display:contents` wrapper-spans ARE in the DOM tree even though they generate no boxes. The CSS child combinator (`>`) walks the DOM tree (not the box tree), so consumer rules of the shape `.parent > .my-item` **will not match** items inside a `repeat()` because the wrapper-span sits between `.parent` and the items:
1160
+
1161
+ ```html
1162
+ <!-- Actual DOM produced by repeat(): -->
1163
+ <div class="parent">
1164
+ <span style="display:contents"> <!-- ← repeat() per-item wrapper -->
1165
+ <my-item class="my-item">…</my-item>
1166
+ </span>
1167
+ </div>
1168
+ ```
1169
+
1170
+ Use the descendant combinator (a single space) instead, which traverses any depth:
1171
+
1172
+ ```css
1173
+ /* ❌ Won't match — wrapper-span sits between .parent and .my-item */
1174
+ .parent > .my-item { … }
1175
+
1176
+ /* ✅ Descendant combinator pierces through the wrapper-spans */
1177
+ .parent .my-item { … }
1178
+
1179
+ /* ✅ Or use :scope/has() if you need precision: */
1180
+ .parent > :is(.my-item, span > .my-item) { … }
1181
+ ```
1182
+
1183
+ Same caveat applies to `:nth-child()` / `:nth-of-type()` / `:first-child` / `:last-child` against the parent — those count actual children (the wrapper-spans), not the items inside. If you need nth-item styling, key it via a data attribute on the item itself rather than relying on positional pseudo-classes against the wrapper layer.
1184
+
1157
1185
  ### §221j — Typography token cheatsheet
1158
1186
 
1159
1187
  Quick-reference for component-CSS authoring. Cross-reference [`styles/typography.css`](./styles/typography.css):
@@ -82,17 +82,19 @@
82
82
 
83
83
  /* ── Pane header ── */
84
84
  > header {
85
+ box-sizing: border-box;
85
86
  display: flex;
86
87
  align-items: center;
88
+ justify-content: flex-start;
87
89
  gap: var(--pane-gap-sm);
88
- min-height: var(--pane-bar-height);
89
- padding: var(--pane-header-py) var(--pane-header-px);
90
+ height: var(--pane-bar-height);
91
+ padding: 0 var(--pane-header-px);
90
92
  font-size: var(--pane-header-size);
91
93
  font-weight: var(--pane-header-weight);
92
94
  color: var(--pane-header-fg);
93
95
  cursor: pointer;
94
96
  user-select: none;
95
- border-bottom: 1px solid var(--pane-border);
97
+ box-shadow: inset 0 -1px 0 var(--pane-border);
96
98
  transition: background var(--pane-duration) var(--pane-easing);
97
99
  }
98
100
 
@@ -178,7 +180,7 @@
178
180
  }
179
181
 
180
182
  :scope[collapsed] > header {
181
- border-bottom: none;
183
+ box-shadow: none;
182
184
  }
183
185
 
184
186
  /* ── Resize handle ──
@@ -61,15 +61,16 @@
61
61
  box-sizing: border-box;
62
62
  display: flex;
63
63
  gap: var(--tabs-gap);
64
- border-bottom: 1px solid var(--tabs-border);
64
+ height: var(--tabs-button-height);
65
+ box-shadow: inset 0 -1px 0 var(--tabs-border);
65
66
  position: relative;
66
67
  }
67
68
 
68
69
  :scope[orientation="vertical"] > [slot="strip"] {
69
70
  flex-direction: column;
70
71
  align-items: stretch;
71
- border-bottom: none;
72
- border-inline-start: 1px solid var(--tabs-border);
72
+ height: auto;
73
+ box-shadow: inset 1px 0 0 var(--tabs-border);
73
74
  flex-shrink: 0;
74
75
  min-width: var(--tabs-vertical-strip-min-width);
75
76
  }
@@ -77,7 +78,7 @@
77
78
  /* ── Sliding indicator ── */
78
79
  [slot="indicator"] {
79
80
  position: absolute;
80
- bottom: -1px;
81
+ bottom: 0;
81
82
  left: 0;
82
83
  height: var(--tabs-indicator-height);
83
84
  background: var(--tabs-indicator-color);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-components",
3
- "version": "0.5.19",
3
+ "version": "0.5.20",
4
4
  "description": "AdiaUI web components — vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-runtime.",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",