@adia-ai/web-components 0.6.31 → 0.6.33

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.
Files changed (238) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/components/accordion/accordion-item.a2ui.json +1 -0
  3. package/components/accordion/accordion-item.yaml +1 -0
  4. package/components/accordion/accordion.a2ui.json +1 -0
  5. package/components/accordion/accordion.yaml +1 -0
  6. package/components/action-list/action-item.a2ui.json +1 -0
  7. package/components/action-list/action-item.yaml +1 -0
  8. package/components/action-list/action-list.a2ui.json +1 -0
  9. package/components/action-list/action-list.yaml +1 -0
  10. package/components/agent-artifact/agent-artifact.a2ui.json +1 -0
  11. package/components/agent-artifact/agent-artifact.yaml +1 -0
  12. package/components/agent-feedback-bar/agent-feedback-bar.a2ui.json +1 -0
  13. package/components/agent-feedback-bar/agent-feedback-bar.yaml +1 -0
  14. package/components/agent-questions/agent-questions.a2ui.json +1 -0
  15. package/components/agent-questions/agent-questions.yaml +1 -0
  16. package/components/agent-reasoning/agent-reasoning.a2ui.json +1 -0
  17. package/components/agent-reasoning/agent-reasoning.yaml +1 -0
  18. package/components/agent-suggestions/agent-suggestions.a2ui.json +1 -0
  19. package/components/agent-suggestions/agent-suggestions.yaml +1 -0
  20. package/components/agent-trace/agent-trace.a2ui.json +1 -0
  21. package/components/agent-trace/agent-trace.yaml +1 -0
  22. package/components/alert/alert.a2ui.json +1 -0
  23. package/components/alert/alert.yaml +1 -0
  24. package/components/aside/aside.a2ui.json +1 -0
  25. package/components/aside/aside.yaml +1 -0
  26. package/components/avatar/avatar-group.a2ui.json +1 -0
  27. package/components/avatar/avatar-group.yaml +1 -0
  28. package/components/avatar/avatar.a2ui.json +1 -0
  29. package/components/avatar/avatar.yaml +1 -0
  30. package/components/badge/badge.a2ui.json +3 -1
  31. package/components/badge/badge.css +6 -1
  32. package/components/badge/badge.yaml +2 -0
  33. package/components/block/block.a2ui.json +1 -0
  34. package/components/block/block.yaml +1 -0
  35. package/components/breadcrumb/breadcrumb.a2ui.json +1 -0
  36. package/components/breadcrumb/breadcrumb.yaml +1 -0
  37. package/components/button/button.a2ui.json +1 -0
  38. package/components/button/button.yaml +1 -0
  39. package/components/calendar-picker/calendar-picker.a2ui.json +1 -0
  40. package/components/calendar-picker/calendar-picker.yaml +1 -0
  41. package/components/canvas/canvas.a2ui.json +1 -0
  42. package/components/canvas/canvas.yaml +1 -0
  43. package/components/card/card.a2ui.json +1 -0
  44. package/components/card/card.yaml +1 -0
  45. package/components/chart/chart.a2ui.json +3 -1
  46. package/components/chart/chart.yaml +2 -0
  47. package/components/chart-legend/chart-legend.a2ui.json +1 -0
  48. package/components/chart-legend/chart-legend.yaml +1 -0
  49. package/components/chat-thread/chat-input.a2ui.json +1 -0
  50. package/components/chat-thread/chat-input.yaml +1 -0
  51. package/components/chat-thread/chat-thread.a2ui.json +1 -0
  52. package/components/chat-thread/chat-thread.yaml +1 -0
  53. package/components/check/check.a2ui.json +3 -1
  54. package/components/check/check.yaml +2 -0
  55. package/components/code/code.a2ui.json +1 -0
  56. package/components/code/code.css +1 -1
  57. package/components/code/code.yaml +1 -0
  58. package/components/col/col.a2ui.json +1 -0
  59. package/components/col/col.yaml +1 -0
  60. package/components/color-input/color-input.a2ui.json +1 -0
  61. package/components/color-input/color-input.yaml +1 -0
  62. package/components/color-picker/color-picker.a2ui.json +1 -0
  63. package/components/color-picker/color-picker.yaml +1 -0
  64. package/components/command/command.a2ui.json +1 -0
  65. package/components/command/command.yaml +1 -0
  66. package/components/demo-toggle/demo-toggle.a2ui.json +1 -0
  67. package/components/demo-toggle/demo-toggle.yaml +1 -0
  68. package/components/description-list/description-list.a2ui.json +1 -0
  69. package/components/description-list/description-list.yaml +1 -0
  70. package/components/divider/divider.a2ui.json +1 -0
  71. package/components/divider/divider.yaml +1 -0
  72. package/components/drawer/drawer.a2ui.json +1 -0
  73. package/components/drawer/drawer.yaml +1 -0
  74. package/components/embed/embed.a2ui.json +1 -0
  75. package/components/embed/embed.yaml +1 -0
  76. package/components/empty-state/empty-state.a2ui.json +1 -0
  77. package/components/empty-state/empty-state.yaml +1 -0
  78. package/components/feed/feed-item.a2ui.json +1 -0
  79. package/components/feed/feed-item.yaml +1 -0
  80. package/components/feed/feed.a2ui.json +1 -0
  81. package/components/feed/feed.yaml +1 -0
  82. package/components/field/field.a2ui.json +3 -1
  83. package/components/field/field.css +10 -1
  84. package/components/field/field.test.js +32 -0
  85. package/components/field/field.yaml +2 -0
  86. package/components/fields/fields.a2ui.json +1 -0
  87. package/components/fields/fields.yaml +1 -0
  88. package/components/footer/footer.a2ui.json +1 -0
  89. package/components/footer/footer.yaml +1 -0
  90. package/components/grid/grid.a2ui.json +1 -0
  91. package/components/grid/grid.yaml +1 -0
  92. package/components/header/header.a2ui.json +1 -0
  93. package/components/header/header.yaml +1 -0
  94. package/components/heatmap/heatmap.a2ui.json +1 -0
  95. package/components/heatmap/heatmap.yaml +1 -0
  96. package/components/icon/icon.a2ui.json +3 -1
  97. package/components/icon/icon.yaml +2 -0
  98. package/components/image/image.a2ui.json +1 -0
  99. package/components/image/image.yaml +1 -0
  100. package/components/input/input.a2ui.json +1 -0
  101. package/components/input/input.yaml +1 -0
  102. package/components/inspector/inspector.a2ui.json +1 -0
  103. package/components/inspector/inspector.yaml +1 -0
  104. package/components/kbd/kbd.a2ui.json +1 -0
  105. package/components/kbd/kbd.yaml +1 -0
  106. package/components/link/link.a2ui.json +1 -0
  107. package/components/link/link.yaml +1 -0
  108. package/components/list/list-item.a2ui.json +1 -0
  109. package/components/list/list-item.yaml +1 -0
  110. package/components/list/list.a2ui.json +1 -0
  111. package/components/list/list.yaml +1 -0
  112. package/components/menu/menu-divider.a2ui.json +1 -0
  113. package/components/menu/menu-divider.yaml +1 -0
  114. package/components/menu/menu-item.a2ui.json +1 -0
  115. package/components/menu/menu-item.yaml +1 -0
  116. package/components/menu/menu.a2ui.json +1 -0
  117. package/components/menu/menu.yaml +1 -0
  118. package/components/modal/modal.a2ui.json +1 -0
  119. package/components/modal/modal.yaml +1 -0
  120. package/components/nav/nav.a2ui.json +1 -0
  121. package/components/nav/nav.yaml +1 -0
  122. package/components/nav-group/nav-group.a2ui.json +1 -0
  123. package/components/nav-group/nav-group.yaml +1 -0
  124. package/components/nav-item/nav-item.a2ui.json +3 -1
  125. package/components/nav-item/nav-item.yaml +2 -0
  126. package/components/noodles/noodles.a2ui.json +1 -0
  127. package/components/noodles/noodles.yaml +1 -0
  128. package/components/option-card/option-card.a2ui.json +1 -0
  129. package/components/option-card/option-card.yaml +1 -0
  130. package/components/otp-input/otp-input.a2ui.json +1 -0
  131. package/components/otp-input/otp-input.yaml +1 -0
  132. package/components/page/page.a2ui.json +1 -0
  133. package/components/page/page.yaml +1 -0
  134. package/components/pagination/pagination.a2ui.json +1 -0
  135. package/components/pagination/pagination.yaml +1 -0
  136. package/components/pane/pane.a2ui.json +1 -0
  137. package/components/pane/pane.yaml +1 -0
  138. package/components/pipeline-status/pipeline-status.a2ui.json +1 -0
  139. package/components/pipeline-status/pipeline-status.yaml +1 -0
  140. package/components/popover/popover.a2ui.json +1 -0
  141. package/components/popover/popover.yaml +1 -0
  142. package/components/progress/progress.a2ui.json +1 -0
  143. package/components/progress/progress.yaml +1 -0
  144. package/components/progress-row/progress-row.a2ui.json +1 -0
  145. package/components/progress-row/progress-row.yaml +1 -0
  146. package/components/radio/radio.a2ui.json +1 -0
  147. package/components/radio/radio.yaml +1 -0
  148. package/components/range/range.a2ui.json +1 -0
  149. package/components/range/range.yaml +1 -0
  150. package/components/rating/rating.a2ui.json +3 -1
  151. package/components/rating/rating.yaml +2 -0
  152. package/components/richtext/richtext.a2ui.json +1 -0
  153. package/components/richtext/richtext.yaml +1 -0
  154. package/components/row/row.a2ui.json +1 -0
  155. package/components/row/row.yaml +1 -0
  156. package/components/search/search.a2ui.json +1 -0
  157. package/components/search/search.yaml +1 -0
  158. package/components/section/section.a2ui.json +1 -0
  159. package/components/section/section.yaml +1 -0
  160. package/components/segment/segment.a2ui.json +1 -0
  161. package/components/segment/segment.css +8 -2
  162. package/components/segment/segment.yaml +1 -0
  163. package/components/segmented/segmented.a2ui.json +1 -0
  164. package/components/segmented/segmented.yaml +1 -0
  165. package/components/select/select.a2ui.json +1 -0
  166. package/components/select/select.yaml +1 -0
  167. package/components/skeleton/skeleton.a2ui.json +1 -0
  168. package/components/skeleton/skeleton.yaml +1 -0
  169. package/components/slider/slider.a2ui.json +1 -0
  170. package/components/slider/slider.yaml +1 -0
  171. package/components/stack/stack.a2ui.json +1 -0
  172. package/components/stack/stack.yaml +1 -0
  173. package/components/stat/stat.a2ui.json +4 -1
  174. package/components/stat/stat.yaml +3 -0
  175. package/components/step-progress/step-progress.a2ui.json +1 -0
  176. package/components/step-progress/step-progress.yaml +1 -0
  177. package/components/stepper/stepper-item.a2ui.json +1 -0
  178. package/components/stepper/stepper-item.yaml +1 -0
  179. package/components/stepper/stepper.a2ui.json +1 -0
  180. package/components/stepper/stepper.yaml +1 -0
  181. package/components/stream/stream.a2ui.json +1 -0
  182. package/components/stream/stream.yaml +1 -0
  183. package/components/swatch/swatch.a2ui.json +1 -0
  184. package/components/swatch/swatch.yaml +1 -0
  185. package/components/swiper/swiper.a2ui.json +1 -0
  186. package/components/swiper/swiper.yaml +1 -0
  187. package/components/switch/switch.a2ui.json +1 -0
  188. package/components/switch/switch.yaml +1 -0
  189. package/components/table/class.js +9 -0
  190. package/components/table/table.a2ui.json +2 -1
  191. package/components/table/table.d.ts +1 -1
  192. package/components/table/table.test.js +53 -0
  193. package/components/table/table.yaml +14 -1
  194. package/components/table-toolbar/table-toolbar.a2ui.json +1 -0
  195. package/components/table-toolbar/table-toolbar.yaml +1 -0
  196. package/components/tabs/tab.a2ui.json +1 -0
  197. package/components/tabs/tab.yaml +1 -0
  198. package/components/tabs/tabs.a2ui.json +3 -1
  199. package/components/tabs/tabs.css +1 -1
  200. package/components/tabs/tabs.yaml +2 -0
  201. package/components/tag/tag.a2ui.json +1 -0
  202. package/components/tag/tag.css +6 -1
  203. package/components/tag/tag.test.js +46 -0
  204. package/components/tag/tag.yaml +1 -0
  205. package/components/text/text.a2ui.json +1 -0
  206. package/components/text/text.yaml +1 -0
  207. package/components/textarea/textarea.a2ui.json +1 -0
  208. package/components/textarea/textarea.yaml +1 -0
  209. package/components/timeline/timeline-item.a2ui.json +1 -0
  210. package/components/timeline/timeline-item.yaml +1 -0
  211. package/components/timeline/timeline.a2ui.json +1 -0
  212. package/components/timeline/timeline.yaml +1 -0
  213. package/components/toast/toast.a2ui.json +1 -0
  214. package/components/toast/toast.yaml +1 -0
  215. package/components/toggle-group/toggle-group.a2ui.json +1 -0
  216. package/components/toggle-group/toggle-group.yaml +1 -0
  217. package/components/toggle-group/toggle-option.a2ui.json +1 -0
  218. package/components/toggle-group/toggle-option.yaml +1 -0
  219. package/components/toggle-scheme/toggle-scheme.a2ui.json +1 -0
  220. package/components/toggle-scheme/toggle-scheme.yaml +1 -0
  221. package/components/toolbar/toolbar-group.a2ui.json +1 -0
  222. package/components/toolbar/toolbar-group.yaml +1 -0
  223. package/components/toolbar/toolbar.a2ui.json +1 -0
  224. package/components/toolbar/toolbar.yaml +1 -0
  225. package/components/tooltip/tooltip.a2ui.json +1 -0
  226. package/components/tooltip/tooltip.yaml +1 -0
  227. package/components/tree/tree-item.a2ui.json +1 -0
  228. package/components/tree/tree-item.yaml +1 -0
  229. package/components/tree/tree.a2ui.json +1 -0
  230. package/components/tree/tree.yaml +1 -0
  231. package/components/upload/upload.a2ui.json +1 -0
  232. package/components/upload/upload.yaml +1 -0
  233. package/core/icons-phosphor.js +9 -3
  234. package/dist/icons-manifest.js +9091 -0
  235. package/dist/web-components.min.css +1 -1
  236. package/dist/web-components.min.js +16 -16
  237. package/package.json +1 -1
  238. package/styles/colors/semantics.css +3 -3
@@ -157,6 +157,7 @@
157
157
  "name": "idle"
158
158
  }
159
159
  ],
160
+ "status": "stable",
160
161
  "synonyms": {
161
162
  "carousel": [
162
163
  "swiper",
@@ -1,6 +1,7 @@
1
1
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
2
2
  name: UISwiper
3
3
  tag: swiper-ui
4
+ status: stable
4
5
  component: Swiper
5
6
  category: layout
6
7
  version: 1
@@ -125,6 +125,7 @@
125
125
  "name": "disabled"
126
126
  }
127
127
  ],
128
+ "status": "stable",
128
129
  "synonyms": {
129
130
  "tags": [
130
131
  "Toggle",
@@ -1,6 +1,7 @@
1
1
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
2
2
  name: UISwitch
3
3
  tag: switch-ui
4
+ status: stable
4
5
  component: Switch
5
6
  category: layout
6
7
  version: 1
@@ -541,6 +541,15 @@ export class UITable extends UIElement {
541
541
  // ── Render ─────────────────────────────────────────────────────────────────
542
542
 
543
543
  render() {
544
+ // Raw mode: visual-only passthrough. The consumer authored the entire
545
+ // body shape (native <table>, custom row rendering, etc.) and only wants
546
+ // table-ui's CSS tokens (chrome reset via :scope[raw]). The data
547
+ // lifecycle (header injection, body reconciliation, overlays, aggregation,
548
+ // pagination) MUST NOT run — otherwise `.data === []` injects a
549
+ // [data-empty] overlay above the consumer's content (FB-53 §2). Raw is
550
+ // the explicit "consumer owns layout" mode.
551
+ if (this.raw) return;
552
+
544
553
  const visCols = this.#visibleColumns;
545
554
 
546
555
  // Set grid template
@@ -52,7 +52,7 @@
52
52
  "default": 0
53
53
  },
54
54
  "raw": {
55
- "description": "Raw mode",
55
+ "description": "Visual-only passthrough — applies `<table-ui>`'s chrome reset (background / border / border-radius all transparent) AND short-circuits the data lifecycle entirely. The consumer owns the body shape: no header injection, no row reconciliation from `.data`, no empty-state / loading overlays, no aggregation or pagination footers. Use raw when embedding `<table-ui>` inside surfaces that supply their own chrome (e.g. `<card-ui><section bleed>`), or when wrapping a consumer-authored native `<table>` for design-token styling without the framework's data semantics. Pre-v0.6.33 (FB-53 §2) `raw` was visual-only and the data lifecycle still ran — wrapping a `.data`-unset native table produced a phantom \"No data\" overlay. v0.6.33+ matches the documented contract.",
56
56
  "type": "boolean",
57
57
  "default": false
58
58
  },
@@ -281,6 +281,7 @@
281
281
  "name": "idle"
282
282
  }
283
283
  ],
284
+ "status": "stable",
284
285
  "synonyms": {
285
286
  "admin": [
286
287
  "dashboard",
@@ -98,7 +98,7 @@ export class UITable extends UIElement {
98
98
  loading: boolean;
99
99
  /** Rows per page. 0 = show all rows without pagination. When > 0, renders a pagination bar below the table. */
100
100
  paginate: number;
101
- /** Raw mode */
101
+ /** Visual-only passthrough — applies `<table-ui>`'s chrome reset (background / border / border-radius all transparent) AND short-circuits the data lifecycle entirely. The consumer owns the body shape: no header injection, no row reconciliation from `.data`, no empty-state / loading overlays, no aggregation or pagination footers. Use raw when embedding `<table-ui>` inside surfaces that supply their own chrome (e.g. `<card-ui><section bleed>`), or when wrapping a consumer-authored native `<table>` for design-token styling without the framework's data semantics. Pre-v0.6.33 (FB-53 §2) `raw` was visual-only and the data lifecycle still ran — wrapping a `.data`-unset native table produced a phantom "No data" overlay. v0.6.33+ matches the documented contract. */
102
102
  raw: boolean;
103
103
  /** Global search/filter string. Filters visible rows across all columns using case-insensitive substring matching. Resets to page 1 on change. */
104
104
  search: string;
@@ -283,3 +283,56 @@ describe('table-ui — FB-47 keyboard: Enter activates focused body cell', () =>
283
283
  expect(cellClickFired).toBe(false);
284
284
  });
285
285
  });
286
+
287
+ /**
288
+ * Raw mode: visual-only passthrough — consumer owns the body shape.
289
+ *
290
+ * Pre-v0.6.33 (FB-53 §2), `<table-ui raw>` only applied the CSS chrome
291
+ * reset (background/border/radius transparent) but the data lifecycle
292
+ * still ran. With `.data === []` (the natural state when wrapping a
293
+ * consumer-authored native <table>), `#renderOverlays` injected a
294
+ * [data-empty] "No data" placeholder above the consumer's content.
295
+ *
296
+ * v0.6.33 short-circuits `render()` at the top when `this.raw` is set:
297
+ * no header injection, no body reconciliation, no overlays, no
298
+ * aggregation, no pagination.
299
+ */
300
+ describe('table-ui — raw mode passthrough (FB-53 §2)', () => {
301
+ beforeEach(() => { document.body.innerHTML = ''; });
302
+
303
+ it('raw mode does NOT inject [data-empty] overlay when .data is empty', async () => {
304
+ const el = mount('<table-ui raw><table><tr><td>foo</td></tr></table></table-ui>');
305
+ // No .data set → empty by default. Without the raw early-return,
306
+ // #renderOverlays would create the [data-empty] placeholder.
307
+ await raf();
308
+ expect(el.querySelector(':scope > [data-empty]')).toBeNull();
309
+ // Consumer's native <table> survives untouched.
310
+ expect(el.querySelector(':scope > table')).not.toBeNull();
311
+ });
312
+
313
+ it('raw mode does NOT inject [data-header] or [data-body] rowgroups', async () => {
314
+ const el = mount('<table-ui raw><table><tr><td>x</td></tr></table></table-ui>');
315
+ await raf();
316
+ expect(el.querySelector(':scope > [data-header]')).toBeNull();
317
+ expect(el.querySelector(':scope > [data-body]')).toBeNull();
318
+ });
319
+
320
+ it('raw mode preserves consumer markup even when .columns + .data are set', async () => {
321
+ const el = mount('<table-ui raw><table id="consumer"><tr><td>consumer-owned</td></tr></table></table-ui>');
322
+ el.columns = COLS;
323
+ el.data = ROWS;
324
+ await raf();
325
+ // The consumer's native <table> is still the only table-shaped child.
326
+ expect(el.querySelector('#consumer')).not.toBeNull();
327
+ expect(el.querySelectorAll(':scope > [role="rowgroup"]').length).toBe(0);
328
+ });
329
+
330
+ it('non-raw mode (default) still injects header + body rowgroups', async () => {
331
+ const el = mount('<table-ui></table-ui>');
332
+ el.columns = COLS;
333
+ el.data = ROWS;
334
+ await raf();
335
+ expect(el.querySelector(':scope > [data-header]')).not.toBeNull();
336
+ expect(el.querySelector(':scope > [data-body]')).not.toBeNull();
337
+ });
338
+ });
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UITable
5
5
  tag: table-ui
6
+ status: stable
6
7
  component: Table
7
8
  category: agent
8
9
  version: 1
@@ -54,7 +55,19 @@ props:
54
55
  type: number
55
56
  default: 0
56
57
  raw:
57
- description: Raw mode
58
+ description: >-
59
+ Visual-only passthrough — applies `<table-ui>`'s chrome reset
60
+ (background / border / border-radius all transparent) AND
61
+ short-circuits the data lifecycle entirely. The consumer
62
+ owns the body shape: no header injection, no row reconciliation
63
+ from `.data`, no empty-state / loading overlays, no aggregation
64
+ or pagination footers. Use raw when embedding `<table-ui>` inside
65
+ surfaces that supply their own chrome (e.g. `<card-ui><section
66
+ bleed>`), or when wrapping a consumer-authored native `<table>`
67
+ for design-token styling without the framework's data semantics.
68
+ Pre-v0.6.33 (FB-53 §2) `raw` was visual-only and the data lifecycle
69
+ still ran — wrapping a `.data`-unset native table produced a
70
+ phantom "No data" overlay. v0.6.33+ matches the documented contract.
58
71
  type: boolean
59
72
  default: false
60
73
  reflect: true
@@ -139,6 +139,7 @@
139
139
  "name": "idle"
140
140
  }
141
141
  ],
142
+ "status": "stable",
142
143
  "synonyms": {
143
144
  "columns": [
144
145
  "table-toolbar",
@@ -1,6 +1,7 @@
1
1
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
2
2
  name: UITableToolbar
3
3
  tag: table-toolbar-ui
4
+ status: stable
4
5
  component: TableToolbar
5
6
  category: agent
6
7
  version: 1
@@ -58,6 +58,7 @@
58
58
  ],
59
59
  "slots": {},
60
60
  "states": [],
61
+ "status": "stable",
61
62
  "synonyms": {
62
63
  "tab": [
63
64
  "view-tab",
@@ -11,6 +11,7 @@
11
11
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
12
12
  name: UITab
13
13
  tag: tab-ui
14
+ status: stable
14
15
  component: Tab
15
16
  category: navigation
16
17
  version: 1
@@ -40,7 +40,8 @@
40
40
  }
41
41
  },
42
42
  "required": [
43
- "component"
43
+ "component",
44
+ "value"
44
45
  ],
45
46
  "unevaluatedProperties": false,
46
47
  "x-adiaui": {
@@ -92,6 +93,7 @@
92
93
  "name": "idle"
93
94
  }
94
95
  ],
96
+ "status": "stable",
95
97
  "synonyms": {
96
98
  "layout": [
97
99
  "split",
@@ -4,7 +4,7 @@
4
4
  --tabs-border: transparent;
5
5
  --tabs-bg: transparent;
6
6
  --tabs-radius: var(--a-radius-md);
7
- --tabs-button-height: 2.25rem;
7
+ --tabs-button-height: var(--a-size);
8
8
  --tabs-button-px: var(--a-space-2);
9
9
  --tabs-font-size: var(--a-ui-md);
10
10
  --tabs-gap: var(--a-space-1);
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UITabs
5
5
  tag: tabs-ui
6
+ status: stable
6
7
  component: Tabs
7
8
  category: container
8
9
  version: 1
@@ -28,6 +29,7 @@ props:
28
29
  value:
29
30
  description: Value of the currently active tab. Set programmatically or auto-assigned to the first
30
31
  non-disabled tab on connect.
32
+ required: true
31
33
  type: string
32
34
  default: ""
33
35
  events:
@@ -114,6 +114,7 @@
114
114
  "name": "disabled"
115
115
  }
116
116
  ],
117
+ "status": "stable",
117
118
  "synonyms": {
118
119
  "autocomplete": [
119
120
  "search",
@@ -55,7 +55,12 @@ tag-ui[removable]:not([disabled]):hover {
55
55
  transition: background var(--tag-duration) var(--tag-easing), color var(--tag-duration) var(--tag-easing);
56
56
  }
57
57
 
58
- :scope::after {
58
+ /* `[text]` attribute selector gates the ::after so consumers using
59
+ slotted content (`<tag-ui>Beta</tag-ui>`) don't get an empty
60
+ pseudo-element flex item — which would otherwise inherit the
61
+ host's `gap` and add a phantom `--tag-gap`-wide trailing space
62
+ after the slotted content. Mirrors `button.css` line ~103. */
63
+ :scope[text]::after {
59
64
  content: attr(text);
60
65
  }
61
66
 
@@ -0,0 +1,46 @@
1
+ /**
2
+ * tag-ui regression tests.
3
+ *
4
+ * Source-grep contract for the `content: attr(text)` gating pattern.
5
+ * Pre-fix (ungated `:scope::after { content: attr(text) }`), an empty
6
+ * `attr(text)` still generated a zero-width pseudo-element flex item,
7
+ * and the host's `inline-flex` + `gap` added a phantom `--tag-gap`
8
+ * trailing space after slotted content like `<tag-ui>Beta</tag-ui>`.
9
+ * The fix gates the pseudo-element on `[text]` attribute presence, so
10
+ * slot-content consumers don't pay the gap cost.
11
+ *
12
+ * jsdom doesn't evaluate `@scope` rules via `getComputedStyle()`, so
13
+ * we validate the CSS source shape directly (same recipe as
14
+ * description-list.test.js and text.test.js).
15
+ */
16
+
17
+ import { describe, it, expect } from 'vitest';
18
+ import { readFileSync } from 'node:fs';
19
+ import { fileURLToPath } from 'node:url';
20
+ import { dirname, resolve } from 'node:path';
21
+
22
+ const HERE = dirname(fileURLToPath(import.meta.url));
23
+ const TAG_CSS = readFileSync(resolve(HERE, 'tag.css'), 'utf8');
24
+
25
+ describe('tag-ui — content: attr(text) gating', () => {
26
+ it('gates the ::after pseudo-element on [text] attribute presence', () => {
27
+ // The fixed rule: `:scope[text]::after { content: attr(text); }`
28
+ expect(TAG_CSS).toMatch(/:scope\[text\]::after\s*\{[^}]*content:\s*attr\(text\)/);
29
+ });
30
+
31
+ it('does NOT carry an ungated :scope::after with content: attr(text)', () => {
32
+ // The pre-fix shape would add phantom flex-gap space after slotted
33
+ // content. Match the bare `:scope::after` form (no attribute
34
+ // selector chained) followed by the attr(text) declaration.
35
+ expect(TAG_CSS).not.toMatch(/:scope::after\s*\{[^}]*content:\s*attr\(text\)/);
36
+ });
37
+
38
+ it('host :scope still declares the flex + gap layout (gap is real, just no longer applied to an empty pseudo)', () => {
39
+ // Sanity check that the fix didn't accidentally remove the host
40
+ // flex/gap declarations — those are still load-bearing for the
41
+ // [icon] + [dismiss] slot rendering and for proper :scope[text]
42
+ // gap rendering when text IS set.
43
+ expect(TAG_CSS).toMatch(/:scope\s*\{[^}]*display:\s*inline-flex/);
44
+ expect(TAG_CSS).toMatch(/:scope\s*\{[^}]*gap:\s*var\(--tag-gap\)/);
45
+ });
46
+ });
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UITag
5
5
  tag: tag-ui
6
+ status: stable
6
7
  component: Tag
7
8
  category: display
8
9
  version: 1
@@ -154,6 +154,7 @@
154
154
  "name": "idle"
155
155
  }
156
156
  ],
157
+ "status": "stable",
157
158
  "synonyms": {
158
159
  "text": [
159
160
  "typography",
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UIText
5
5
  tag: text-ui
6
+ status: stable
6
7
  component: Text
7
8
  category: display
8
9
  version: 1
@@ -123,6 +123,7 @@
123
123
  "name": "idle"
124
124
  }
125
125
  ],
126
+ "status": "stable",
126
127
  "synonyms": {
127
128
  "textarea": [
128
129
  "multiline-input",
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UITextarea
5
5
  tag: textarea-ui
6
+ status: stable
6
7
  component: Textarea
7
8
  category: layout
8
9
  version: 1
@@ -77,6 +77,7 @@
77
77
  ],
78
78
  "slots": {},
79
79
  "states": [],
80
+ "status": "stable",
80
81
  "synonyms": {
81
82
  "timeline-item": [
82
83
  "timeline-row",
@@ -11,6 +11,7 @@
11
11
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
12
12
  name: UITimelineItem
13
13
  tag: timeline-item-ui
14
+ status: stable
14
15
  component: TimelineItem
15
16
  category: feedback
16
17
  version: 1
@@ -81,6 +81,7 @@
81
81
  "name": "idle"
82
82
  }
83
83
  ],
84
+ "status": "stable",
84
85
  "synonyms": {
85
86
  "timeline": [
86
87
  "activity-log",
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UITimeline
5
5
  tag: timeline-ui
6
+ status: stable
6
7
  component: Timeline
7
8
  category: display
8
9
  version: 1
@@ -98,6 +98,7 @@
98
98
  "name": "idle"
99
99
  }
100
100
  ],
101
+ "status": "stable",
101
102
  "synonyms": {
102
103
  "alert": [
103
104
  "alert",
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UIToast
5
5
  tag: toast-ui
6
+ status: stable
6
7
  component: Toast
7
8
  category: container
8
9
  version: 1
@@ -76,6 +76,7 @@
76
76
  "name": "idle"
77
77
  }
78
78
  ],
79
+ "status": "stable",
79
80
  "synonyms": {
80
81
  "toggle-group": [
81
82
  "segmented-control",
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UIToggleGroup
5
5
  tag: toggle-group-ui
6
+ status: stable
6
7
  component: ToggleGroup
7
8
  category: navigation
8
9
  version: 1
@@ -61,6 +61,7 @@
61
61
  ],
62
62
  "slots": {},
63
63
  "states": [],
64
+ "status": "stable",
64
65
  "synonyms": {
65
66
  "toggle-option": [
66
67
  "toggle-segment",
@@ -8,6 +8,7 @@
8
8
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
9
9
  name: UIToggleOption
10
10
  tag: toggle-option-ui
11
+ status: stable
11
12
  component: ToggleOption
12
13
  category: forms
13
14
  version: 1
@@ -186,6 +186,7 @@
186
186
  "name": "disabled"
187
187
  }
188
188
  ],
189
+ "status": "stable",
189
190
  "synonyms": {
190
191
  "dark-mode": [
191
192
  "toggle-scheme"
@@ -2,6 +2,7 @@
2
2
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
3
3
  name: UIToggleScheme
4
4
  tag: toggle-scheme-ui
5
+ status: stable
5
6
  component: ToggleScheme
6
7
  category: control
7
8
  version: 1
@@ -41,6 +41,7 @@
41
41
  ],
42
42
  "slots": {},
43
43
  "states": [],
44
+ "status": "stable",
44
45
  "synonyms": {
45
46
  "toolbar-group": [
46
47
  "button-group",
@@ -9,6 +9,7 @@
9
9
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
10
10
  name: UIToolbarGroup
11
11
  tag: toolbar-group-ui
12
+ status: stable
12
13
  component: ToolbarGroup
13
14
  category: navigation
14
15
  version: 1
@@ -78,6 +78,7 @@
78
78
  "name": "idle"
79
79
  }
80
80
  ],
81
+ "status": "stable",
81
82
  "synonyms": {
82
83
  "action-bar": [
83
84
  "toolbar",
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UIToolbar
5
5
  tag: toolbar-ui
6
+ status: stable
6
7
  component: Toolbar
7
8
  category: layout
8
9
  version: 1
@@ -105,6 +105,7 @@
105
105
  "name": "idle"
106
106
  }
107
107
  ],
108
+ "status": "stable",
108
109
  "synonyms": {
109
110
  "buttons": [
110
111
  "toolbar",
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UITooltip
5
5
  tag: tooltip-ui
6
+ status: stable
6
7
  component: Tooltip
7
8
  category: container
8
9
  version: 1
@@ -66,6 +66,7 @@
66
66
  ],
67
67
  "slots": {},
68
68
  "states": [],
69
+ "status": "stable",
69
70
  "synonyms": {
70
71
  "tree-item": [
71
72
  "tree-node",
@@ -11,6 +11,7 @@
11
11
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
12
12
  name: UITreeItem
13
13
  tag: tree-item-ui
14
+ status: stable
14
15
  component: TreeItem
15
16
  category: data
16
17
  version: 1
@@ -87,6 +87,7 @@
87
87
  "name": "idle"
88
88
  }
89
89
  ],
90
+ "status": "stable",
90
91
  "synonyms": {
91
92
  "folder": [
92
93
  "inbox",
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UITree
5
5
  tag: tree-ui
6
+ status: stable
6
7
  component: Tree
7
8
  category: data
8
9
  version: 1
@@ -128,6 +128,7 @@
128
128
  "name": "disabled"
129
129
  }
130
130
  ],
131
+ "status": "stable",
131
132
  "synonyms": {
132
133
  "attach": [
133
134
  "file",
@@ -3,6 +3,7 @@
3
3
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
4
  name: UIUpload
5
5
  tag: upload-ui
6
+ status: stable
6
7
  component: Upload
7
8
  category: input
8
9
  version: 1
@@ -118,10 +118,16 @@ if (hasViteGlob) {
118
118
  // never tries to pre-resolve it in dev (where the file doesn't exist).
119
119
  const manifestSpec = './icons-manifest.js';
120
120
  import(/* @vite-ignore */ manifestSpec).then(({ default: manifest }) => {
121
- const modules = Object.fromEntries(Object.entries(manifest).map(([weight, names]) => {
122
- const prefix = `/node_modules/@phosphor-icons/core/assets/${weight}/`;
121
+ // `cdn` is an optional key added by bundle-js.mjs for CDN-distributed
122
+ // bundles. When present, SVGs are fetched from the CDN origin rather than
123
+ // /node_modules/ (which only exists on localhost / in a bundler context).
124
+ const { cdn: cdnBase, ...weights } = manifest;
125
+ const modules = Object.fromEntries(Object.entries(weights).map(([weight, names]) => {
126
+ const base = cdnBase
127
+ ? `${cdnBase}${weight}/`
128
+ : `/node_modules/@phosphor-icons/core/assets/${weight}/`;
123
129
  const entries = names.map(name => {
124
- const path = prefix + name;
130
+ const path = base + name;
125
131
  const loader = () => fetch(path).then(r => r.ok ? r.text() : Promise.reject(new Error(`icon fetch failed: ${path}`)));
126
132
  return [path, loader];
127
133
  });