@adia-ai/web-components 0.4.8 → 0.5.0

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 (112) hide show
  1. package/USAGE.md +255 -2
  2. package/components/action-list/action-list.a2ui.json +15 -1
  3. package/components/action-list/action-list.d.ts +10 -1
  4. package/components/action-list/action-list.yaml +10 -0
  5. package/components/agent-artifact/agent-artifact.a2ui.json +7 -1
  6. package/components/agent-artifact/agent-artifact.d.ts +6 -1
  7. package/components/agent-artifact/agent-artifact.yaml +4 -0
  8. package/components/agent-feedback-bar/agent-feedback-bar.a2ui.json +7 -1
  9. package/components/agent-feedback-bar/agent-feedback-bar.d.ts +6 -1
  10. package/components/agent-feedback-bar/agent-feedback-bar.yaml +4 -0
  11. package/components/agent-questions/agent-questions.a2ui.json +11 -1
  12. package/components/agent-questions/agent-questions.d.ts +8 -1
  13. package/components/agent-questions/agent-questions.yaml +7 -0
  14. package/components/agent-reasoning/agent-reasoning.a2ui.json +25 -3
  15. package/components/agent-reasoning/agent-reasoning.d.ts +20 -3
  16. package/components/agent-reasoning/agent-reasoning.yaml +15 -0
  17. package/components/agent-suggestions/agent-suggestions.a2ui.json +15 -1
  18. package/components/agent-suggestions/agent-suggestions.d.ts +10 -1
  19. package/components/agent-suggestions/agent-suggestions.yaml +10 -0
  20. package/components/agent-trace/agent-trace.a2ui.json +7 -1
  21. package/components/agent-trace/agent-trace.d.ts +6 -1
  22. package/components/agent-trace/agent-trace.yaml +4 -0
  23. package/components/canvas/canvas.yaml +9 -7
  24. package/components/chart/chart.a2ui.json +3 -0
  25. package/components/chart/chart.d.ts +2 -0
  26. package/components/chart/chart.yaml +5 -0
  27. package/components/chart-legend/chart-legend.a2ui.json +15 -1
  28. package/components/chart-legend/chart-legend.d.ts +10 -1
  29. package/components/chart-legend/chart-legend.yaml +10 -0
  30. package/components/chat-thread/chat-thread.a2ui.json +11 -1
  31. package/components/chat-thread/chat-thread.d.ts +8 -1
  32. package/components/chat-thread/chat-thread.yaml +7 -0
  33. package/components/code/code.a2ui.json +36 -7
  34. package/components/code/code.d.ts +30 -0
  35. package/components/code/code.yaml +29 -6
  36. package/components/color-picker/class.js +59 -1
  37. package/components/color-picker/color-picker.a2ui.json +34 -0
  38. package/components/color-picker/color-picker.d.ts +70 -8
  39. package/components/color-picker/color-picker.yaml +49 -0
  40. package/components/command/command.a2ui.json +11 -1
  41. package/components/command/command.d.ts +8 -1
  42. package/components/command/command.yaml +7 -0
  43. package/components/demo-toggle/demo-toggle.a2ui.json +7 -1
  44. package/components/demo-toggle/demo-toggle.d.ts +6 -1
  45. package/components/demo-toggle/demo-toggle.yaml +4 -0
  46. package/components/heatmap/heatmap.a2ui.json +11 -2
  47. package/components/heatmap/heatmap.d.ts +6 -0
  48. package/components/heatmap/heatmap.yaml +17 -2
  49. package/components/link/link.a2ui.json +11 -1
  50. package/components/link/link.d.ts +8 -1
  51. package/components/link/link.yaml +7 -0
  52. package/components/list/list.a2ui.json +11 -1
  53. package/components/list/list.d.ts +8 -1
  54. package/components/list/list.yaml +7 -0
  55. package/components/menu/menu.a2ui.json +11 -1
  56. package/components/menu/menu.d.ts +8 -1
  57. package/components/menu/menu.yaml +7 -0
  58. package/components/nav/nav.a2ui.json +15 -1
  59. package/components/nav/nav.d.ts +10 -1
  60. package/components/nav/nav.yaml +10 -0
  61. package/components/nav-group/nav-group.a2ui.json +11 -1
  62. package/components/nav-group/nav-group.d.ts +8 -1
  63. package/components/nav-group/nav-group.yaml +7 -0
  64. package/components/nav-item/nav-item.a2ui.json +15 -1
  65. package/components/nav-item/nav-item.d.ts +10 -1
  66. package/components/nav-item/nav-item.yaml +10 -0
  67. package/components/noodles/noodles.a2ui.json +46 -2
  68. package/components/noodles/noodles.d.ts +28 -2
  69. package/components/noodles/noodles.yaml +32 -0
  70. package/components/otp-input/otp-input.a2ui.json +14 -2
  71. package/components/otp-input/otp-input.d.ts +11 -0
  72. package/components/otp-input/otp-input.yaml +10 -2
  73. package/components/pagination/pagination.a2ui.json +7 -1
  74. package/components/pagination/pagination.d.ts +6 -1
  75. package/components/pagination/pagination.yaml +4 -0
  76. package/components/stream/stream.a2ui.json +7 -1
  77. package/components/stream/stream.d.ts +6 -1
  78. package/components/stream/stream.yaml +4 -0
  79. package/components/swatch/class.js +362 -15
  80. package/components/swatch/swatch.a2ui.json +68 -1
  81. package/components/swatch/swatch.css +150 -0
  82. package/components/swatch/swatch.d.ts +43 -0
  83. package/components/swatch/swatch.yaml +67 -1
  84. package/components/swiper/swiper.a2ui.json +18 -2
  85. package/components/swiper/swiper.d.ts +14 -2
  86. package/components/swiper/swiper.yaml +11 -0
  87. package/components/table/table.a2ui.json +80 -5
  88. package/components/table/table.d.ts +58 -5
  89. package/components/table/table.yaml +54 -2
  90. package/components/tabs/tabs.a2ui.json +7 -1
  91. package/components/tabs/tabs.d.ts +6 -1
  92. package/components/tabs/tabs.yaml +4 -0
  93. package/components/tag/tag.a2ui.json +11 -1
  94. package/components/tag/tag.d.ts +8 -1
  95. package/components/tag/tag.yaml +7 -0
  96. package/components/timeline/timeline.a2ui.json +3 -7
  97. package/components/timeline/timeline.d.ts +2 -4
  98. package/components/timeline/timeline.yaml +3 -6
  99. package/components/toggle-group/toggle-group.a2ui.json +7 -1
  100. package/components/toggle-group/toggle-group.d.ts +6 -1
  101. package/components/toggle-group/toggle-group.yaml +4 -0
  102. package/components/toggle-scheme/toggle-scheme.a2ui.json +11 -1
  103. package/components/toggle-scheme/toggle-scheme.d.ts +8 -1
  104. package/components/toggle-scheme/toggle-scheme.yaml +7 -0
  105. package/components/tree/tree.a2ui.json +15 -1
  106. package/components/tree/tree.d.ts +10 -1
  107. package/components/tree/tree.yaml +10 -0
  108. package/core/data-stream.d.ts +56 -0
  109. package/core/element.d.ts +10 -0
  110. package/core/index.d.ts +6 -0
  111. package/index.d.ts +9 -2
  112. package/package.json +2 -2
@@ -13,6 +13,16 @@
13
13
  }
14
14
  ],
15
15
  "properties": {
16
+ "autoContrast": {
17
+ "description": "When set, computes the swatch color's OKLab L and switches the label /\ndetail color between light + dark so it remains legible against the\ntile background. Only applies to shape=\"block\" (where the label sits\nON the tile). Uses a 1px canvas probe to handle any CSS color form\n(oklch / hex / hsl / named / var() references).\n",
18
+ "type": "boolean",
19
+ "default": false
20
+ },
21
+ "badge": {
22
+ "description": "Optional marker(s) rendered in the upper-right of the tile. Single value\nOR comma/space-separated list of variants (v0.4.9+ multi-badge support).\nVariants: out-of-gamut (△), p3-only (✦), apca-pass (✓), apca-fail (✗).\nEach pip carries an aria-label so screen readers surface the semantic\n(\"Outside sRGB gamut\", \"Contrast passes APCA\", etc.). Unknown variants\nare silently dropped.\n",
23
+ "type": "string",
24
+ "default": ""
25
+ },
16
26
  "color": {
17
27
  "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.",
18
28
  "type": "string",
@@ -21,11 +31,36 @@
21
31
  "component": {
22
32
  "const": "Swatch"
23
33
  },
34
+ "copyable": {
35
+ "description": "When set, renders an inline copy-to-clipboard button. Defaults to copying [color]; override via [copy-value].",
36
+ "type": "boolean",
37
+ "default": false
38
+ },
39
+ "copyValue": {
40
+ "description": "Override what gets copied when [copyable] is set. Defaults to [color]. Not reflected (color strings are long; attr round-tripping reads poorly).",
41
+ "type": "string",
42
+ "default": ""
43
+ },
44
+ "detail": {
45
+ "description": "Optional secondary line of text rendered below the label. Typically the raw token value (e.g. \"oklch(0.53 0.18 240)\") when the swatch represents a design-token step.",
46
+ "type": "string",
47
+ "default": ""
48
+ },
24
49
  "label": {
25
50
  "description": "Optional label rendered next to (or below, for shape=\"block\") the swatch. Use the default slot for richer content.",
26
51
  "type": "string",
27
52
  "default": ""
28
53
  },
54
+ "selectable": {
55
+ "description": "When set, makes the swatch keyboard-focusable + clickable. Sets role=\"button\" + tabindex=\"0\". Dispatches a \"select\" event on activation (click / Enter / Space).",
56
+ "type": "boolean",
57
+ "default": false
58
+ },
59
+ "selected": {
60
+ "description": "Reflected visual selected state. Pair with [selectable] to make the swatch behave like a radio-style picker. Sets aria-pressed.",
61
+ "type": "boolean",
62
+ "default": false
63
+ },
29
64
  "shape": {
30
65
  "description": "Visual shape — block (filled tile), dot (small circle), square (small filled square), line (solid hairline), dashed (dashed hairline).",
31
66
  "type": "string",
@@ -57,7 +92,25 @@
57
92
  "anti_patterns": [],
58
93
  "category": "display",
59
94
  "composes": [],
60
- "events": {},
95
+ "events": {
96
+ "select": {
97
+ "description": "Fired when a selectable swatch is activated (click / Enter / Space). detail carries the swatch's value, color, and label.",
98
+ "detail": {
99
+ "color": {
100
+ "description": "The raw [color] attribute value.",
101
+ "type": "string"
102
+ },
103
+ "label": {
104
+ "description": "The [label] attribute value.",
105
+ "type": "string"
106
+ },
107
+ "value": {
108
+ "description": "The swatch's effective value — [color] when present, else [label].",
109
+ "type": "string"
110
+ }
111
+ }
112
+ }
113
+ },
61
114
  "examples": [
62
115
  {
63
116
  "description": "A single dot swatch with text label, e.g. as a chart-legend row.",
@@ -94,6 +147,11 @@
94
147
  {
95
148
  "description": "Default, ready for display.",
96
149
  "name": "idle"
150
+ },
151
+ {
152
+ "description": "Reflected when the swatch is in the selected state (pair with [selectable]).",
153
+ "attribute": "selected",
154
+ "name": "selected"
97
155
  }
98
156
  ],
99
157
  "synonyms": {
@@ -107,8 +165,17 @@
107
165
  },
108
166
  "tag": "swatch-ui",
109
167
  "tokens": {
168
+ "--swatch-badge-fg": {
169
+ "description": "Color of the badge symbol. Defaults to chrome-foreground; overridden per-badge variant."
170
+ },
110
171
  "--swatch-color": {
111
172
  "description": "Resolved color of the swatch fill / line. Wins over the [color] attr if set inline."
173
+ },
174
+ "--swatch-detail-fg": {
175
+ "description": "Color of the secondary detail line. Defaults to subtle-foreground."
176
+ },
177
+ "--swatch-select-ring": {
178
+ "description": "Color of the focus + selected ring when [selectable] is set."
112
179
  }
113
180
  },
114
181
  "traits": [],
@@ -31,6 +31,25 @@
31
31
  --swatch-label-size: var(--a-ui-size);
32
32
  --swatch-label-step-size: 10px;
33
33
  --swatch-label-step-mt: 4px;
34
+ --swatch-detail-size: var(--a-ui-xs);
35
+ --swatch-detail-fg: var(--a-fg-subtle);
36
+
37
+ /* ── Badge ── */
38
+ --swatch-badge-size: var(--a-ui-xs);
39
+ --swatch-badge-fg: var(--a-chrome-fg);
40
+ --swatch-badge-bg: var(--a-chrome-bg);
41
+ --swatch-badge-pad: 2px 4px;
42
+ --swatch-badge-radius: var(--a-radius-xs);
43
+
44
+ /* ── Copy button ── */
45
+ --swatch-copy-size: var(--a-space-3);
46
+ --swatch-copy-fg: var(--a-fg-muted);
47
+ --swatch-copy-fg-ok: var(--a-success);
48
+ --swatch-copy-fg-fail: var(--a-warning);
49
+
50
+ /* ── Selectable ring ── */
51
+ --swatch-select-ring: var(--a-accent);
52
+ --swatch-select-ring-width: 2px;
34
53
  }
35
54
 
36
55
  :scope {
@@ -138,4 +157,135 @@
138
157
  --_size: calc(var(--swatch-tile-md) * 1.4);
139
158
  --_block-h: var(--swatch-tile-lg);
140
159
  }
160
+
161
+ /* ═══════ Detail line ═══════
162
+ Second line below the label — typically the raw token value for a
163
+ design-token swatch. For shape="block" sits under the label; for
164
+ non-block shapes is inline (small, muted, after label). */
165
+ :scope > [data-detail] {
166
+ color: var(--swatch-detail-fg);
167
+ font-size: var(--swatch-detail-size);
168
+ font-family: var(--a-font-family-code);
169
+ font-variant-numeric: tabular-nums;
170
+ white-space: nowrap;
171
+ overflow: hidden;
172
+ text-overflow: ellipsis;
173
+ min-width: 0;
174
+ }
175
+ :scope > [data-detail][hidden] { display: none; }
176
+
177
+ :scope[shape="block"] > [data-detail] {
178
+ text-align: center;
179
+ margin-block-start: 2px;
180
+ }
181
+
182
+ /* ═══════ Badge stack ═══════
183
+ Symbol pips (△ / ✦ / ✓ / ✗) in the upper-right of the tile. v0.4.9 §92
184
+ supports multiple simultaneous badges — the container is a flex row;
185
+ each pip is a positioned child with semantic color. */
186
+ :scope > [data-badge] {
187
+ position: absolute;
188
+ top: -4px;
189
+ right: -4px;
190
+ display: inline-flex;
191
+ align-items: center;
192
+ gap: 2px;
193
+ pointer-events: none;
194
+ }
195
+ :scope > [data-badge][hidden] { display: none; }
196
+
197
+ :scope > [data-badge] > [data-badge-variant] {
198
+ display: inline-flex;
199
+ align-items: center;
200
+ justify-content: center;
201
+ min-width: var(--a-space-4);
202
+ height: var(--a-space-4);
203
+ padding: var(--swatch-badge-pad);
204
+ background: var(--swatch-badge-bg);
205
+ color: var(--swatch-badge-fg);
206
+ font-size: var(--swatch-badge-size);
207
+ line-height: 1;
208
+ border-radius: var(--swatch-badge-radius);
209
+ box-shadow: 0 0 0 1px color-mix(in oklab, var(--a-border-subtle) 60%, transparent);
210
+ }
211
+
212
+ /* Make sure the badge has a positioning context — the tile holds it. */
213
+ :scope { position: relative; }
214
+
215
+ /* Badge variants — symbol color encodes semantic */
216
+ :scope > [data-badge] > [data-badge-variant="out-of-gamut"] { color: var(--a-warning); }
217
+ :scope > [data-badge] > [data-badge-variant="p3-only"] { color: var(--a-info); }
218
+ :scope > [data-badge] > [data-badge-variant="apca-pass"] { color: var(--a-success); }
219
+ :scope > [data-badge] > [data-badge-variant="apca-fail"] { color: var(--a-danger); }
220
+
221
+ /* ═══════ Auto-contrast label color ═══════
222
+ When [auto-contrast] is set, JS computes the swatch's OKLab L and
223
+ stamps [data-on-light] or [data-on-dark] on the label. The label then
224
+ swaps fg color so it remains legible against the tile background.
225
+ Only fires for shape="block" (label sits ON the tile); for other
226
+ shapes the label is beside the tile and uses the normal chrome fg. */
227
+ :scope[shape="block"][auto-contrast] > [data-label] {
228
+ position: relative;
229
+ z-index: 1;
230
+ }
231
+ :scope[shape="block"][auto-contrast] > [data-label][data-on-dark] {
232
+ color: var(--a-chrome-light, #fafafa);
233
+ }
234
+ :scope[shape="block"][auto-contrast] > [data-label][data-on-light] {
235
+ color: var(--a-chrome-dark, #111);
236
+ }
237
+ /* Detail line follows the same auto-contrast choice. */
238
+ :scope[shape="block"][auto-contrast] > [data-detail] {
239
+ position: relative;
240
+ z-index: 1;
241
+ }
242
+ :scope[shape="block"][auto-contrast] > [data-label][data-on-dark] ~ [data-detail] {
243
+ color: color-mix(in oklab, var(--a-chrome-light, #fafafa) 80%, transparent);
244
+ }
245
+ :scope[shape="block"][auto-contrast] > [data-label][data-on-light] ~ [data-detail] {
246
+ color: color-mix(in oklab, var(--a-chrome-dark, #111) 70%, transparent);
247
+ }
248
+
249
+ /* ═══════ Copy button ═══════ */
250
+ :scope > [data-copy] {
251
+ appearance: none;
252
+ -webkit-appearance: none;
253
+ background: transparent;
254
+ border: 0;
255
+ padding: 2px 4px;
256
+ margin-inline-start: var(--a-space-1);
257
+ color: var(--swatch-copy-fg);
258
+ font-size: var(--a-ui-sm);
259
+ line-height: 1;
260
+ cursor: pointer;
261
+ border-radius: var(--a-radius-xs);
262
+ transition: color 100ms ease-out, background 100ms ease-out;
263
+ }
264
+ :scope > [data-copy]:hover { color: var(--a-fg); background: var(--a-bg-2); }
265
+ :scope > [data-copy]:focus-visible {
266
+ outline: var(--swatch-select-ring-width) solid var(--swatch-select-ring);
267
+ outline-offset: 1px;
268
+ }
269
+ :scope > [data-copy][hidden] { display: none; }
270
+ :scope > [data-copy][data-copy-state="ok"] { color: var(--swatch-copy-fg-ok); }
271
+ :scope > [data-copy][data-copy-state="fail"] { color: var(--swatch-copy-fg-fail); }
272
+
273
+ /* ═══════ Selectable + selected states ═══════
274
+ [selectable] makes the whole host focusable; ring on :focus-visible.
275
+ [selected] always shows the ring. */
276
+ :scope[selectable] {
277
+ cursor: pointer;
278
+ border-radius: var(--a-radius-sm);
279
+ transition: box-shadow 120ms ease-out;
280
+ }
281
+ :scope[selectable]:focus { outline: none; }
282
+ :scope[selectable]:focus-visible {
283
+ box-shadow: 0 0 0 var(--swatch-select-ring-width) var(--swatch-select-ring);
284
+ }
285
+ :scope[selected] {
286
+ box-shadow: 0 0 0 var(--swatch-select-ring-width) var(--swatch-select-ring);
287
+ }
288
+ :scope[selectable]:hover:not([selected]) {
289
+ box-shadow: 0 0 0 1px color-mix(in oklab, var(--swatch-select-ring) 50%, transparent);
290
+ }
141
291
  }
@@ -17,13 +17,56 @@ spacing demo pages.
17
17
 
18
18
  import { UIElement } from '../../core/element.js';
19
19
 
20
+ export interface SwatchSelectEventDetail {
21
+ /** The raw [color] attribute value. */
22
+ color: string;
23
+ /** The [label] attribute value. */
24
+ label: string;
25
+ /** The swatch's effective value — [color] when present, else [label]. */
26
+ value: string;
27
+ }
28
+
29
+ export type SwatchSelectEvent = CustomEvent<SwatchSelectEventDetail>;
30
+
20
31
  export class UISwatch extends UIElement {
32
+ /** When set, computes the swatch color's OKLab L and switches the label /
33
+ detail color between light + dark so it remains legible against the
34
+ tile background. Only applies to shape="block" (where the label sits
35
+ ON the tile). Uses a 1px canvas probe to handle any CSS color form
36
+ (oklch / hex / hsl / named / var() references).
37
+ */
38
+ autoContrast: boolean;
39
+ /** Optional marker(s) rendered in the upper-right of the tile. Single value
40
+ OR comma/space-separated list of variants (v0.4.9+ multi-badge support).
41
+ Variants: out-of-gamut (△), p3-only (✦), apca-pass (✓), apca-fail (✗).
42
+ Each pip carries an aria-label so screen readers surface the semantic
43
+ ("Outside sRGB gamut", "Contrast passes APCA", etc.). Unknown variants
44
+ are silently dropped.
45
+ */
46
+ badge: string;
21
47
  /** 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. */
22
48
  color: string;
49
+ /** When set, renders an inline copy-to-clipboard button. Defaults to copying [color]; override via [copy-value]. */
50
+ copyable: boolean;
51
+ /** Override what gets copied when [copyable] is set. Defaults to [color]. Not reflected (color strings are long; attr round-tripping reads poorly). */
52
+ copyValue: string;
53
+ /** Optional secondary line of text rendered below the label. Typically the raw token value (e.g. "oklch(0.53 0.18 240)") when the swatch represents a design-token step. */
54
+ detail: string;
23
55
  /** Optional label rendered next to (or below, for shape="block") the swatch. Use the default slot for richer content. */
24
56
  label: string;
57
+ /** When set, makes the swatch keyboard-focusable + clickable. Sets role="button" + tabindex="0". Dispatches a "select" event on activation (click / Enter / Space). */
58
+ selectable: boolean;
59
+ /** Reflected visual selected state. Pair with [selectable] to make the swatch behave like a radio-style picker. Sets aria-pressed. */
60
+ selected: boolean;
25
61
  /** Visual shape — block (filled tile), dot (small circle), square (small filled square), line (solid hairline), dashed (dashed hairline). */
26
62
  shape: 'block' | 'dot' | 'square' | 'line' | 'dashed';
27
63
  /** Size preset — sm / md / lg. Drives the swatch's intrinsic dimensions; lg is reserved for the token-scale demo (40 px tall). */
28
64
  size: 'sm' | 'md' | 'lg';
65
+
66
+ addEventListener<K extends keyof HTMLElementEventMap>(
67
+ type: K,
68
+ listener: (this: UISwatch, ev: HTMLElementEventMap[K]) => unknown,
69
+ options?: boolean | AddEventListenerOptions,
70
+ ): void;
71
+ addEventListener(type: 'select', listener: (ev: SwatchSelectEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
29
72
  }
@@ -41,17 +41,83 @@ props:
41
41
  type: string
42
42
  default: ""
43
43
  reflect: true
44
- events: {}
44
+ detail:
45
+ description: Optional secondary line of text rendered below the label. Typically the raw token value (e.g. "oklch(0.53 0.18 240)") when the swatch represents a design-token step.
46
+ type: string
47
+ default: ""
48
+ reflect: true
49
+ badge:
50
+ description: |
51
+ Optional marker(s) rendered in the upper-right of the tile. Single value
52
+ OR comma/space-separated list of variants (v0.4.9+ multi-badge support).
53
+ Variants: out-of-gamut (△), p3-only (✦), apca-pass (✓), apca-fail (✗).
54
+ Each pip carries an aria-label so screen readers surface the semantic
55
+ ("Outside sRGB gamut", "Contrast passes APCA", etc.). Unknown variants
56
+ are silently dropped.
57
+ type: string
58
+ default: ""
59
+ reflect: true
60
+ copyable:
61
+ description: When set, renders an inline copy-to-clipboard button. Defaults to copying [color]; override via [copy-value].
62
+ type: boolean
63
+ default: false
64
+ reflect: true
65
+ copyValue:
66
+ description: Override what gets copied when [copyable] is set. Defaults to [color]. Not reflected (color strings are long; attr round-tripping reads poorly).
67
+ type: string
68
+ default: ""
69
+ selectable:
70
+ description: When set, makes the swatch keyboard-focusable + clickable. Sets role="button" + tabindex="0". Dispatches a "select" event on activation (click / Enter / Space).
71
+ type: boolean
72
+ default: false
73
+ reflect: true
74
+ selected:
75
+ description: Reflected visual selected state. Pair with [selectable] to make the swatch behave like a radio-style picker. Sets aria-pressed.
76
+ type: boolean
77
+ default: false
78
+ reflect: true
79
+ autoContrast:
80
+ description: |
81
+ When set, computes the swatch color's OKLab L and switches the label /
82
+ detail color between light + dark so it remains legible against the
83
+ tile background. Only applies to shape="block" (where the label sits
84
+ ON the tile). Uses a 1px canvas probe to handle any CSS color form
85
+ (oklch / hex / hsl / named / var() references).
86
+ type: boolean
87
+ default: false
88
+ reflect: true
89
+ events:
90
+ select:
91
+ description: Fired when a selectable swatch is activated (click / Enter / Space). detail carries the swatch's value, color, and label.
92
+ detail:
93
+ value:
94
+ type: string
95
+ description: The swatch's effective value — [color] when present, else [label].
96
+ color:
97
+ type: string
98
+ description: The raw [color] attribute value.
99
+ label:
100
+ type: string
101
+ description: The [label] attribute value.
45
102
  slots:
46
103
  default:
47
104
  description: Optional rich label content. When present, replaces the [label] attribute's text.
48
105
  states:
49
106
  - name: idle
50
107
  description: Default, ready for display.
108
+ - name: selected
109
+ attribute: selected
110
+ description: Reflected when the swatch is in the selected state (pair with [selectable]).
51
111
  traits: []
52
112
  tokens:
53
113
  --swatch-color:
54
114
  description: Resolved color of the swatch fill / line. Wins over the [color] attr if set inline.
115
+ --swatch-badge-fg:
116
+ description: Color of the badge symbol. Defaults to chrome-foreground; overridden per-badge variant.
117
+ --swatch-detail-fg:
118
+ description: Color of the secondary detail line. Defaults to subtle-foreground.
119
+ --swatch-select-ring:
120
+ description: Color of the focus + selected ring when [selectable] is set.
55
121
  a2ui:
56
122
  rules: []
57
123
  anti_patterns: []
@@ -75,13 +75,29 @@
75
75
  ],
76
76
  "events": {
77
77
  "autoplay-pause": {
78
- "description": "Fired on autoplay-pause."
78
+ "description": "Fired on autoplay-pause.",
79
+ "detail": {
80
+ "reason": {
81
+ "description": "Pause reason (\"hover\" or \"focus\").",
82
+ "type": "string"
83
+ }
84
+ }
79
85
  },
80
86
  "autoplay-resume": {
81
87
  "description": "Fired on autoplay-resume."
82
88
  },
83
89
  "change": {
84
- "description": "Fired when the active slide changes. Detail: { index, slide }."
90
+ "description": "Fired when the active slide changes. Detail: { index, slide }.",
91
+ "detail": {
92
+ "index": {
93
+ "description": "New active slide index.",
94
+ "type": "number"
95
+ },
96
+ "slide": {
97
+ "description": "The active slide element.",
98
+ "type": "object"
99
+ }
100
+ }
85
101
  }
86
102
  },
87
103
  "examples": [
@@ -12,9 +12,21 @@
12
12
 
13
13
  import { UIElement } from '../../core/element.js';
14
14
 
15
- export type SwiperAutoplayPauseEvent = CustomEvent<unknown>;
15
+ export interface SwiperAutoplayPauseEventDetail {
16
+ /** Pause reason ("hover" or "focus"). */
17
+ reason: string;
18
+ }
19
+
20
+ export type SwiperAutoplayPauseEvent = CustomEvent<SwiperAutoplayPauseEventDetail>;
16
21
  export type SwiperAutoplayResumeEvent = CustomEvent<unknown>;
17
- export type SwiperChangeEvent = CustomEvent<unknown>;
22
+ export interface SwiperChangeEventDetail {
23
+ /** New active slide index. */
24
+ index: number;
25
+ /** The active slide element. */
26
+ slide: Record<string, unknown>;
27
+ }
28
+
29
+ export type SwiperChangeEvent = CustomEvent<SwiperChangeEventDetail>;
18
30
 
19
31
  export class UISwiper extends UIElement {
20
32
  /** Enable auto-advance */
@@ -53,10 +53,21 @@ props:
53
53
  events:
54
54
  autoplay-pause:
55
55
  description: Fired on autoplay-pause.
56
+ detail:
57
+ reason:
58
+ type: string
59
+ description: Pause reason ("hover" or "focus").
56
60
  autoplay-resume:
57
61
  description: Fired on autoplay-resume.
58
62
  change:
59
63
  description: 'Fired when the active slide changes. Detail: { index, slide }.'
64
+ detail:
65
+ index:
66
+ type: number
67
+ description: New active slide index.
68
+ slide:
69
+ type: object
70
+ description: The active slide element.
60
71
  slots:
61
72
  default:
62
73
  description: Default slot — primary child content.
@@ -93,19 +93,94 @@
93
93
  ],
94
94
  "events": {
95
95
  "cell-click": {
96
- "description": "Fired when a data cell is clicked."
96
+ "description": "Fired when a data cell is clicked. detail carries the cell location + value.",
97
+ "detail": {
98
+ "dataIndex": {
99
+ "description": "Row index in the underlying data array.",
100
+ "type": "number"
101
+ },
102
+ "key": {
103
+ "description": "Column key.",
104
+ "type": "string"
105
+ },
106
+ "row": {
107
+ "description": "Row data object.",
108
+ "type": "object"
109
+ },
110
+ "value": {
111
+ "description": "Cell value (type depends on column)."
112
+ }
113
+ }
114
+ },
115
+ "filter-change": {
116
+ "description": "Fired when an interactive filter row applies / clears. detail.filters is the current filter map.",
117
+ "detail": {
118
+ "filters": {
119
+ "description": "Map of `{ [columnKey]: filterValue }` reflecting active filters.",
120
+ "type": "object"
121
+ }
122
+ }
97
123
  },
98
124
  "page": {
99
- "description": "Fired when the user navigates to a different page."
125
+ "description": "Fired when the user navigates to a different page.",
126
+ "detail": {
127
+ "page": {
128
+ "description": "New active page index (1-based).",
129
+ "type": "number"
130
+ }
131
+ }
100
132
  },
101
133
  "resize": {
102
- "description": "Fired when a column is resized via drag."
134
+ "description": "Fired when a column is resized via drag.",
135
+ "detail": {
136
+ "key": {
137
+ "description": "Column key being resized.",
138
+ "type": "string"
139
+ },
140
+ "width": {
141
+ "description": "New column width in pixels.",
142
+ "type": "number"
143
+ }
144
+ }
145
+ },
146
+ "row-expand": {
147
+ "description": "Fired when an expandable row's chevron is activated. detail.index is the row position; detail.row is the row data.",
148
+ "detail": {
149
+ "index": {
150
+ "description": "Row index in the underlying data array.",
151
+ "type": "number"
152
+ },
153
+ "row": {
154
+ "description": "Row data object.",
155
+ "type": "object"
156
+ }
157
+ }
103
158
  },
104
159
  "select": {
105
- "description": "Fired when row selection changes."
160
+ "description": "Fired when row selection changes. detail.selected is an array of row indices or IDs.",
161
+ "detail": {
162
+ "selected": {
163
+ "description": "Array of selected row indices or IDs (driven by [select-mode]).",
164
+ "type": "array"
165
+ }
166
+ }
106
167
  },
107
168
  "sort": {
108
- "description": "Fired when sort state changes via header click."
169
+ "description": "Fired when sort state changes via header click.",
170
+ "detail": {
171
+ "dir": {
172
+ "description": "Sort direction — \"asc\" / \"desc\" / null (cleared).",
173
+ "type": "string"
174
+ },
175
+ "key": {
176
+ "description": "Column key being sorted.",
177
+ "type": "string"
178
+ },
179
+ "sortState": {
180
+ "description": "Full sort state array (multi-column support).",
181
+ "type": "array"
182
+ }
183
+ }
109
184
  }
110
185
  },
111
186
  "examples": [
@@ -12,11 +12,62 @@
12
12
 
13
13
  import { UIElement } from '../../core/element.js';
14
14
 
15
- export type TableCellClickEvent = CustomEvent<unknown>;
16
- export type TablePageEvent = CustomEvent<unknown>;
17
- export type TableResizeEvent = CustomEvent<unknown>;
18
- export type TableSelectEvent = CustomEvent<unknown>;
19
- export type TableSortEvent = CustomEvent<unknown>;
15
+ export interface TableCellClickEventDetail {
16
+ /** Row index in the underlying data array. */
17
+ dataIndex: number;
18
+ /** Column key. */
19
+ key: string;
20
+ /** Row data object. */
21
+ row: Record<string, unknown>;
22
+ /** Cell value (type depends on column). */
23
+ value: string;
24
+ }
25
+
26
+ export type TableCellClickEvent = CustomEvent<TableCellClickEventDetail>;
27
+ export interface TableFilterChangeEventDetail {
28
+ /** Map of `{ [columnKey]: filterValue }` reflecting active filters. */
29
+ filters: Record<string, unknown>;
30
+ }
31
+
32
+ export type TableFilterChangeEvent = CustomEvent<TableFilterChangeEventDetail>;
33
+ export interface TablePageEventDetail {
34
+ /** New active page index (1-based). */
35
+ page: number;
36
+ }
37
+
38
+ export type TablePageEvent = CustomEvent<TablePageEventDetail>;
39
+ export interface TableResizeEventDetail {
40
+ /** Column key being resized. */
41
+ key: string;
42
+ /** New column width in pixels. */
43
+ width: number;
44
+ }
45
+
46
+ export type TableResizeEvent = CustomEvent<TableResizeEventDetail>;
47
+ export interface TableRowExpandEventDetail {
48
+ /** Row index in the underlying data array. */
49
+ index: number;
50
+ /** Row data object. */
51
+ row: Record<string, unknown>;
52
+ }
53
+
54
+ export type TableRowExpandEvent = CustomEvent<TableRowExpandEventDetail>;
55
+ export interface TableSelectEventDetail {
56
+ /** Array of selected row indices or IDs (driven by [select-mode]). */
57
+ selected: unknown[];
58
+ }
59
+
60
+ export type TableSelectEvent = CustomEvent<TableSelectEventDetail>;
61
+ export interface TableSortEventDetail {
62
+ /** Sort direction — "asc" / "desc" / null (cleared). */
63
+ dir: string;
64
+ /** Column key being sorted. */
65
+ key: string;
66
+ /** Full sort state array (multi-column support). */
67
+ sortState: unknown[];
68
+ }
69
+
70
+ export type TableSortEvent = CustomEvent<TableSortEventDetail>;
20
71
 
21
72
  export class UITable extends UIElement {
22
73
  /** Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, accessor?, format?, render?, sortFn?, filterType?, meta?}. Alternative to declarative <col-def> children. */
@@ -48,8 +99,10 @@ export class UITable extends UIElement {
48
99
  options?: boolean | AddEventListenerOptions,
49
100
  ): void;
50
101
  addEventListener(type: 'cell-click', listener: (ev: TableCellClickEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
102
+ addEventListener(type: 'filter-change', listener: (ev: TableFilterChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
51
103
  addEventListener(type: 'page', listener: (ev: TablePageEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
52
104
  addEventListener(type: 'resize', listener: (ev: TableResizeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
105
+ addEventListener(type: 'row-expand', listener: (ev: TableRowExpandEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
53
106
  addEventListener(type: 'select', listener: (ev: TableSelectEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
54
107
  addEventListener(type: 'sort', listener: (ev: TableSortEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
55
108
  }