@adia-ai/web-components 0.4.6 → 0.4.7

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 (284) hide show
  1. package/USAGE.md +29 -9
  2. package/components/accordion/accordion.d.ts +17 -0
  3. package/components/accordion/accordion.js +10 -117
  4. package/components/accordion/class.js +132 -0
  5. package/components/action-list/action-list.d.ts +15 -0
  6. package/components/action-list/action-list.js +9 -140
  7. package/components/action-list/class.js +156 -0
  8. package/components/agent-artifact/agent-artifact.d.ts +25 -0
  9. package/components/agent-artifact/agent-artifact.js +8 -181
  10. package/components/agent-artifact/class.js +200 -0
  11. package/components/agent-feedback-bar/agent-feedback-bar.d.ts +21 -0
  12. package/components/agent-feedback-bar/agent-feedback-bar.js +8 -143
  13. package/components/agent-feedback-bar/class.js +162 -0
  14. package/components/agent-questions/agent-questions.d.ts +23 -0
  15. package/components/agent-questions/agent-questions.js +8 -180
  16. package/components/agent-questions/class.js +199 -0
  17. package/components/agent-reasoning/agent-reasoning.d.ts +23 -0
  18. package/components/agent-reasoning/agent-reasoning.js +8 -494
  19. package/components/agent-reasoning/class.js +513 -0
  20. package/components/agent-suggestions/agent-suggestions.d.ts +21 -0
  21. package/components/agent-suggestions/agent-suggestions.js +8 -78
  22. package/components/agent-suggestions/class.js +97 -0
  23. package/components/agent-trace/agent-trace.d.ts +19 -0
  24. package/components/alert/alert.d.ts +29 -0
  25. package/components/alert/alert.js +8 -175
  26. package/components/alert/class.js +194 -0
  27. package/components/avatar/avatar.d.ts +27 -0
  28. package/components/avatar/avatar.js +9 -159
  29. package/components/avatar/class.js +173 -0
  30. package/components/badge/badge.d.ts +27 -0
  31. package/components/badge/badge.js +9 -75
  32. package/components/badge/class.js +93 -0
  33. package/components/block/block.d.ts +19 -0
  34. package/components/block/block.js +9 -15
  35. package/components/block/class.js +33 -0
  36. package/components/breadcrumb/breadcrumb.d.ts +23 -0
  37. package/components/breadcrumb/breadcrumb.js +8 -113
  38. package/components/breadcrumb/class.js +132 -0
  39. package/components/button/button.d.ts +34 -0
  40. package/components/button/button.js +15 -66
  41. package/components/button/class.js +80 -0
  42. package/components/calendar-picker/calendar-picker.a2ui.json +6 -1
  43. package/components/calendar-picker/calendar-picker.js +8 -332
  44. package/components/calendar-picker/calendar-picker.yaml +51 -177
  45. package/components/calendar-picker/class.js +351 -0
  46. package/components/canvas/canvas.a2ui.json +6 -1
  47. package/components/canvas/canvas.d.ts +17 -0
  48. package/components/canvas/canvas.yaml +19 -36
  49. package/components/card/card.a2ui.json +3 -0
  50. package/components/card/card.d.ts +27 -0
  51. package/components/card/card.js +9 -50
  52. package/components/card/card.yaml +171 -433
  53. package/components/card/class.js +68 -0
  54. package/components/chart/chart.d.ts +41 -0
  55. package/components/chart/chart.js +8 -2131
  56. package/components/chart/class.js +2150 -0
  57. package/components/chart-legend/chart-legend.d.ts +27 -0
  58. package/components/chart-legend/chart-legend.js +8 -197
  59. package/components/chart-legend/class.js +215 -0
  60. package/components/chat-thread/chat-thread.d.ts +17 -0
  61. package/components/chat-thread/chat-thread.js +8 -157
  62. package/components/chat-thread/class.js +176 -0
  63. package/components/check/check.js +11 -52
  64. package/components/check/class.js +68 -0
  65. package/components/code/class.js +501 -0
  66. package/components/code/code.js +8 -482
  67. package/components/col/class.js +30 -0
  68. package/components/col/col.d.ts +23 -0
  69. package/components/col/col.js +10 -13
  70. package/components/color-picker/class.js +550 -0
  71. package/components/color-picker/color-picker.js +8 -531
  72. package/components/command/class.js +364 -0
  73. package/components/command/command.a2ui.json +3 -0
  74. package/components/command/command.d.ts +19 -0
  75. package/components/command/command.js +8 -345
  76. package/components/command/command.yaml +105 -124
  77. package/components/demo-toggle/class.js +153 -0
  78. package/components/demo-toggle/demo-toggle.d.ts +23 -0
  79. package/components/demo-toggle/demo-toggle.js +8 -135
  80. package/components/description-list/class.js +86 -0
  81. package/components/description-list/description-list.d.ts +21 -0
  82. package/components/description-list/description-list.js +8 -67
  83. package/components/divider/class.js +57 -0
  84. package/components/divider/divider.d.ts +19 -0
  85. package/components/divider/divider.js +10 -40
  86. package/components/drawer/class.js +306 -0
  87. package/components/drawer/drawer.d.ts +25 -0
  88. package/components/drawer/drawer.js +8 -287
  89. package/components/embed/class.js +73 -0
  90. package/components/embed/embed.d.ts +23 -0
  91. package/components/embed/embed.js +9 -55
  92. package/components/empty-state/class.js +108 -0
  93. package/components/empty-state/empty-state.d.ts +21 -0
  94. package/components/empty-state/empty-state.js +9 -90
  95. package/components/feed/class.js +381 -0
  96. package/components/feed/feed.d.ts +19 -0
  97. package/components/feed/feed.js +9 -367
  98. package/components/field/class.js +266 -0
  99. package/components/field/field.d.ts +23 -0
  100. package/components/field/field.js +8 -247
  101. package/components/fields/class.js +106 -0
  102. package/components/fields/fields.d.ts +19 -0
  103. package/components/fields/fields.js +8 -87
  104. package/components/grid/class.js +31 -0
  105. package/components/grid/grid.d.ts +23 -0
  106. package/components/grid/grid.js +10 -14
  107. package/components/heatmap/class.js +305 -0
  108. package/components/heatmap/heatmap.d.ts +31 -0
  109. package/components/heatmap/heatmap.js +8 -286
  110. package/components/icon/class.js +54 -0
  111. package/components/icon/icon.d.ts +23 -0
  112. package/components/icon/icon.js +13 -40
  113. package/components/image/class.js +112 -0
  114. package/components/image/image.d.ts +33 -0
  115. package/components/image/image.js +9 -94
  116. package/components/input/class.js +773 -0
  117. package/components/input/input.a2ui.json +3 -0
  118. package/components/input/input.js +8 -755
  119. package/components/input/input.yaml +171 -442
  120. package/components/inspector/class.js +142 -0
  121. package/components/inspector/inspector.a2ui.json +8 -1
  122. package/components/inspector/inspector.d.ts +17 -0
  123. package/components/inspector/inspector.js +8 -124
  124. package/components/inspector/inspector.yaml +15 -30
  125. package/components/kbd/class.js +34 -0
  126. package/components/kbd/kbd.a2ui.json +3 -0
  127. package/components/kbd/kbd.d.ts +17 -0
  128. package/components/kbd/kbd.js +10 -17
  129. package/components/kbd/kbd.yaml +54 -185
  130. package/components/link/class.js +187 -0
  131. package/components/link/link.d.ts +55 -0
  132. package/components/link/link.js +8 -168
  133. package/components/list/class.js +249 -0
  134. package/components/list/list.d.ts +23 -0
  135. package/components/list/list.js +9 -231
  136. package/components/menu/class.js +332 -0
  137. package/components/menu/menu.d.ts +21 -0
  138. package/components/menu/menu.js +11 -316
  139. package/components/modal/class.js +231 -0
  140. package/components/modal/modal.a2ui.json +5 -1
  141. package/components/modal/modal.d.ts +23 -0
  142. package/components/modal/modal.js +8 -212
  143. package/components/modal/modal.yaml +19 -39
  144. package/components/nav/class.js +150 -0
  145. package/components/nav/nav.d.ts +31 -0
  146. package/components/nav/nav.js +8 -131
  147. package/components/nav-group/class.js +152 -0
  148. package/components/nav-group/nav-group.d.ts +35 -0
  149. package/components/nav-group/nav-group.js +9 -134
  150. package/components/nav-item/class.js +86 -0
  151. package/components/nav-item/nav-item.d.ts +37 -0
  152. package/components/nav-item/nav-item.js +10 -69
  153. package/components/noodles/class.js +510 -0
  154. package/components/noodles/noodles.d.ts +33 -0
  155. package/components/noodles/noodles.js +9 -493
  156. package/components/option-card/class.js +167 -0
  157. package/components/option-card/option-card.js +8 -149
  158. package/components/otp-input/class.js +180 -0
  159. package/components/otp-input/otp-input.a2ui.json +5 -1
  160. package/components/otp-input/otp-input.js +9 -162
  161. package/components/otp-input/otp-input.yaml +45 -174
  162. package/components/page/class.js +97 -0
  163. package/components/page/page.d.ts +46 -0
  164. package/components/page/page.js +8 -79
  165. package/components/pagination/class.js +195 -0
  166. package/components/pagination/pagination.d.ts +23 -0
  167. package/components/pagination/pagination.js +9 -177
  168. package/components/pane/class.js +186 -0
  169. package/components/pane/pane.a2ui.json +12 -1
  170. package/components/pane/pane.d.ts +31 -0
  171. package/components/pane/pane.js +8 -167
  172. package/components/pane/pane.yaml +57 -157
  173. package/components/pipeline-status/class.js +189 -0
  174. package/components/pipeline-status/pipeline-status.a2ui.json +7 -1
  175. package/components/pipeline-status/pipeline-status.d.ts +21 -0
  176. package/components/pipeline-status/pipeline-status.js +9 -172
  177. package/components/pipeline-status/pipeline-status.yaml +34 -72
  178. package/components/popover/class.js +194 -0
  179. package/components/popover/popover.d.ts +23 -0
  180. package/components/popover/popover.js +9 -176
  181. package/components/progress/class.js +74 -0
  182. package/components/progress/progress.a2ui.json +3 -0
  183. package/components/progress/progress.d.ts +19 -0
  184. package/components/progress/progress.js +10 -57
  185. package/components/progress/progress.yaml +124 -287
  186. package/components/progress-row/class.js +110 -0
  187. package/components/progress-row/progress-row.d.ts +23 -0
  188. package/components/progress-row/progress-row.js +8 -92
  189. package/components/radio/class.js +83 -0
  190. package/components/radio/radio.js +11 -67
  191. package/components/range/class.js +194 -0
  192. package/components/range/range.js +9 -176
  193. package/components/rating/class.js +148 -0
  194. package/components/rating/rating.js +9 -130
  195. package/components/richtext/class.js +87 -0
  196. package/components/richtext/richtext.a2ui.json +7 -1
  197. package/components/richtext/richtext.d.ts +19 -0
  198. package/components/richtext/richtext.js +8 -68
  199. package/components/richtext/richtext.yaml +30 -65
  200. package/components/row/class.js +50 -0
  201. package/components/row/row.d.ts +27 -0
  202. package/components/row/row.js +10 -33
  203. package/components/search/class.js +134 -0
  204. package/components/search/search.js +10 -117
  205. package/components/segment/class.js +62 -0
  206. package/components/segment/segment.d.ts +25 -0
  207. package/components/segment/segment.js +10 -45
  208. package/components/segmented/class.js +165 -0
  209. package/components/segmented/segmented.a2ui.json +4 -0
  210. package/components/segmented/segmented.js +10 -148
  211. package/components/segmented/segmented.yaml +41 -59
  212. package/components/select/class.js +408 -0
  213. package/components/select/select.js +15 -396
  214. package/components/skeleton/class.js +52 -0
  215. package/components/skeleton/skeleton.d.ts +23 -0
  216. package/components/skeleton/skeleton.js +8 -34
  217. package/components/slider/class.js +184 -0
  218. package/components/slider/slider.js +9 -166
  219. package/components/stack/class.js +28 -0
  220. package/components/stack/stack.d.ts +17 -0
  221. package/components/stack/stack.js +10 -11
  222. package/components/step-progress/class.js +98 -0
  223. package/components/step-progress/step-progress.d.ts +27 -0
  224. package/components/step-progress/step-progress.js +8 -79
  225. package/components/stepper/class.js +126 -0
  226. package/components/stepper/stepper.d.ts +19 -0
  227. package/components/stepper/stepper.js +9 -112
  228. package/components/stream/class.js +109 -0
  229. package/components/stream/stream.d.ts +19 -0
  230. package/components/stream/stream.js +8 -90
  231. package/components/swatch/class.js +131 -0
  232. package/components/swatch/swatch.d.ts +28 -0
  233. package/components/swatch/swatch.js +8 -112
  234. package/components/swiper/class.js +373 -0
  235. package/components/swiper/swiper.a2ui.json +4 -0
  236. package/components/swiper/swiper.d.ts +31 -0
  237. package/components/swiper/swiper.js +8 -354
  238. package/components/swiper/swiper.yaml +68 -212
  239. package/components/switch/class.js +63 -0
  240. package/components/switch/switch.a2ui.json +6 -1
  241. package/components/switch/switch.js +11 -47
  242. package/components/switch/switch.yaml +70 -265
  243. package/components/table/class.js +1453 -0
  244. package/components/table/table.d.ts +37 -0
  245. package/components/table/table.js +8 -1435
  246. package/components/table-toolbar/class.js +680 -0
  247. package/components/table-toolbar/table-toolbar.d.ts +33 -0
  248. package/components/table-toolbar/table-toolbar.js +8 -689
  249. package/components/tabs/class.js +242 -0
  250. package/components/tabs/tabs.d.ts +21 -0
  251. package/components/tabs/tabs.js +8 -223
  252. package/components/tag/class.js +99 -0
  253. package/components/tag/tag.d.ts +27 -0
  254. package/components/tag/tag.js +8 -80
  255. package/components/text/class.js +46 -0
  256. package/components/text/text.d.ts +25 -0
  257. package/components/text/text.js +9 -28
  258. package/components/textarea/class.js +134 -0
  259. package/components/textarea/textarea.js +11 -118
  260. package/components/timeline/class.js +176 -0
  261. package/components/timeline/timeline.d.ts +19 -0
  262. package/components/timeline/timeline.js +9 -162
  263. package/components/toast/class.js +92 -0
  264. package/components/toast/toast.d.ts +23 -0
  265. package/components/toast/toast.js +9 -76
  266. package/components/toggle-group/class.js +154 -0
  267. package/components/toggle-group/toggle-group.d.ts +19 -0
  268. package/components/toggle-group/toggle-group.js +11 -140
  269. package/components/toggle-scheme/class.js +286 -0
  270. package/components/toggle-scheme/toggle-scheme.d.ts +41 -0
  271. package/components/toggle-scheme/toggle-scheme.js +8 -268
  272. package/components/toolbar/class.js +388 -0
  273. package/components/toolbar/toolbar.d.ts +23 -0
  274. package/components/toolbar/toolbar.js +10 -376
  275. package/components/tooltip/class.js +299 -0
  276. package/components/tooltip/tooltip.d.ts +27 -0
  277. package/components/tooltip/tooltip.js +8 -280
  278. package/components/tree/class.js +245 -0
  279. package/components/tree/tree.d.ts +15 -0
  280. package/components/tree/tree.js +9 -244
  281. package/components/upload/class.js +199 -0
  282. package/components/upload/upload.js +11 -183
  283. package/index.d.ts +159 -5
  284. package/package.json +5 -1
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Non-side-effect class export for `<agent-suggestions-ui>`.
3
+ *
4
+ * Importing this file gives you the class(es) without auto-registering the tag.
5
+ * Useful for test isolation, subclassing with tag-name override, or selective
6
+ * composition.
7
+ *
8
+ * The auto-register path stays at `@adia-ai/web-components/components/agent-suggestions`
9
+ * (which imports this file + calls `defineIfFree()`).
10
+ *
11
+ * @see ../../USAGE.md#registration--auto-vs-explicit
12
+ */
13
+
14
+ /**
15
+ * <agent-suggestions-ui> — Row of follow-up suggestion chips.
16
+ *
17
+ * The agent proposes 2-4 next-step prompts; user picks one. The host listens
18
+ * for `suggestion-select` and dispatches the associated prompt.
19
+ *
20
+ * JS API:
21
+ * el.suggestions = [
22
+ * { label: 'Add price comparison' }, // label === prompt
23
+ * { label: 'Add quantity stepper', prompt: 'add a stepper' },
24
+ * { label: 'Variants picker', prompt: 'add a variants picker', icon: 'tag' },
25
+ * ];
26
+ *
27
+ * el.addEventListener('suggestion-select', (e) => {
28
+ * submit(e.detail.prompt);
29
+ * });
30
+ *
31
+ * Attributes:
32
+ * variant — outline (default) | ghost | subtle
33
+ * size — sm (default) | md
34
+ * disabled — disable all chips
35
+ *
36
+ * Events:
37
+ * suggestion-select — detail: { label, prompt, index }
38
+ */
39
+
40
+ import { UIElement } from '../../core/element.js';
41
+
42
+ function truncate(s, n) {
43
+ if (typeof s !== 'string') return '';
44
+ return s.length > n ? s.slice(0, n - 1) + '…' : s;
45
+ }
46
+
47
+ export class UIAgentSuggestions extends UIElement {
48
+ static properties = {
49
+ variant: { type: String, default: 'outline', reflect: true },
50
+ size: { type: String, default: 'sm', reflect: true },
51
+ disabled: { type: Boolean, default: false, reflect: true },
52
+ };
53
+
54
+ static template = () => null;
55
+
56
+ #suggestions = [];
57
+
58
+ get suggestions() { return this.#suggestions; }
59
+ set suggestions(v) {
60
+ this.#suggestions = Array.isArray(v) ? v.slice() : [];
61
+ this.#render();
62
+ }
63
+
64
+ connected() {
65
+ this.#render();
66
+ }
67
+
68
+ disconnected() {
69
+ this.innerHTML = '';
70
+ }
71
+
72
+ #render() {
73
+ this.innerHTML = '';
74
+ for (let i = 0; i < this.#suggestions.length; i++) {
75
+ const s = this.#suggestions[i];
76
+ const label = typeof s === 'string' ? s : s.label || s.prompt || '';
77
+ const prompt = typeof s === 'string' ? s : s.prompt || s.label || '';
78
+ const icon = typeof s === 'object' ? s.icon : null;
79
+
80
+ const chip = document.createElement('button-ui');
81
+ chip.setAttribute('text', truncate(label, 42));
82
+ chip.setAttribute('variant', this.variant);
83
+ chip.setAttribute('size', this.size);
84
+ if (icon) chip.setAttribute('icon', icon);
85
+ if (this.disabled) chip.setAttribute('disabled', '');
86
+
87
+ chip.addEventListener('press', () => {
88
+ if (this.disabled) return;
89
+ this.dispatchEvent(new CustomEvent('suggestion-select', {
90
+ bubbles: true,
91
+ detail: { label, prompt, index: i },
92
+ }));
93
+ });
94
+ this.appendChild(chip);
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `<agent-trace-ui>` — Collapsible metrics + training-feedback panel for an agent turn.
3
+ *
4
+ * @see https://ui-kit.exe.xyz/site/components/agent-trace
5
+ *
6
+ * Type declarations generated by scripts/build/dts-codegen.mjs from
7
+ * the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
8
+ * run `npm run components`, then `npm run codegen:dts` to regenerate;
9
+ * or hand-author this file fully if rich event types are needed.
10
+ */
11
+
12
+ import { UIElement } from '../../core/element.js';
13
+
14
+ export class UIAgentTrace extends UIElement {
15
+ /** Hide the trace body. Default-visible disclosure (matches the agent-* family — agent-reasoning, agent-artifact). Set to opt out. */
16
+ collapsed: boolean;
17
+ /** Fallback summary label. */
18
+ label: string;
19
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `<alert-ui>` — Inline alert banner with optional icon and close button.
3
+ *
4
+ * @see https://ui-kit.exe.xyz/site/components/alert
5
+ *
6
+ * Type declarations generated by scripts/build/dts-codegen.mjs from
7
+ * the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
8
+ * run `npm run components`, then `npm run codegen:dts` to regenerate;
9
+ * or hand-author this file fully if rich event types are needed.
10
+ */
11
+
12
+ import { UIElement } from '../../core/element.js';
13
+
14
+ export class UIAlert extends UIElement {
15
+ /** Bold headline rendered as the first line of the alert content. Pair with [description] for the canonical "banner" pattern (headline + body). When [title] or [description] is set, the [text] prop is ignored. */
16
+ title: string;
17
+ /** Body text rendered as the second line of the alert content, below [title]. May be used alone (without [title]) for a single muted-body message. */
18
+ description: string;
19
+ /** Whether a close button is displayed. Alias [dismissible] is also accepted (same semantics, different spelling — the corpus and many libraries use both; both map to the same state). */
20
+ closable: boolean;
21
+ /** Public alias for [closable] — same semantics. Both attributes render the close button. Use whichever spelling matches your authoring style. */
22
+ dismissible: boolean;
23
+ /** Icon identifier displayed before the message content */
24
+ icon: string;
25
+ /** Single-line alert message. For two-line "headline + body" alerts, use [title] + [description] instead. For rich content (links, formatting), use the [slot="content"] slot. */
26
+ text: string;
27
+ /** Semantic color variant. */
28
+ variant: 'default' | 'info' | 'success' | 'warning' | 'danger' | 'muted' | 'neutral';
29
+ }
@@ -1,184 +1,17 @@
1
1
  /**
2
- * <alert-ui text="Something happened" variant="info" icon="info-circle"></alert-ui>
3
- * <alert-ui text="Deleted." variant="danger" closable></alert-ui>
2
+ * `<alert-ui>` auto-registers the tag on import.
4
3
  *
5
- * Inline alert banner with optional icon and close button.
4
+ * For non-side-effect class import (test isolation, tag override), use
5
+ * the `class` subpath:
6
6
  *
7
- * Variants: default, info, success, warning, danger, muted, neutral
8
- * Slots: leading (icon), content (text), close (dismiss button)
7
+ * import { UIAlert } from '@adia-ai/web-components/components/alert/class';
9
8
  *
10
- * Events:
11
- * close — fired when the user dismisses the alert
9
+ * @see ../../USAGE.md#registration--auto-vs-explicit
12
10
  */
13
11
 
14
- import { UIElement } from '../../core/element.js';
12
+ import { defineIfFree } from '../../core/register.js';
13
+ import { UIAlert } from './class.js';
15
14
 
16
- // One-time warn cache so the same alias hit doesn't spam the console
17
- // across hundreds of components per render. We use warnings ONLY for
18
- // genuine hallucinations the LLM should learn to stop emitting:
19
- // - variant="error" (canonical: "danger" — explicit in the enum)
20
- // - [closeable] (canonical: "closable" — established spelling)
21
- // First-class props ([title], [description], [dismissible]) do NOT warn —
22
- // they're public, supported, documented in alert.yaml.
23
- const _aliasWarned = new Set();
24
- function _warnOnce(key, message) {
25
- if (_aliasWarned.has(key)) return;
26
- _aliasWarned.add(key);
27
- // eslint-disable-next-line no-console
28
- console.warn(`[alert-ui] ${message}`);
29
- }
30
-
31
- class UIAlert extends UIElement {
32
- static properties = {
33
- text: { type: String, default: '', reflect: true },
34
- title: { type: String, default: '', reflect: true },
35
- description: { type: String, default: '', reflect: true },
36
- variant: { type: String, default: 'default', reflect: true },
37
- closable: { type: Boolean, default: false, reflect: true },
38
- dismissible: { type: Boolean, default: false, reflect: true },
39
- icon: { type: String, default: '', reflect: true },
40
- };
41
-
42
- static parts = {
43
- leading: '<icon-ui slot="leading"></icon-ui>',
44
- content: '<span slot="content"></span>',
45
- /* Close affordance is a real button-ui \u2014 inherits the system focus
46
- ring, hover transition, and icon sizing automatically. Listen for
47
- the canonical `press` event (button-ui dispatches on click + Enter
48
- + Space, no extra keydown wiring needed). */
49
- close: '<button-ui slot="close" icon="x" variant="ghost" size="sm" aria-label="Close"></button-ui>',
50
- };
51
-
52
- static template = () => null;
53
-
54
- /**
55
- * Normalize alias attrs that the LLM / corpus occasionally emits in
56
- * non-canonical forms. Runs once at connected() before render(). Two
57
- * categories:
58
- *
59
- * FIRST-CLASS ALIASES (public, supported, no warn):
60
- * - [dismissible] ↔ [closable] (same semantics; either spelling
61
- * maps to the same close-button affordance)
62
- *
63
- * HALLUCINATION ALIASES (warn-once, encourage canonical form):
64
- * - variant="error" → variant="danger" (not in the canonical
65
- * enum [default, info, success, warning, danger, muted, neutral])
66
- * - [closeable] → [closable] (alternate spelling, less standard
67
- * than dismissible/closable; warn to discourage)
68
- */
69
- #normalizeAliases() {
70
- // variant=error → danger (hallucination; warn)
71
- if (this.getAttribute('variant') === 'error') {
72
- _warnOnce('variant-error', 'variant="error" is not in the canonical enum [default, info, success, warning, danger, muted, neutral]. Mapping to "danger". Fix the source (LLM prompt / corpus pattern) to emit "danger" directly.');
73
- this.setAttribute('variant', 'danger');
74
- }
75
-
76
- // closeable → closable (typo-class; warn)
77
- if (this.hasAttribute('closeable') && !this.hasAttribute('closable') && !this.hasAttribute('dismissible')) {
78
- _warnOnce('alias-closeable', 'attribute [closeable] is a misspelled alias of canonical [closable]. Mapping. Fix the source to use [closable] or [dismissible].');
79
- this.setAttribute('closable', '');
80
- this.removeAttribute('closeable');
81
- }
82
-
83
- // dismissible ↔ closable (first-class alias; no warn)
84
- if (this.hasAttribute('dismissible') && !this.hasAttribute('closable')) {
85
- this.setAttribute('closable', '');
86
- }
87
- }
88
-
89
- #onPress = (e) => {
90
- if (e.target.closest('[slot="close"]')) this.#close();
91
- };
92
-
93
- connected() {
94
- this.#normalizeAliases();
95
- this.#updateRole();
96
-
97
- // Stamp default DOM if nothing was provided
98
- if (this.icon) this.ensure('leading');
99
- this.ensure('content');
100
- if (this.closable) this.ensure('close');
101
-
102
- this.addEventListener('press', this.#onPress);
103
- }
104
-
105
- disconnected() {
106
- this.removeEventListener('press', this.#onPress);
107
- }
108
-
109
- render() {
110
- // Icon
111
- if (this.icon) {
112
- const leading = this.ensure('leading');
113
- if (leading) leading.setAttribute('name', this.icon);
114
- } else {
115
- this.drop('leading');
116
- }
117
-
118
- // Content rendering — three modes, in precedence order:
119
- // 1. Author-provided <span slot="content">…</span> with content
120
- // already inside wins (rich content path)
121
- // 2. [title] and/or [description] — bolded headline + body paragraph
122
- // 3. [text] — single-line message
123
- //
124
- // Detection of "author content" is by checking whether the slot
125
- // element has its `data-alert-auto` flag (set by us when we stamp
126
- // content). If the flag is absent AND the element has any content,
127
- // the author provided it; leave it alone.
128
- const content = this.ensure('content');
129
- if (content) {
130
- const wasAutoStamped = content.hasAttribute('data-alert-auto');
131
- const hasContent = content.childNodes.length > 0;
132
- if (!wasAutoStamped && hasContent) {
133
- // Author-provided rich content. Mirror title/description to
134
- // aria-label if they were set, but don't touch the markup.
135
- if (this.title || this.description) {
136
- const aria = [this.title, this.description].filter(Boolean).join('. ');
137
- this.setAttribute('aria-label', aria);
138
- }
139
- } else if (this.title || this.description) {
140
- // Mode 2: title + description composed
141
- content.setAttribute('data-alert-auto', 'title-desc');
142
- content.replaceChildren();
143
- if (this.title) {
144
- const strong = document.createElement('strong');
145
- strong.textContent = this.title;
146
- content.appendChild(strong);
147
- if (this.description) content.appendChild(document.createTextNode(' '));
148
- }
149
- if (this.description) {
150
- content.appendChild(document.createTextNode(this.description));
151
- }
152
- const aria = [this.title, this.description].filter(Boolean).join('. ');
153
- this.setAttribute('aria-label', aria);
154
- } else if (this.text) {
155
- // Mode 3: single-line text
156
- content.setAttribute('data-alert-auto', 'text');
157
- content.textContent = this.text;
158
- }
159
- }
160
-
161
- // Close button
162
- if (this.closable || this.dismissible) {
163
- this.ensure('close');
164
- } else {
165
- this.drop('close');
166
- }
167
-
168
- // Role
169
- this.#updateRole();
170
- }
171
-
172
- #updateRole() {
173
- const role = (this.variant === 'danger' || this.variant === 'warning') ? 'alert' : 'status';
174
- this.setAttribute('role', role);
175
- }
176
-
177
- #close() {
178
- this.dispatchEvent(new Event('close', { bubbles: true }));
179
- this.remove();
180
- }
181
- }
182
- customElements.define('alert-ui', UIAlert);
15
+ defineIfFree('alert-ui', UIAlert);
183
16
 
184
17
  export { UIAlert };
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Non-side-effect class export for `<alert-ui>`.
3
+ *
4
+ * Importing this file gives you the class(es) without auto-registering the tag.
5
+ * Useful for test isolation, subclassing with tag-name override, or selective
6
+ * composition.
7
+ *
8
+ * The auto-register path stays at `@adia-ai/web-components/components/alert`
9
+ * (which imports this file + calls `defineIfFree()`).
10
+ *
11
+ * @see ../../USAGE.md#registration--auto-vs-explicit
12
+ */
13
+
14
+ /**
15
+ * <alert-ui text="Something happened" variant="info" icon="info-circle"></alert-ui>
16
+ * <alert-ui text="Deleted." variant="danger" closable></alert-ui>
17
+ *
18
+ * Inline alert banner with optional icon and close button.
19
+ *
20
+ * Variants: default, info, success, warning, danger, muted, neutral
21
+ * Slots: leading (icon), content (text), close (dismiss button)
22
+ *
23
+ * Events:
24
+ * close — fired when the user dismisses the alert
25
+ */
26
+
27
+ import { UIElement } from '../../core/element.js';
28
+
29
+ // One-time warn cache so the same alias hit doesn't spam the console
30
+ // across hundreds of components per render. We use warnings ONLY for
31
+ // genuine hallucinations the LLM should learn to stop emitting:
32
+ // - variant="error" (canonical: "danger" — explicit in the enum)
33
+ // - [closeable] (canonical: "closable" — established spelling)
34
+ // First-class props ([title], [description], [dismissible]) do NOT warn —
35
+ // they're public, supported, documented in alert.yaml.
36
+ const _aliasWarned = new Set();
37
+ function _warnOnce(key, message) {
38
+ if (_aliasWarned.has(key)) return;
39
+ _aliasWarned.add(key);
40
+ // eslint-disable-next-line no-console
41
+ console.warn(`[alert-ui] ${message}`);
42
+ }
43
+
44
+ export class UIAlert extends UIElement {
45
+ static properties = {
46
+ text: { type: String, default: '', reflect: true },
47
+ title: { type: String, default: '', reflect: true },
48
+ description: { type: String, default: '', reflect: true },
49
+ variant: { type: String, default: 'default', reflect: true },
50
+ closable: { type: Boolean, default: false, reflect: true },
51
+ dismissible: { type: Boolean, default: false, reflect: true },
52
+ icon: { type: String, default: '', reflect: true },
53
+ };
54
+
55
+ static parts = {
56
+ leading: '<icon-ui slot="leading"></icon-ui>',
57
+ content: '<span slot="content"></span>',
58
+ /* Close affordance is a real button-ui \u2014 inherits the system focus
59
+ ring, hover transition, and icon sizing automatically. Listen for
60
+ the canonical `press` event (button-ui dispatches on click + Enter
61
+ + Space, no extra keydown wiring needed). */
62
+ close: '<button-ui slot="close" icon="x" variant="ghost" size="sm" aria-label="Close"></button-ui>',
63
+ };
64
+
65
+ static template = () => null;
66
+
67
+ /**
68
+ * Normalize alias attrs that the LLM / corpus occasionally emits in
69
+ * non-canonical forms. Runs once at connected() before render(). Two
70
+ * categories:
71
+ *
72
+ * FIRST-CLASS ALIASES (public, supported, no warn):
73
+ * - [dismissible] ↔ [closable] (same semantics; either spelling
74
+ * maps to the same close-button affordance)
75
+ *
76
+ * HALLUCINATION ALIASES (warn-once, encourage canonical form):
77
+ * - variant="error" → variant="danger" (not in the canonical
78
+ * enum [default, info, success, warning, danger, muted, neutral])
79
+ * - [closeable] → [closable] (alternate spelling, less standard
80
+ * than dismissible/closable; warn to discourage)
81
+ */
82
+ #normalizeAliases() {
83
+ // variant=error → danger (hallucination; warn)
84
+ if (this.getAttribute('variant') === 'error') {
85
+ _warnOnce('variant-error', 'variant="error" is not in the canonical enum [default, info, success, warning, danger, muted, neutral]. Mapping to "danger". Fix the source (LLM prompt / corpus pattern) to emit "danger" directly.');
86
+ this.setAttribute('variant', 'danger');
87
+ }
88
+
89
+ // closeable → closable (typo-class; warn)
90
+ if (this.hasAttribute('closeable') && !this.hasAttribute('closable') && !this.hasAttribute('dismissible')) {
91
+ _warnOnce('alias-closeable', 'attribute [closeable] is a misspelled alias of canonical [closable]. Mapping. Fix the source to use [closable] or [dismissible].');
92
+ this.setAttribute('closable', '');
93
+ this.removeAttribute('closeable');
94
+ }
95
+
96
+ // dismissible ↔ closable (first-class alias; no warn)
97
+ if (this.hasAttribute('dismissible') && !this.hasAttribute('closable')) {
98
+ this.setAttribute('closable', '');
99
+ }
100
+ }
101
+
102
+ #onPress = (e) => {
103
+ if (e.target.closest('[slot="close"]')) this.#close();
104
+ };
105
+
106
+ connected() {
107
+ this.#normalizeAliases();
108
+ this.#updateRole();
109
+
110
+ // Stamp default DOM if nothing was provided
111
+ if (this.icon) this.ensure('leading');
112
+ this.ensure('content');
113
+ if (this.closable) this.ensure('close');
114
+
115
+ this.addEventListener('press', this.#onPress);
116
+ }
117
+
118
+ disconnected() {
119
+ this.removeEventListener('press', this.#onPress);
120
+ }
121
+
122
+ render() {
123
+ // Icon
124
+ if (this.icon) {
125
+ const leading = this.ensure('leading');
126
+ if (leading) leading.setAttribute('name', this.icon);
127
+ } else {
128
+ this.drop('leading');
129
+ }
130
+
131
+ // Content rendering — three modes, in precedence order:
132
+ // 1. Author-provided <span slot="content">…</span> with content
133
+ // already inside wins (rich content path)
134
+ // 2. [title] and/or [description] — bolded headline + body paragraph
135
+ // 3. [text] — single-line message
136
+ //
137
+ // Detection of "author content" is by checking whether the slot
138
+ // element has its `data-alert-auto` flag (set by us when we stamp
139
+ // content). If the flag is absent AND the element has any content,
140
+ // the author provided it; leave it alone.
141
+ const content = this.ensure('content');
142
+ if (content) {
143
+ const wasAutoStamped = content.hasAttribute('data-alert-auto');
144
+ const hasContent = content.childNodes.length > 0;
145
+ if (!wasAutoStamped && hasContent) {
146
+ // Author-provided rich content. Mirror title/description to
147
+ // aria-label if they were set, but don't touch the markup.
148
+ if (this.title || this.description) {
149
+ const aria = [this.title, this.description].filter(Boolean).join('. ');
150
+ this.setAttribute('aria-label', aria);
151
+ }
152
+ } else if (this.title || this.description) {
153
+ // Mode 2: title + description composed
154
+ content.setAttribute('data-alert-auto', 'title-desc');
155
+ content.replaceChildren();
156
+ if (this.title) {
157
+ const strong = document.createElement('strong');
158
+ strong.textContent = this.title;
159
+ content.appendChild(strong);
160
+ if (this.description) content.appendChild(document.createTextNode(' '));
161
+ }
162
+ if (this.description) {
163
+ content.appendChild(document.createTextNode(this.description));
164
+ }
165
+ const aria = [this.title, this.description].filter(Boolean).join('. ');
166
+ this.setAttribute('aria-label', aria);
167
+ } else if (this.text) {
168
+ // Mode 3: single-line text
169
+ content.setAttribute('data-alert-auto', 'text');
170
+ content.textContent = this.text;
171
+ }
172
+ }
173
+
174
+ // Close button
175
+ if (this.closable || this.dismissible) {
176
+ this.ensure('close');
177
+ } else {
178
+ this.drop('close');
179
+ }
180
+
181
+ // Role
182
+ this.#updateRole();
183
+ }
184
+
185
+ #updateRole() {
186
+ const role = (this.variant === 'danger' || this.variant === 'warning') ? 'alert' : 'status';
187
+ this.setAttribute('role', role);
188
+ }
189
+
190
+ #close() {
191
+ this.dispatchEvent(new Event('close', { bubbles: true }));
192
+ this.remove();
193
+ }
194
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `<avatar-ui>` — Avatar with image → initials → empty fallback chain.
3
+ *
4
+ * @see https://ui-kit.exe.xyz/site/components/avatar
5
+ *
6
+ * Type declarations generated by scripts/build/dts-codegen.mjs from
7
+ * the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
8
+ * run `npm run components`, then `npm run codegen:dts` to regenerate;
9
+ * or hand-author this file fully if rich event types are needed.
10
+ */
11
+
12
+ import { UIElement } from '../../core/element.js';
13
+
14
+ export class UIAvatar extends UIElement {
15
+ /** Phosphor icon name shown instead of initials when `src`/`text` are empty. */
16
+ icon: string;
17
+ /** Deprecated alias for `text` (logs a one-shot console warning; will be removed in a future release). New code should use `text=` instead. */
18
+ name: string;
19
+ /** Avatar shape */
20
+ shape: 'circle' | 'square';
21
+ /** Avatar size. Canonical scale (xs/sm/md/lg/xl); long-form aliases (small/medium/large/xlarge) accepted for back-compat. */
22
+ size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'small' | 'medium' | 'large' | 'xlarge';
23
+ /** Image source URL. Falls back to initials on error. */
24
+ src: string;
25
+ /** Display string (full name or initials). Initials derive from spaces — first letter of each word, max 2. */
26
+ text: string;
27
+ }