@aceshooting/lyra-ui 2.0.0 → 2.1.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 (224) hide show
  1. package/README.md +87 -14
  2. package/custom-elements.json +11555 -5539
  3. package/dist/components/app-rail/app-rail-item.d.ts +30 -0
  4. package/dist/components/app-rail/app-rail-item.js +68 -0
  5. package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
  6. package/dist/components/app-rail/app-rail-item.styles.js +65 -0
  7. package/dist/components/app-rail/app-rail.d.ts +21 -24
  8. package/dist/components/app-rail/app-rail.js +68 -132
  9. package/dist/components/app-rail/app-rail.styles.js +5 -2
  10. package/dist/components/attachment-chip/attachment-chip.d.ts +38 -11
  11. package/dist/components/attachment-chip/attachment-chip.js +73 -29
  12. package/dist/components/attachment-trigger/attachment-trigger.d.ts +13 -0
  13. package/dist/components/attachment-trigger/attachment-trigger.js +13 -1
  14. package/dist/components/attachment-trigger/attachment-trigger.styles.js +28 -6
  15. package/dist/components/chart/bar-chart.js +2 -18
  16. package/dist/components/chart/box-plot.d.ts +25 -1
  17. package/dist/components/chart/box-plot.js +136 -6
  18. package/dist/components/chart/box-plot.styles.js +13 -0
  19. package/dist/components/chart/bubble-chart.js +2 -18
  20. package/dist/components/chart/chart.d.ts +54 -10
  21. package/dist/components/chart/chart.js +182 -39
  22. package/dist/components/chart/doughnut-chart.js +2 -18
  23. package/dist/components/chart/histogram-bin.d.ts +5 -2
  24. package/dist/components/chart/histogram-bin.js +12 -4
  25. package/dist/components/chart/histogram.js +8 -16
  26. package/dist/components/chart/line-chart.js +2 -18
  27. package/dist/components/chart/lite-chart.d.ts +80 -3
  28. package/dist/components/chart/lite-chart.js +250 -53
  29. package/dist/components/chart/pie-chart.js +2 -18
  30. package/dist/components/chart/polar-area-chart.js +2 -18
  31. package/dist/components/chart/radar-chart.js +2 -18
  32. package/dist/components/chart/scatter-chart.js +2 -18
  33. package/dist/components/chat-composer/chat-composer.d.ts +42 -1
  34. package/dist/components/chat-composer/chat-composer.js +84 -3
  35. package/dist/components/chat-composer/chat-composer.styles.js +11 -1
  36. package/dist/components/chat-message/chat-message.d.ts +32 -4
  37. package/dist/components/chat-message/chat-message.js +57 -17
  38. package/dist/components/checkbox/checkbox.d.ts +66 -8
  39. package/dist/components/checkbox/checkbox.js +173 -50
  40. package/dist/components/checkbox/checkbox.styles.js +9 -2
  41. package/dist/components/chip/chip-group.js +8 -2
  42. package/dist/components/chip/chip.js +9 -2
  43. package/dist/components/citation-badge/citation-badge.js +21 -3
  44. package/dist/components/code-block/code-block.d.ts +38 -0
  45. package/dist/components/code-block/code-block.js +72 -7
  46. package/dist/components/code-block/code-loader.d.ts +44 -1
  47. package/dist/components/code-block/code-loader.js +63 -0
  48. package/dist/components/combobox/combobox.d.ts +46 -5
  49. package/dist/components/combobox/combobox.js +175 -35
  50. package/dist/components/combobox/combobox.styles.js +3 -3
  51. package/dist/components/context-meter/context-meter.js +17 -8
  52. package/dist/components/context-meter/context-meter.styles.js +0 -6
  53. package/dist/components/conversation-item/conversation-item.d.ts +13 -16
  54. package/dist/components/conversation-item/conversation-item.js +29 -20
  55. package/dist/components/date-picker/calendar-core.d.ts +24 -0
  56. package/dist/components/date-picker/calendar-core.js +51 -4
  57. package/dist/components/date-picker/date-input.d.ts +77 -10
  58. package/dist/components/date-picker/date-input.js +278 -73
  59. package/dist/components/date-picker/date-picker.d.ts +28 -4
  60. package/dist/components/date-picker/date-picker.js +95 -37
  61. package/dist/components/dialog/confirm.js +3 -6
  62. package/dist/components/dialog/dialog.d.ts +75 -31
  63. package/dist/components/dialog/dialog.js +147 -131
  64. package/dist/components/dialog/dialog.styles.js +46 -2
  65. package/dist/components/dock-panel/dock-panel.d.ts +8 -0
  66. package/dist/components/dock-panel/dock-panel.js +15 -1
  67. package/dist/components/dock-panel/dock-panel.styles.js +15 -1
  68. package/dist/components/document-preview/document-preview.d.ts +15 -7
  69. package/dist/components/document-preview/document-preview.js +29 -13
  70. package/dist/components/empty/empty.d.ts +1 -2
  71. package/dist/components/empty/empty.js +18 -12
  72. package/dist/components/empty/empty.styles.js +0 -3
  73. package/dist/components/export-button/export-button.d.ts +12 -0
  74. package/dist/components/export-button/export-button.js +33 -5
  75. package/dist/components/export-button/export-button.styles.js +5 -1
  76. package/dist/components/file-input/accept.js +2 -0
  77. package/dist/components/file-input/file-input.d.ts +10 -1
  78. package/dist/components/file-input/file-input.js +36 -5
  79. package/dist/components/flag/flag.d.ts +1 -1
  80. package/dist/components/flag/flag.js +15 -1
  81. package/dist/components/flag/flag.styles.js +1 -1
  82. package/dist/components/flag/language-map.d.ts +4 -1
  83. package/dist/components/flag/language-map.js +6 -3
  84. package/dist/components/gauge/gauge.d.ts +10 -1
  85. package/dist/components/gauge/gauge.js +28 -9
  86. package/dist/components/generation-status/generation-status.d.ts +13 -5
  87. package/dist/components/generation-status/generation-status.js +59 -5
  88. package/dist/components/graph/graph.d.ts +37 -3
  89. package/dist/components/graph/graph.js +132 -20
  90. package/dist/components/heatmap/calendar-grid.d.ts +15 -6
  91. package/dist/components/heatmap/calendar-grid.js +17 -6
  92. package/dist/components/heatmap/heatmap-scale.d.ts +5 -1
  93. package/dist/components/heatmap/heatmap-scale.js +8 -2
  94. package/dist/components/heatmap/heatmap.d.ts +166 -25
  95. package/dist/components/heatmap/heatmap.js +372 -89
  96. package/dist/components/json-viewer/json-viewer.d.ts +22 -5
  97. package/dist/components/json-viewer/json-viewer.js +115 -37
  98. package/dist/components/json-viewer/json-viewer.styles.js +2 -1
  99. package/dist/components/kbd/kbd.js +24 -7
  100. package/dist/components/live-region/live-region.d.ts +10 -1
  101. package/dist/components/live-region/live-region.js +42 -6
  102. package/dist/components/map/map.d.ts +24 -1
  103. package/dist/components/map/map.js +89 -24
  104. package/dist/components/markdown/markdown-loader.d.ts +24 -0
  105. package/dist/components/markdown/markdown-loader.js +35 -1
  106. package/dist/components/markdown/markdown.d.ts +46 -8
  107. package/dist/components/markdown/markdown.js +136 -31
  108. package/dist/components/markdown/markdown.styles.js +7 -1
  109. package/dist/components/media-card/media-card.d.ts +25 -17
  110. package/dist/components/media-card/media-card.js +43 -65
  111. package/dist/components/mention-popover/mention-popover.d.ts +4 -1
  112. package/dist/components/mention-popover/mention-popover.js +23 -5
  113. package/dist/components/menu/menu-item.d.ts +32 -3
  114. package/dist/components/menu/menu-item.js +94 -7
  115. package/dist/components/menu/menu-item.styles.js +8 -0
  116. package/dist/components/menu/menu.d.ts +25 -1
  117. package/dist/components/menu/menu.js +99 -3
  118. package/dist/components/menu/menu.styles.js +3 -2
  119. package/dist/components/model-select/model-select.d.ts +48 -3
  120. package/dist/components/model-select/model-select.js +120 -22
  121. package/dist/components/model-select/model-select.styles.js +17 -3
  122. package/dist/components/model-settings-panel/model-settings-panel.d.ts +25 -1
  123. package/dist/components/model-settings-panel/model-settings-panel.js +65 -1
  124. package/dist/components/playback/playback.d.ts +6 -2
  125. package/dist/components/playback/playback.js +72 -29
  126. package/dist/components/playback/playback.styles.js +6 -1
  127. package/dist/components/responsive-panel/responsive-panel.d.ts +29 -16
  128. package/dist/components/responsive-panel/responsive-panel.js +130 -132
  129. package/dist/components/responsive-panel/responsive-panel.styles.js +1 -1
  130. package/dist/components/result-card/result-card.d.ts +8 -2
  131. package/dist/components/result-card/result-card.js +9 -3
  132. package/dist/components/result-card/result-card.styles.js +0 -1
  133. package/dist/components/select/select.d.ts +59 -20
  134. package/dist/components/select/select.js +125 -43
  135. package/dist/components/skeleton/skeleton.d.ts +3 -0
  136. package/dist/components/skeleton/skeleton.js +7 -1
  137. package/dist/components/skeleton/skeleton.styles.js +5 -4
  138. package/dist/components/slider/slider.d.ts +57 -5
  139. package/dist/components/slider/slider.js +195 -80
  140. package/dist/components/source-card/source-card.d.ts +17 -5
  141. package/dist/components/source-card/source-card.js +55 -8
  142. package/dist/components/source-card/source-card.styles.js +1 -1
  143. package/dist/components/source-list/source-list.js +9 -1
  144. package/dist/components/sparkline/sparkline.js +34 -10
  145. package/dist/components/split/split.d.ts +141 -14
  146. package/dist/components/split/split.js +357 -52
  147. package/dist/components/split/split.styles.js +18 -1
  148. package/dist/components/stat/stat.d.ts +10 -4
  149. package/dist/components/stat/stat.js +46 -11
  150. package/dist/components/stream-status/stream-status.d.ts +27 -11
  151. package/dist/components/stream-status/stream-status.js +95 -13
  152. package/dist/components/streaming-text/streaming-text.d.ts +9 -3
  153. package/dist/components/streaming-text/streaming-text.js +25 -10
  154. package/dist/components/streaming-text/streaming-text.styles.js +3 -2
  155. package/dist/components/switch/switch.d.ts +52 -7
  156. package/dist/components/switch/switch.js +111 -40
  157. package/dist/components/switch/switch.styles.js +1 -1
  158. package/dist/components/table/table.d.ts +18 -3
  159. package/dist/components/table/table.js +88 -20
  160. package/dist/components/tabs/tabs.d.ts +23 -0
  161. package/dist/components/tabs/tabs.js +76 -12
  162. package/dist/components/tabs/tabs.styles.js +11 -0
  163. package/dist/components/thinking-panel/thinking-panel.d.ts +3 -1
  164. package/dist/components/thinking-panel/thinking-panel.js +34 -9
  165. package/dist/components/thinking-panel/thinking-panel.styles.js +6 -0
  166. package/dist/components/time-range/time-range.d.ts +59 -2
  167. package/dist/components/time-range/time-range.js +163 -67
  168. package/dist/components/toast/toast-item.d.ts +12 -3
  169. package/dist/components/toast/toast-item.js +90 -53
  170. package/dist/components/toast/toast-item.styles.js +59 -28
  171. package/dist/components/toast/toast.js +17 -5
  172. package/dist/components/toast/toaster.js +10 -1
  173. package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +11 -10
  174. package/dist/components/tool-approval-dialog/tool-approval-dialog.js +50 -124
  175. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +1 -1
  176. package/dist/components/tool-call-chip/tool-call-chip.d.ts +18 -2
  177. package/dist/components/tool-call-chip/tool-call-chip.js +86 -25
  178. package/dist/components/tool-param-form/tool-param-form.d.ts +89 -28
  179. package/dist/components/tool-param-form/tool-param-form.js +350 -106
  180. package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +27 -7
  181. package/dist/components/tool-result-dialog/tool-result-dialog.js +80 -115
  182. package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +1 -1
  183. package/dist/components/tool-result-view/registry.d.ts +0 -8
  184. package/dist/components/tool-result-view/registry.js +7 -2
  185. package/dist/components/tool-result-view/tool-result-view.d.ts +6 -3
  186. package/dist/components/tool-result-view/tool-result-view.js +18 -4
  187. package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +11 -11
  188. package/dist/components/tool-select-dialog/tool-select-dialog.js +44 -133
  189. package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +13 -4
  190. package/dist/components/tree/tree-node.d.ts +4 -1
  191. package/dist/components/tree/tree-node.js +4 -1
  192. package/dist/components/tree/tree.d.ts +17 -8
  193. package/dist/components/tree/tree.js +21 -20
  194. package/dist/components/typing-indicator/typing-indicator.d.ts +12 -2
  195. package/dist/components/typing-indicator/typing-indicator.js +16 -4
  196. package/dist/components/typing-indicator/typing-indicator.styles.js +2 -2
  197. package/dist/components/virtual-list/virtual-list.d.ts +56 -19
  198. package/dist/components/virtual-list/virtual-list.js +184 -38
  199. package/dist/components/virtual-list/virtual-list.styles.js +12 -0
  200. package/dist/components/widget/widget.d.ts +5 -4
  201. package/dist/components/widget/widget.js +54 -120
  202. package/dist/components/widget/widget.styles.js +8 -2
  203. package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
  204. package/dist/components/word-cloud/word-cloud-layout.js +20 -6
  205. package/dist/components/word-cloud/word-cloud.d.ts +22 -2
  206. package/dist/components/word-cloud/word-cloud.js +45 -6
  207. package/dist/components/word-cloud/word-cloud.styles.js +13 -1
  208. package/dist/internal/anchored-validity.d.ts +1 -0
  209. package/dist/internal/anchored-validity.js +86 -0
  210. package/dist/internal/form-associated.d.ts +7 -0
  211. package/dist/internal/form-associated.js +43 -4
  212. package/dist/internal/numbers.d.ts +12 -0
  213. package/dist/internal/numbers.js +26 -0
  214. package/dist/internal/overlay-manager.d.ts +51 -0
  215. package/dist/internal/overlay-manager.js +523 -0
  216. package/dist/internal/positioner.js +27 -3
  217. package/dist/internal/safe-url.d.ts +12 -0
  218. package/dist/internal/safe-url.js +41 -0
  219. package/dist/internal/tokens.styles.js +17 -11
  220. package/dist/lyra.d.ts +5 -2
  221. package/dist/lyra.js +3 -1
  222. package/llms-full.txt +970 -426
  223. package/llms.txt +5 -4
  224. package/package.json +19 -2
@@ -4,11 +4,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { html, svg, nothing } from 'lit';
7
+ import { html, svg, nothing, } from 'lit';
8
8
  import { property, state } from 'lit/decorators.js';
9
9
  import { LyraElement } from '../../internal/lyra-element.js';
10
10
  import { defineElement } from '../../internal/prefix.js';
11
11
  import { place } from '../../internal/positioner.js';
12
+ import { nextId } from '../../internal/a11y.js';
12
13
  import { styles } from './tool-call-chip.styles.js';
13
14
  // Mirrors the shared icon set's viewBox/stroke conventions
14
15
  // (internal/icons.ts's chevronIcon()/closeIcon()/etc.) without adding
@@ -74,6 +75,15 @@ const STATUS_LABEL = {
74
75
  error: 'Error',
75
76
  denied: 'Denied',
76
77
  };
78
+ const STATUS_VALUES = new Set(Object.keys(STATUS_LABEL));
79
+ const statusConverter = {
80
+ fromAttribute(value) {
81
+ return value !== null && STATUS_VALUES.has(value) ? value : 'pending';
82
+ },
83
+ toAttribute(value) {
84
+ return value;
85
+ },
86
+ };
77
87
  /** `820` -> `"820ms"`; `1500` -> `"1.5s"`; `2000` -> `"2s"`. Sub-second
78
88
  * durations are the common case for a single tool call, so they get the
79
89
  * more precise unit; once a call runs a full second or longer, trimming to
@@ -107,7 +117,12 @@ function formatDuration(ms) {
107
117
  * a short preview) shown in a floating tooltip on hover/focus, positioned
108
118
  * with `internal/positioner.js`'s `place()` the same way `<lyra-combobox>`
109
119
  * positions its listbox. No tooltip is shown at all when the slot carries no
110
- * content — hovering an empty chip does nothing.
120
+ * content — hovering an empty chip does nothing. Hover and keyboard focus are
121
+ * tracked as independent reasons to keep the tooltip open (mirrors
122
+ * `<lyra-citation-badge>`'s popover), so releasing one modality while the
123
+ * other is still active doesn't close it, and the trigger button's
124
+ * `aria-describedby` points at the tooltip's id whenever it's open and has
125
+ * content, so the association reaches assistive tech too.
111
126
  *
112
127
  * The `icon` slot overrides the built-in per-status glyph entirely via the
113
128
  * platform's own slot-fallback-content mechanism (`<slot
@@ -141,7 +156,10 @@ export class LyraToolCallChip extends LyraElement {
141
156
  this.name = '';
142
157
  /** Optional grouping label, e.g. `research`. */
143
158
  this.category = '';
144
- /** The call's current lifecycle state — drives the glyph, color, and `status-text`. */
159
+ /**
160
+ * The call's current lifecycle state — drives the glyph, color, and
161
+ * `status-text`. Invalid runtime values use the pending presentation.
162
+ */
145
163
  this.status = 'pending';
146
164
  /** Short human-readable status text, e.g. `Searching web…`. */
147
165
  this.summary = '';
@@ -159,30 +177,50 @@ export class LyraToolCallChip extends LyraElement {
159
177
  // expected to be markup, not a bare text node.
160
178
  this.hasDetailSlot = false;
161
179
  this.tooltipOpen = false;
180
+ this.tooltipId = nextId('tool-call-chip-tooltip');
181
+ // Hover and focus are tracked as independent "keep it open" reasons --
182
+ // mirrors lyra-citation-badge's identical hovering/focused pair for the
183
+ // same hover/focus preview-popover pattern -- so releasing one (e.g. the
184
+ // pointer leaving while the chip still has keyboard focus) doesn't close a
185
+ // tooltip the other modality is still holding open.
186
+ this.hovering = false;
187
+ this.focused = false;
162
188
  this.onDetailSlotChange = (e) => {
163
189
  this.hasDetailSlot = e.target.assignedElements({ flatten: true }).length > 0;
190
+ // The slot can be emptied out from under an already-open tooltip (e.g. a
191
+ // consumer clearing streamed/async preview content) -- nothing left to
192
+ // show, so don't leave an empty tooltip floating open regardless of
193
+ // whether hover/focus is still active.
194
+ if (!this.hasDetailSlot)
195
+ this.hideTooltip();
164
196
  };
165
- this.showTooltip = () => {
166
- if (!this.hasDetailSlot || this.tooltipOpen)
197
+ this.onMouseEnter = () => {
198
+ this.hovering = true;
199
+ this.showTooltip();
200
+ };
201
+ this.onMouseLeave = () => {
202
+ this.hovering = false;
203
+ if (this.focused)
167
204
  return;
168
- this.tooltipOpen = true;
205
+ this.hideTooltip();
206
+ };
207
+ this.onFocus = () => {
208
+ this.focused = true;
209
+ this.showTooltip();
169
210
  };
170
- // Unconditional on blur/mouseleave, with no "did the pointer move into the
171
- // tooltip itself" check -- the default slot is documented as read-only
172
- // preview content (raw args, a short snippet), not an interactive surface
173
- // meant to retain focus/hover of its own, so this stays as simple as a
174
- // native `title` attribute's show/hide instead of adding a second
175
- // pointer-tracking region.
176
- this.hideTooltip = () => {
177
- if (!this.tooltipOpen)
211
+ this.onBlur = () => {
212
+ this.focused = false;
213
+ if (this.hovering)
178
214
  return;
179
- this.tooltipOpen = false;
215
+ this.hideTooltip();
180
216
  };
181
217
  this.onKeyDown = (e) => {
182
218
  // The native <button> already handles Enter/Space activation on its
183
219
  // own -- this only needs to cover dismissing the (non-native) tooltip,
184
220
  // the same Escape-to-close convention every other popup in this library
185
- // follows (see lyra-combobox's onKeyDown).
221
+ // follows (see lyra-combobox's onKeyDown). Unconditional close (not
222
+ // gated on hovering/focused) since Escape is a deliberate dismissal, not
223
+ // transient pointer/focus travel.
186
224
  if (e.key === 'Escape' && this.tooltipOpen) {
187
225
  e.stopPropagation();
188
226
  this.hideTooltip();
@@ -214,11 +252,32 @@ export class LyraToolCallChip extends LyraElement {
214
252
  super.disconnectedCallback();
215
253
  this.cleanupPositioner?.();
216
254
  }
255
+ showTooltip() {
256
+ if (!this.hasDetailSlot || this.tooltipOpen)
257
+ return;
258
+ this.tooltipOpen = true;
259
+ }
260
+ // Called both as the actual (unconditional) close -- from onDetailSlotChange
261
+ // and the Escape handler below, where the tooltip must close regardless of
262
+ // hover/focus state -- and from onMouseLeave/onBlur once each has already
263
+ // confirmed the *other* modality isn't still holding the tooltip open. The
264
+ // default slot is documented as read-only preview content (raw args, a
265
+ // short snippet), not an interactive surface meant to retain focus/hover of
266
+ // its own, so there's no "did the pointer move into the tooltip itself"
267
+ // check needed beyond the hovering/focused pair.
268
+ hideTooltip() {
269
+ if (!this.tooltipOpen)
270
+ return;
271
+ this.tooltipOpen = false;
272
+ }
273
+ get effectiveStatus() {
274
+ return STATUS_VALUES.has(this.status) ? this.status : 'pending';
275
+ }
217
276
  get accessibleLabel() {
218
277
  const parts = [this.name || 'Tool call'];
219
278
  if (this.summary)
220
279
  parts.push(this.summary);
221
- parts.push(STATUS_LABEL[this.status]);
280
+ parts.push(STATUS_LABEL[this.effectiveStatus]);
222
281
  if (this.durationMs != null && Number.isFinite(this.durationMs))
223
282
  parts.push(formatDuration(this.durationMs));
224
283
  return parts.join(' — ');
@@ -227,20 +286,22 @@ export class LyraToolCallChip extends LyraElement {
227
286
  const hasCategory = this.category.length > 0;
228
287
  const hasSummary = this.summary.length > 0;
229
288
  const hasDuration = this.durationMs != null && Number.isFinite(this.durationMs);
289
+ const status = this.effectiveStatus;
230
290
  return html `
231
291
  <button
232
292
  part="base"
233
293
  type="button"
234
294
  aria-label=${this.getAttribute('aria-label') || this.accessibleLabel}
295
+ aria-describedby=${this.hasDetailSlot && this.tooltipOpen ? this.tooltipId : nothing}
235
296
  @click=${this.onClick}
236
- @mouseenter=${this.showTooltip}
237
- @mouseleave=${this.hideTooltip}
238
- @focus=${this.showTooltip}
239
- @blur=${this.hideTooltip}
297
+ @mouseenter=${this.onMouseEnter}
298
+ @mouseleave=${this.onMouseLeave}
299
+ @focus=${this.onFocus}
300
+ @blur=${this.onBlur}
240
301
  @keydown=${this.onKeyDown}
241
302
  >
242
303
  <span part="icon" aria-hidden="true">
243
- <slot name="icon">${this.icon ? this.icon : STATUS_ICON[this.status]()}</slot>
304
+ <slot name="icon">${this.icon ? this.icon : STATUS_ICON[status]()}</slot>
244
305
  </span>
245
306
  <span part="label">
246
307
  <span part="category" ?hidden=${!hasCategory}>${this.category}</span>
@@ -248,11 +309,11 @@ export class LyraToolCallChip extends LyraElement {
248
309
  <span part="summary" ?hidden=${!hasSummary}>${this.summary}</span>
249
310
  </span>
250
311
  <span part="meta">
251
- <span part="status-text">${STATUS_LABEL[this.status]}</span>
312
+ <span part="status-text">${STATUS_LABEL[status]}</span>
252
313
  <span part="duration" ?hidden=${!hasDuration}>${hasDuration ? formatDuration(this.durationMs) : nothing}</span>
253
314
  </span>
254
315
  </button>
255
- <div part="tooltip" role="tooltip" ?hidden=${!this.tooltipOpen}>
316
+ <div part="tooltip" id=${this.tooltipId} role="tooltip" ?hidden=${!this.tooltipOpen}>
256
317
  <slot @slotchange=${this.onDetailSlotChange}></slot>
257
318
  </div>
258
319
  `;
@@ -265,7 +326,7 @@ __decorate([
265
326
  property()
266
327
  ], LyraToolCallChip.prototype, "category", void 0);
267
328
  __decorate([
268
- property({ reflect: true })
329
+ property({ reflect: true, converter: statusConverter })
269
330
  ], LyraToolCallChip.prototype, "status", void 0);
270
331
  __decorate([
271
332
  property()
@@ -5,6 +5,7 @@ import '../combobox/option.js';
5
5
  import '../checkbox/checkbox.js';
6
6
  /** The four leaf property types this phase's flat-schema renderer understands. */
7
7
  export type ToolParamFormPropertyType = 'string' | 'number' | 'integer' | 'boolean';
8
+ export type ToolParamFormPrimitive = string | number | boolean;
8
9
  /**
9
10
  * One `schema.properties` entry. Deliberately shallow — see the class doc for
10
11
  * the full scope limitation this type encodes.
@@ -19,6 +20,8 @@ export interface ToolParamFormProperty {
19
20
  title?: string;
20
21
  /** Pre-filled value used whenever `value` doesn't already have this key. */
21
22
  default?: unknown;
23
+ /** Exact primitive value required when the property is present. */
24
+ const?: ToolParamFormPrimitive;
22
25
  }
23
26
  /**
24
27
  * The (intentionally flat) JSON Schema subset this component can render:
@@ -38,18 +41,21 @@ export interface ToolParamFormSchema {
38
41
  *
39
42
  * **Scope limitation (intentional, not accidental):** this phase only
40
43
  * understands a *flat* object schema — every `properties` entry must be
41
- * `'string'`, `'number'`, `'integer'`, `'boolean'`, or a string `enum`.
42
- * Nested objects, arrays, `oneOf`/`anyOf`/`allOf`, `$ref`, and any other
43
- * JSON Schema keyword are not read. A full JSON-Schema-to-form renderer is
44
+ * `'string'`, `'number'`, `'integer'`, `'boolean'`, or a string `enum`;
45
+ * primitive `const` is also enforced. Nested objects, arrays,
46
+ * `oneOf`/`anyOf`/`allOf`, `$ref`, constraints such as `minLength`/`minimum`,
47
+ * and schema-valued `additionalProperties` are not read. A full
48
+ * JSON-Schema-to-form renderer is
44
49
  * out of scope for this component; a property whose `type` isn't one of the
45
- * four above renders a visible "Unsupported field type" note instead of
46
- * silently dropping it or throwing.
50
+ * four above renders a visible "Unsupported field type" note and marks the
51
+ * form invalid instead of silently dropping it or throwing.
47
52
  *
48
53
  * Fields render in `Object.keys(schema.properties)` order (insertion order,
49
54
  * which is reliable for a plain object's string keys). A field's label is
50
55
  * `title ?? ` the property key; `description` renders as helper text below
51
- * the control; a key listed in `required` gets a visible `*` and the
52
- * underlying control's own `required` wiring.
56
+ * the control; a key listed in `required` gets a visible `*`. The outer
57
+ * component owns validation because JSON Schema `required` means property
58
+ * presence, unlike HTML controls' nonempty/must-check semantics.
53
59
  *
54
60
  * This component owns no Submit/Cancel/Approve chrome — a consumer composes
55
61
  * it inside their own dialog (e.g. a tool-approval dialog) and reads
@@ -64,7 +70,9 @@ export interface ToolParamFormSchema {
64
70
  * uncontrolled `<input placeholder>` not writing to `.value`, and means the
65
71
  * very first `lyra-input` a consumer receives already carries every default
66
72
  * resolved, so round-tripping `e.detail.value` back into `.value` converges
67
- * after one edit.
73
+ * after one edit. JSON Schema defines `default` as an annotation; this form
74
+ * renderer deliberately materializes it before validation and submission,
75
+ * so a valid default can satisfy `required` here.
68
76
  *
69
77
  * Optional native `<form>` participation is implemented via `ElementInternals`
70
78
  * attached directly (this component's value is a whole object, not a plain
@@ -78,55 +86,108 @@ export interface ToolParamFormSchema {
78
86
  * @event lyra-input - A field's value changed. `detail: { value }` — the
79
87
  * full current value object (every property, defaults resolved), not just
80
88
  * the field that changed.
81
- * @event lyra-validity-change - Overall validity changed (a required field
82
- * became empty/non-empty). `detail: { valid: boolean; errors: Record<string, string> }`.
89
+ * @event lyra-validity-change - Overall validity or field errors changed.
90
+ * `detail: { valid: boolean; errors: Record<string, string> }`.
83
91
  * @csspart base - The outer wrapper around all fields.
84
92
  * @csspart field - One property's wrapper (label + control + description + error).
85
93
  * @csspart label - A field's label.
86
94
  * @csspart description - A field's helper text, from `schema.description`.
87
- * @csspart error - A field's inline validation message (only rendered once the field has been visited).
95
+ * @csspart error - A field-level or form-level validation message.
88
96
  */
89
97
  export declare class LyraToolParamForm extends LyraElement {
90
98
  static formAssociated: boolean;
91
99
  static styles: import("lit").CSSResultGroup[];
92
- schema: ToolParamFormSchema;
93
- value: Record<string, unknown>;
94
- /** Submission key for the optional native `<form>` participation — see the class doc. */
95
- name: string;
96
- disabled: boolean;
100
+ static properties: {
101
+ name: {
102
+ reflect: boolean;
103
+ noAccessor: boolean;
104
+ };
105
+ schema: {
106
+ attribute: boolean;
107
+ noAccessor: boolean;
108
+ };
109
+ value: {
110
+ attribute: boolean;
111
+ noAccessor: boolean;
112
+ };
113
+ disabled: {
114
+ type: BooleanConstructor;
115
+ reflect: boolean;
116
+ noAccessor: boolean;
117
+ };
118
+ };
97
119
  private _errors;
120
+ private _formError;
121
+ private showFormError;
98
122
  private touchedFields;
99
123
  private internals;
124
+ private validityController;
100
125
  private baseId;
126
+ private _fieldsetDisabled;
127
+ private _name;
128
+ private _schema;
129
+ private _value;
130
+ private _effectiveValue;
131
+ private _validityFlags;
132
+ private _disabled;
101
133
  private lastValidityKey;
102
134
  constructor();
135
+ get form(): HTMLFormElement | null;
136
+ get labels(): NodeList;
137
+ get validity(): ValidityState;
138
+ get validationMessage(): string;
139
+ get willValidate(): boolean;
140
+ private firstInvalidField;
103
141
  connectedCallback(): void;
104
142
  /** `value`, with any property missing from it filled in from `schema`'s own `default` — see the class doc. */
105
143
  get effectiveValue(): Record<string, unknown>;
144
+ private get schemaProperties();
145
+ private get requiredKeys();
146
+ private resolveEffectiveValue;
147
+ get schema(): ToolParamFormSchema;
148
+ set schema(next: ToolParamFormSchema);
149
+ get value(): Record<string, unknown>;
150
+ set value(next: Record<string, unknown>);
151
+ /** Submission key for the optional native `<form>` participation, reflected synchronously. */
152
+ get name(): string;
153
+ set name(next: string);
154
+ get disabled(): boolean;
155
+ set disabled(next: boolean);
156
+ /** Whether the form is disabled explicitly or by an ancestor fieldset. */
157
+ get effectiveDisabled(): boolean;
106
158
  /**
107
- * The current per-field validation errors (`{ [propertyKey]: message }`),
108
- * required-and-empty only mirrors the last `lyra-validity-change`
109
- * event's `errors`. Independent of which fields have been visited; a
110
- * consumer wanting the visited-only, screen-reader-announced subset
111
- * should read the rendered `[part="error"]` elements instead.
159
+ * The current per-field validation errors (`{ [propertyKey]: message }`)
160
+ * required presence, primitive type, integer, enum, const, or unsupported
161
+ * type — mirrors the last `lyra-validity-change` event's `errors`.
162
+ * Independent of which fields have been visited; a consumer wanting the
163
+ * visited-only, screen-reader-announced subset should read the rendered
164
+ * `[part="error"]` elements instead.
112
165
  */
113
166
  get errors(): Record<string, string>;
114
- /** The current per-field validation errors (required-and-empty only), independent of `touchedFields`. */
115
- private computeErrors;
116
- /** Non-mutating validity check — unlike `reportValidity()`, never reveals inline errors. */
167
+ /** A schema-wide or JSON-serialization error that cannot be assigned to one field. */
168
+ get formError(): string;
169
+ /**
170
+ * Computes the supported flat JSON Schema subset against the exact value
171
+ * that will be submitted. Defaults are already materialized in `effective`.
172
+ */
173
+ private computeValidation;
174
+ /** Resynchronizes validity without revealing inline errors. */
117
175
  checkValidity(): boolean;
118
176
  /**
119
- * Reveals inline errors for every currently-invalid required field (as if
120
- * each had been visited) and returns overall validity — the hook a
177
+ * Reveals every current field/root error (as if each field had been
178
+ * visited) and returns overall validity — the hook a
121
179
  * consumer's own Submit/Approve button should call right before acting,
122
180
  * mirroring a native `<form>`'s `reportValidity()`.
123
181
  */
124
182
  reportValidity(): boolean;
125
183
  formResetCallback(): void;
184
+ formStateRestoreCallback(state: string | File | FormData | null, _mode?: 'restore' | 'autocomplete'): void;
126
185
  formDisabledCallback(disabled: boolean): void;
127
- protected willUpdate(changed: PropertyValues): void;
128
- /** Pushes `effectiveValue`/`errors` into `ElementInternals` — see the class doc's form-participation note. */
186
+ private schemaShapeError;
187
+ private serializeEffectiveValue;
188
+ /** Pushes the already-computed snapshot into `ElementInternals`. */
129
189
  private syncInternals;
190
+ private syncFormState;
130
191
  protected updated(changed: PropertyValues): void;
131
192
  private setFieldValue;
132
193
  private markTouched;