@aceshooting/lyra-ui 1.1.0 → 2.0.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 (335) hide show
  1. package/README.md +12 -1
  2. package/custom-elements.json +21460 -8489
  3. package/dist/components/app-rail/app-rail.d.ts +171 -0
  4. package/dist/components/app-rail/app-rail.js +483 -0
  5. package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
  6. package/dist/components/app-rail/app-rail.styles.js +125 -0
  7. package/dist/components/attachment-chip/attachment-chip.d.ts +114 -0
  8. package/dist/components/attachment-chip/attachment-chip.js +312 -0
  9. package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
  10. package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
  11. package/dist/components/attachment-trigger/attachment-trigger.d.ts +83 -0
  12. package/dist/components/attachment-trigger/attachment-trigger.js +258 -0
  13. package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
  14. package/dist/components/attachment-trigger/attachment-trigger.styles.js +68 -0
  15. package/dist/components/chart/box-plot.js +11 -1
  16. package/dist/components/chart/chart-loader.d.ts +44 -13
  17. package/dist/components/chart/chart-loader.js +65 -18
  18. package/dist/components/chart/chart.d.ts +12 -2
  19. package/dist/components/chart/chart.js +121 -14
  20. package/dist/components/chart/histogram-bin.d.ts +4 -1
  21. package/dist/components/chart/histogram-bin.js +24 -14
  22. package/dist/components/chart/lite-chart.d.ts +63 -0
  23. package/dist/components/chart/lite-chart.js +181 -23
  24. package/dist/components/chart/lite-chart.styles.js +9 -0
  25. package/dist/components/chat-composer/chat-composer.d.ts +92 -0
  26. package/dist/components/chat-composer/chat-composer.js +285 -0
  27. package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
  28. package/dist/components/chat-composer/chat-composer.styles.js +135 -0
  29. package/dist/components/chat-message/chat-message.d.ts +113 -0
  30. package/dist/components/chat-message/chat-message.js +291 -0
  31. package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
  32. package/dist/components/chat-message/chat-message.styles.js +203 -0
  33. package/dist/components/checkbox/checkbox.d.ts +59 -0
  34. package/dist/components/checkbox/checkbox.js +230 -0
  35. package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
  36. package/dist/components/checkbox/checkbox.styles.js +70 -0
  37. package/dist/components/chip/chip-group.d.ts +56 -0
  38. package/dist/components/chip/chip-group.js +124 -0
  39. package/dist/components/chip/chip-group.styles.d.ts +1 -0
  40. package/dist/components/chip/chip-group.styles.js +57 -0
  41. package/dist/components/chip/chip.d.ts +64 -0
  42. package/dist/components/chip/chip.js +115 -0
  43. package/dist/components/chip/chip.styles.d.ts +1 -0
  44. package/dist/components/chip/chip.styles.js +115 -0
  45. package/dist/components/citation-badge/citation-badge.d.ts +113 -0
  46. package/dist/components/citation-badge/citation-badge.js +300 -0
  47. package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
  48. package/dist/components/citation-badge/citation-badge.styles.js +96 -0
  49. package/dist/components/code-block/code-block.d.ts +89 -0
  50. package/dist/components/code-block/code-block.js +317 -0
  51. package/dist/components/code-block/code-block.styles.d.ts +1 -0
  52. package/dist/components/code-block/code-block.styles.js +187 -0
  53. package/dist/components/code-block/code-loader.d.ts +44 -0
  54. package/dist/components/code-block/code-loader.js +79 -0
  55. package/dist/components/combobox/combobox.d.ts +19 -1
  56. package/dist/components/combobox/combobox.js +84 -14
  57. package/dist/components/combobox/option.d.ts +5 -1
  58. package/dist/components/combobox/option.js +35 -0
  59. package/dist/components/context-meter/context-meter.d.ts +53 -0
  60. package/dist/components/context-meter/context-meter.js +150 -0
  61. package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
  62. package/dist/components/context-meter/context-meter.styles.js +120 -0
  63. package/dist/components/conversation-item/conversation-item.d.ts +128 -0
  64. package/dist/components/conversation-item/conversation-item.js +322 -0
  65. package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
  66. package/dist/components/conversation-item/conversation-item.styles.js +155 -0
  67. package/dist/components/date-picker/date-input.d.ts +24 -0
  68. package/dist/components/date-picker/date-input.js +134 -22
  69. package/dist/components/date-picker/date-picker.d.ts +7 -0
  70. package/dist/components/date-picker/date-picker.js +85 -16
  71. package/dist/components/dialog/confirm.d.ts +40 -0
  72. package/dist/components/dialog/confirm.js +79 -0
  73. package/dist/components/dialog/dialog.d.ts +85 -0
  74. package/dist/components/dialog/dialog.js +272 -0
  75. package/dist/components/dialog/dialog.styles.d.ts +1 -0
  76. package/dist/components/dialog/dialog.styles.js +52 -0
  77. package/dist/components/dock-panel/dock-panel.d.ts +134 -0
  78. package/dist/components/dock-panel/dock-panel.js +345 -0
  79. package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
  80. package/dist/components/dock-panel/dock-panel.styles.js +145 -0
  81. package/dist/components/document-preview/document-preview.d.ts +135 -0
  82. package/dist/components/document-preview/document-preview.js +372 -0
  83. package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
  84. package/dist/components/document-preview/document-preview.styles.js +191 -0
  85. package/dist/components/export-button/csv.js +1 -1
  86. package/dist/components/export-button/export-button.js +2 -0
  87. package/dist/components/flag/flag.d.ts +42 -5
  88. package/dist/components/flag/flag.js +70 -3
  89. package/dist/components/gauge/gauge.js +19 -10
  90. package/dist/components/generation-status/generation-status.d.ts +109 -0
  91. package/dist/components/generation-status/generation-status.js +273 -0
  92. package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
  93. package/dist/components/generation-status/generation-status.styles.js +84 -0
  94. package/dist/components/heatmap/calendar-grid.d.ts +4 -1
  95. package/dist/components/heatmap/calendar-grid.js +25 -12
  96. package/dist/components/heatmap/heatmap-scale.d.ts +6 -0
  97. package/dist/components/heatmap/heatmap-scale.js +7 -1
  98. package/dist/components/heatmap/heatmap.d.ts +89 -3
  99. package/dist/components/heatmap/heatmap.js +158 -29
  100. package/dist/components/json-viewer/json-viewer.d.ts +53 -0
  101. package/dist/components/json-viewer/json-viewer.js +283 -0
  102. package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
  103. package/dist/components/json-viewer/json-viewer.styles.js +176 -0
  104. package/dist/components/kbd/kbd.d.ts +77 -0
  105. package/dist/components/kbd/kbd.js +214 -0
  106. package/dist/components/kbd/kbd.styles.d.ts +1 -0
  107. package/dist/components/kbd/kbd.styles.js +52 -0
  108. package/dist/components/live-region/live-region.d.ts +81 -0
  109. package/dist/components/live-region/live-region.js +153 -0
  110. package/dist/components/live-region/live-region.styles.d.ts +1 -0
  111. package/dist/components/live-region/live-region.styles.js +10 -0
  112. package/dist/components/map/map.d.ts +8 -6
  113. package/dist/components/map/map.js +44 -8
  114. package/dist/components/markdown/markdown-loader.d.ts +34 -0
  115. package/dist/components/markdown/markdown-loader.js +43 -0
  116. package/dist/components/markdown/markdown.d.ts +81 -0
  117. package/dist/components/markdown/markdown.js +284 -0
  118. package/dist/components/markdown/markdown.styles.d.ts +1 -0
  119. package/dist/components/markdown/markdown.styles.js +82 -0
  120. package/dist/components/media-card/media-card.d.ts +122 -0
  121. package/dist/components/media-card/media-card.js +295 -0
  122. package/dist/components/media-card/media-card.styles.d.ts +1 -0
  123. package/dist/components/media-card/media-card.styles.js +132 -0
  124. package/dist/components/mention-popover/mention-popover.d.ts +200 -0
  125. package/dist/components/mention-popover/mention-popover.js +475 -0
  126. package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
  127. package/dist/components/mention-popover/mention-popover.styles.js +101 -0
  128. package/dist/components/menu/menu-item.d.ts +62 -0
  129. package/dist/components/menu/menu-item.js +119 -0
  130. package/dist/components/menu/menu-item.styles.d.ts +1 -0
  131. package/dist/components/menu/menu-item.styles.js +67 -0
  132. package/dist/components/menu/menu.d.ts +143 -0
  133. package/dist/components/menu/menu.js +365 -0
  134. package/dist/components/menu/menu.styles.d.ts +1 -0
  135. package/dist/components/menu/menu.styles.js +66 -0
  136. package/dist/components/model-select/model-select.d.ts +125 -0
  137. package/dist/components/model-select/model-select.js +490 -0
  138. package/dist/components/model-select/model-select.styles.d.ts +1 -0
  139. package/dist/components/model-select/model-select.styles.js +189 -0
  140. package/dist/components/model-settings-panel/model-settings-panel.d.ts +69 -0
  141. package/dist/components/model-settings-panel/model-settings-panel.js +145 -0
  142. package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
  143. package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
  144. package/dist/components/playback/playback.d.ts +13 -1
  145. package/dist/components/playback/playback.js +47 -14
  146. package/dist/components/responsive-panel/responsive-panel.d.ts +150 -0
  147. package/dist/components/responsive-panel/responsive-panel.js +365 -0
  148. package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
  149. package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
  150. package/dist/components/result-card/result-card.d.ts +44 -0
  151. package/dist/components/result-card/result-card.js +83 -0
  152. package/dist/components/result-card/result-card.styles.d.ts +1 -0
  153. package/dist/components/result-card/result-card.styles.js +50 -0
  154. package/dist/components/result-card/result-field.d.ts +36 -0
  155. package/dist/components/result-card/result-field.js +87 -0
  156. package/dist/components/result-card/result-field.styles.d.ts +1 -0
  157. package/dist/components/result-card/result-field.styles.js +32 -0
  158. package/dist/components/select/select.d.ts +45 -1
  159. package/dist/components/select/select.js +114 -17
  160. package/dist/components/select/select.styles.js +26 -2
  161. package/dist/components/slider/slider.d.ts +89 -0
  162. package/dist/components/slider/slider.js +352 -0
  163. package/dist/components/slider/slider.styles.d.ts +1 -0
  164. package/dist/components/slider/slider.styles.js +87 -0
  165. package/dist/components/source-card/source-card.d.ts +92 -0
  166. package/dist/components/source-card/source-card.js +148 -0
  167. package/dist/components/source-card/source-card.styles.d.ts +1 -0
  168. package/dist/components/source-card/source-card.styles.js +69 -0
  169. package/dist/components/source-list/source-list.d.ts +63 -0
  170. package/dist/components/source-list/source-list.js +122 -0
  171. package/dist/components/source-list/source-list.styles.d.ts +1 -0
  172. package/dist/components/source-list/source-list.styles.js +59 -0
  173. package/dist/components/sparkline/sparkline.js +27 -13
  174. package/dist/components/split/split.d.ts +93 -1
  175. package/dist/components/split/split.js +284 -15
  176. package/dist/components/split/split.styles.js +30 -0
  177. package/dist/components/stat/stat.d.ts +22 -1
  178. package/dist/components/stat/stat.js +49 -3
  179. package/dist/components/stat/stat.styles.js +20 -0
  180. package/dist/components/stream-status/stream-status.d.ts +110 -0
  181. package/dist/components/stream-status/stream-status.js +210 -0
  182. package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
  183. package/dist/components/stream-status/stream-status.styles.js +103 -0
  184. package/dist/components/streaming-text/streaming-text.d.ts +98 -0
  185. package/dist/components/streaming-text/streaming-text.js +209 -0
  186. package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
  187. package/dist/components/streaming-text/streaming-text.styles.js +62 -0
  188. package/dist/components/switch/switch.d.ts +58 -0
  189. package/dist/components/switch/switch.js +179 -0
  190. package/dist/components/switch/switch.styles.d.ts +1 -0
  191. package/dist/components/switch/switch.styles.js +75 -0
  192. package/dist/components/table/table.d.ts +73 -4
  193. package/dist/components/table/table.js +169 -20
  194. package/dist/components/table/table.styles.js +6 -1
  195. package/dist/components/tabs/tabs.d.ts +51 -0
  196. package/dist/components/tabs/tabs.js +190 -0
  197. package/dist/components/tabs/tabs.styles.d.ts +1 -0
  198. package/dist/components/tabs/tabs.styles.js +63 -0
  199. package/dist/components/thinking-panel/thinking-panel.d.ts +121 -0
  200. package/dist/components/thinking-panel/thinking-panel.js +235 -0
  201. package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
  202. package/dist/components/thinking-panel/thinking-panel.styles.js +117 -0
  203. package/dist/components/toast/toast-item.d.ts +1 -0
  204. package/dist/components/toast/toast-item.js +31 -6
  205. package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +130 -0
  206. package/dist/components/tool-approval-dialog/tool-approval-dialog.js +403 -0
  207. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
  208. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
  209. package/dist/components/tool-call-chip/tool-call-chip.d.ts +89 -0
  210. package/dist/components/tool-call-chip/tool-call-chip.js +288 -0
  211. package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
  212. package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
  213. package/dist/components/tool-param-form/tool-param-form.d.ts +145 -0
  214. package/dist/components/tool-param-form/tool-param-form.js +366 -0
  215. package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
  216. package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
  217. package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +102 -0
  218. package/dist/components/tool-result-dialog/tool-result-dialog.js +393 -0
  219. package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
  220. package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
  221. package/dist/components/tool-result-view/registry.d.ts +81 -0
  222. package/dist/components/tool-result-view/registry.js +84 -0
  223. package/dist/components/tool-result-view/tool-result-view.d.ts +55 -0
  224. package/dist/components/tool-result-view/tool-result-view.js +138 -0
  225. package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
  226. package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
  227. package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
  228. package/dist/components/tool-select-dialog/tool-select-dialog.js +439 -0
  229. package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
  230. package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +182 -0
  231. package/dist/components/tree/tree-node.d.ts +11 -2
  232. package/dist/components/tree/tree-node.js +16 -6
  233. package/dist/components/tree/tree.d.ts +8 -2
  234. package/dist/components/tree/tree.js +18 -11
  235. package/dist/components/typing-indicator/typing-indicator.d.ts +60 -0
  236. package/dist/components/typing-indicator/typing-indicator.js +96 -0
  237. package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
  238. package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
  239. package/dist/components/virtual-list/virtual-list.d.ts +173 -0
  240. package/dist/components/virtual-list/virtual-list.js +461 -0
  241. package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
  242. package/dist/components/virtual-list/virtual-list.styles.js +44 -0
  243. package/dist/components/widget/widget.d.ts +10 -0
  244. package/dist/components/widget/widget.js +24 -1
  245. package/dist/components/widget/widget.styles.js +9 -2
  246. package/dist/components/word-cloud/word-cloud-layout.js +14 -1
  247. package/dist/components/word-cloud/word-cloud.d.ts +6 -0
  248. package/dist/components/word-cloud/word-cloud.js +25 -14
  249. package/dist/components/word-cloud/word-cloud.styles.js +4 -2
  250. package/dist/internal/announcer.d.ts +57 -0
  251. package/dist/internal/announcer.js +71 -0
  252. package/dist/internal/form-associated.d.ts +1 -0
  253. package/dist/internal/form-associated.js +55 -11
  254. package/dist/internal/group-by-recency.d.ts +50 -0
  255. package/dist/internal/group-by-recency.js +80 -0
  256. package/dist/internal/rtl.d.ts +23 -0
  257. package/dist/internal/rtl.js +28 -0
  258. package/dist/internal/scroll-lock.d.ts +10 -5
  259. package/dist/internal/scroll-lock.js +30 -14
  260. package/dist/internal/tokens.styles.js +6 -0
  261. package/dist/lyra.d.ts +130 -31
  262. package/dist/lyra.js +94 -26
  263. package/llms-full.txt +3921 -32
  264. package/llms.txt +16 -1
  265. package/package.json +23 -5
  266. package/dist/components/chart/bar-chart.stories.d.ts +0 -5
  267. package/dist/components/chart/bar-chart.stories.js +0 -20
  268. package/dist/components/chart/box-plot.stories.d.ts +0 -5
  269. package/dist/components/chart/box-plot.stories.js +0 -29
  270. package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
  271. package/dist/components/chart/bubble-chart.stories.js +0 -26
  272. package/dist/components/chart/chart.stories.d.ts +0 -32
  273. package/dist/components/chart/chart.stories.js +0 -141
  274. package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
  275. package/dist/components/chart/doughnut-chart.stories.js +0 -26
  276. package/dist/components/chart/histogram.stories.d.ts +0 -5
  277. package/dist/components/chart/histogram.stories.js +0 -17
  278. package/dist/components/chart/line-chart.stories.d.ts +0 -22
  279. package/dist/components/chart/line-chart.stories.js +0 -99
  280. package/dist/components/chart/lite-chart.stories.d.ts +0 -12
  281. package/dist/components/chart/lite-chart.stories.js +0 -98
  282. package/dist/components/chart/pie-chart.stories.d.ts +0 -5
  283. package/dist/components/chart/pie-chart.stories.js +0 -26
  284. package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
  285. package/dist/components/chart/polar-area-chart.stories.js +0 -20
  286. package/dist/components/chart/radar-chart.stories.d.ts +0 -5
  287. package/dist/components/chart/radar-chart.stories.js +0 -20
  288. package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
  289. package/dist/components/chart/scatter-chart.stories.js +0 -31
  290. package/dist/components/combobox/combobox.stories.d.ts +0 -24
  291. package/dist/components/combobox/combobox.stories.js +0 -102
  292. package/dist/components/date-picker/date-input.stories.d.ts +0 -10
  293. package/dist/components/date-picker/date-input.stories.js +0 -48
  294. package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
  295. package/dist/components/date-picker/date-picker.stories.js +0 -25
  296. package/dist/components/empty/empty.stories.d.ts +0 -7
  297. package/dist/components/empty/empty.stories.js +0 -34
  298. package/dist/components/export-button/export-button.stories.d.ts +0 -7
  299. package/dist/components/export-button/export-button.stories.js +0 -37
  300. package/dist/components/file-input/file-input.stories.d.ts +0 -7
  301. package/dist/components/file-input/file-input.stories.js +0 -19
  302. package/dist/components/flag/flag.stories.d.ts +0 -5
  303. package/dist/components/flag/flag.stories.js +0 -17
  304. package/dist/components/gauge/gauge.stories.d.ts +0 -8
  305. package/dist/components/gauge/gauge.stories.js +0 -19
  306. package/dist/components/graph/graph.stories.d.ts +0 -8
  307. package/dist/components/graph/graph.stories.js +0 -68
  308. package/dist/components/heatmap/heatmap.stories.d.ts +0 -22
  309. package/dist/components/heatmap/heatmap.stories.js +0 -154
  310. package/dist/components/map/map.stories.d.ts +0 -15
  311. package/dist/components/map/map.stories.js +0 -135
  312. package/dist/components/playback/playback.stories.d.ts +0 -7
  313. package/dist/components/playback/playback.stories.js +0 -16
  314. package/dist/components/select/select.stories.d.ts +0 -19
  315. package/dist/components/select/select.stories.js +0 -75
  316. package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
  317. package/dist/components/skeleton/skeleton.stories.js +0 -16
  318. package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
  319. package/dist/components/sparkline/sparkline.stories.js +0 -39
  320. package/dist/components/split/split.stories.d.ts +0 -7
  321. package/dist/components/split/split.stories.js +0 -36
  322. package/dist/components/stat/stat.stories.d.ts +0 -8
  323. package/dist/components/stat/stat.stories.js +0 -64
  324. package/dist/components/table/table.stories.d.ts +0 -12
  325. package/dist/components/table/table.stories.js +0 -67
  326. package/dist/components/time-range/time-range.stories.d.ts +0 -8
  327. package/dist/components/time-range/time-range.stories.js +0 -26
  328. package/dist/components/toast/toast.stories.d.ts +0 -8
  329. package/dist/components/toast/toast.stories.js +0 -72
  330. package/dist/components/tree/tree.stories.d.ts +0 -9
  331. package/dist/components/tree/tree.stories.js +0 -52
  332. package/dist/components/widget/widget.stories.d.ts +0 -7
  333. package/dist/components/widget/widget.stories.js +0 -41
  334. package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
  335. package/dist/components/word-cloud/word-cloud.stories.js +0 -55
@@ -0,0 +1,403 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { html, nothing } from 'lit';
8
+ import { property, state } from 'lit/decorators.js';
9
+ import { LyraElement } from '../../internal/lyra-element.js';
10
+ import { defineElement } from '../../internal/prefix.js';
11
+ import { lockScroll } from '../../internal/scroll-lock.js';
12
+ import { nextId } from '../../internal/a11y.js';
13
+ import { styles } from './tool-approval-dialog.styles.js';
14
+ import '../json-viewer/json-viewer.js';
15
+ const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
16
+ // Shadow-piercing so a slotted custom element's real focusable target, and
17
+ // this component's own directly-rendered <lyra-json-viewer>'s internal
18
+ // toggle/copy buttons, are found even though neither the slotted host tag
19
+ // nor <lyra-json-viewer> itself matches FOCUSABLE_SELECTOR. Deliberately
20
+ // duplicated from lyra-dialog's/lyra-tool-select-dialog's identical helper
21
+ // rather than imported/shared -- this component is its own standalone
22
+ // overlay and must not depend on either (see this file's class doc).
23
+ function collectFocusable(el) {
24
+ const result = [];
25
+ if (el.matches(FOCUSABLE_SELECTOR)) {
26
+ result.push(el);
27
+ }
28
+ if (el instanceof HTMLSlotElement) {
29
+ for (const assigned of el.assignedElements({ flatten: true })) {
30
+ result.push(...collectFocusable(assigned));
31
+ }
32
+ return result;
33
+ }
34
+ const container = el.shadowRoot ?? el;
35
+ for (const child of Array.from(container.children)) {
36
+ result.push(...collectFocusable(child));
37
+ }
38
+ return result;
39
+ }
40
+ /** Whether `el` is actually laid out/paintable -- `checkVisibility()` (falling
41
+ * back to `getClientRects().length` where unsupported) correctly follows
42
+ * flattened-tree/slot assignment, unlike `offsetParent`. Mirrors
43
+ * lyra-dialog's/lyra-tool-select-dialog's identical helper. */
44
+ function isRendered(el) {
45
+ return el.checkVisibility ? el.checkVisibility() : el.getClientRects().length > 0;
46
+ }
47
+ /**
48
+ * `<lyra-tool-approval-dialog>` — a human-in-the-loop gate: presents one
49
+ * proposed tool/function call (`toolName` + `args`) and blocks an agent from
50
+ * executing it until a person explicitly approves or denies it, with an
51
+ * optional inline "edit the arguments before approving" step.
52
+ *
53
+ * This is its own standalone overlay implementation (`role="dialog"`,
54
+ * focus-trapped, Escape/backdrop-dismissible, scroll-locking) rather than
55
+ * nesting a `<lyra-dialog>` in its shadow template — see `<lyra-dialog>`'s
56
+ * own header comment for why a new overlay component in this library
57
+ * duplicates that pattern locally instead of composing the previous one.
58
+ *
59
+ * Approve/Deny/Edit are built-in chrome (not a `footer` slot a consumer must
60
+ * assemble) — this component's interaction shape is fixed enough (there is
61
+ * exactly one correct set of actions for "approve this call") that requiring
62
+ * every consumer to re-build it would just be boilerplate. A `footer` slot is
63
+ * still offered for *supplementary* content a consumer wants alongside those
64
+ * buttons (e.g. a "remember this choice for this tool" checkbox) — its
65
+ * content renders to the start of the action row, before Deny/Edit/Approve.
66
+ *
67
+ * Editing: while `editable`, an Edit button swaps the read-only
68
+ * `<lyra-json-viewer>` for a plain `<textarea>` pre-filled with
69
+ * `JSON.stringify(args, null, 2)`. Every keystroke is re-validated with
70
+ * `JSON.parse` — the Approve button is `disabled` for as long as the current
71
+ * textarea content fails to parse, so a malformed edit can never be silently
72
+ * approved as either the broken text or a stale copy of the original args.
73
+ * The same button relabels to "Cancel" while editing; clicking it discards
74
+ * the draft entirely and returns to the read-only view of the *original*
75
+ * `args` — there is no separate "save" step independent of Approve itself.
76
+ * Both `editing` and any in-progress draft reset back to the read-only view
77
+ * every time the dialog transitions from closed to open, so a reused
78
+ * instance never leaks one proposal's half-finished edit into the next.
79
+ *
80
+ * Initial focus deliberately does *not* land on Approve (see `updated()`):
81
+ * approving a tool call is a consequential, potentially irreversible action,
82
+ * so a user who opens this dialog and reflexively presses Enter/Space before
83
+ * reading anything should deny, not approve. Deny gets the initial focus
84
+ * instead — the same "focus the safe action" convention a native destructive-
85
+ * confirmation dialog (delete, discard, etc.) typically follows for its own
86
+ * Cancel button — rather than the inert dialog panel, which would need an
87
+ * extra Tab press before *any* action is reachable at all.
88
+ *
89
+ * @customElement lyra-tool-approval-dialog
90
+ * @slot footer - Optional supplementary content (e.g. a "remember this
91
+ * choice" checkbox), rendered before the built-in Deny/Edit/Approve buttons.
92
+ * @event lyra-approve - The call was approved. `detail: { args }` — the
93
+ * current, already-parsed arguments object: the original `args` prop, or (if
94
+ * an edit was in progress) the user's edited-and-validated version. Always
95
+ * followed by `lyra-close` with reason `'approve'`.
96
+ * @event lyra-deny - The call was denied (no detail). Always followed by
97
+ * `lyra-close` with reason `'deny'`.
98
+ * @event lyra-close - `detail: ToolApprovalDialogCloseReason`. Fired exactly
99
+ * once per dismissal — via Escape, a backdrop click, the Approve/Deny
100
+ * buttons, or a `close()` call — so there is one consistent "this dialog is
101
+ * now closed" signal regardless of which path triggered it.
102
+ * @csspart backdrop - The full-viewport scrim behind the panel.
103
+ * @csspart panel - The dialog panel itself (`role="dialog"` while open).
104
+ * @csspart header - The wrapper around the heading.
105
+ * @csspart tool-name - The `toolName` text within the heading.
106
+ * @csspart body - The wrapper around the args view/editor.
107
+ * @csspart args-view - The read-only `<lyra-json-viewer>` shown while not editing.
108
+ * @csspart args-editor - The raw-JSON `<textarea>` shown while editing.
109
+ * @csspart error - The inline "invalid JSON" message, shown only while editing with unparseable content.
110
+ * @csspart footer - The action row wrapping the `footer` slot and the built-in buttons.
111
+ * @csspart deny-button - The built-in Deny button.
112
+ * @csspart edit-button - The built-in Edit/Cancel toggle button (only rendered while `editable`).
113
+ * @csspart approve-button - The built-in Approve button — `disabled` while an in-progress edit is invalid JSON.
114
+ */
115
+ export class LyraToolApprovalDialog extends LyraElement {
116
+ constructor() {
117
+ super(...arguments);
118
+ /** Whether the dialog is open. Set this (or call `close()`) — there is no separate `show()`/`hide()` pair. */
119
+ this.open = false;
120
+ /** The proposed tool/function's name, e.g. `web_search`. Drives the heading and the dialog's accessible name. */
121
+ this.toolName = '';
122
+ /** The proposed call's arguments — any JSON-serializable value, rendered via `<lyra-json-viewer>` (or, while editing, stringified into the textarea). */
123
+ this.args = {};
124
+ /** Whether an "Edit" affordance is offered at all. When `false`, `args` is always shown read-only and can never be changed before approval. */
125
+ this.editable = true;
126
+ this.editing = false;
127
+ /** The textarea's current raw text while editing — deliberately independent of `args` until Approve is pressed, so a malformed in-progress edit never overwrites it. */
128
+ this.draftText = '';
129
+ /** `JSON.parse` failure message for `draftText`, or `''` while it parses cleanly. Empty string (not `undefined`) so it can drive `?hidden` directly. */
130
+ this.draftError = '';
131
+ this.titleId = nextId('tool-approval-dialog-title');
132
+ this.errorId = nextId('tool-approval-dialog-error');
133
+ this.onBackdropClick = () => {
134
+ this.close('backdrop');
135
+ };
136
+ this.onDocKeyDown = (e) => {
137
+ if (!this.open)
138
+ return;
139
+ if (e.key === 'Escape') {
140
+ e.preventDefault();
141
+ this.close('escape');
142
+ return;
143
+ }
144
+ if (e.key !== 'Tab')
145
+ return;
146
+ const focusable = this.getFocusableElements();
147
+ if (focusable.length === 0) {
148
+ e.preventDefault();
149
+ return;
150
+ }
151
+ const first = focusable[0];
152
+ const last = focusable[focusable.length - 1];
153
+ const active = this.getActiveElement();
154
+ if (e.shiftKey && active === first) {
155
+ e.preventDefault();
156
+ last.focus();
157
+ }
158
+ else if (!e.shiftKey && active === last) {
159
+ e.preventDefault();
160
+ first.focus();
161
+ }
162
+ };
163
+ this.toggleEdit = () => {
164
+ if (this.editing) {
165
+ this.editing = false;
166
+ this.draftText = '';
167
+ this.draftError = '';
168
+ }
169
+ else {
170
+ this.editing = true;
171
+ this.draftText = this.stringifyArgs();
172
+ this.draftError = '';
173
+ }
174
+ };
175
+ this.onDraftInput = (e) => {
176
+ const value = e.target.value;
177
+ this.draftText = value;
178
+ try {
179
+ JSON.parse(value);
180
+ this.draftError = '';
181
+ }
182
+ catch (err) {
183
+ this.draftError = err instanceof Error ? err.message : 'Invalid JSON.';
184
+ }
185
+ };
186
+ this.onApprove = () => {
187
+ let currentArgs = this.args;
188
+ if (this.editing) {
189
+ // The Approve button is disabled whenever draftError is non-empty, so
190
+ // this should always succeed -- the try/catch is defense-in-depth
191
+ // against a state desync rather than an expected path.
192
+ try {
193
+ currentArgs = JSON.parse(this.draftText);
194
+ }
195
+ catch {
196
+ return;
197
+ }
198
+ }
199
+ this.emit('lyra-approve', { args: currentArgs });
200
+ this.close('approve');
201
+ };
202
+ this.onDeny = () => {
203
+ this.emit('lyra-deny');
204
+ this.close('deny');
205
+ };
206
+ }
207
+ static { this.styles = [LyraElement.styles, styles]; }
208
+ willUpdate(changed) {
209
+ if (changed.has('open')) {
210
+ if (this.open) {
211
+ // Captured here (before render) rather than from a click event on
212
+ // some specific internal control -- like lyra-dialog, a trigger
213
+ // typically lives *outside* this component entirely, so "whatever
214
+ // had focus right before open" is the only generally correct
215
+ // definition of "the trigger".
216
+ const active = this.getActiveElement();
217
+ this.lastTrigger = active instanceof HTMLElement ? active : undefined;
218
+ this.releaseScrollLock = lockScroll();
219
+ document.addEventListener('keydown', this.onDocKeyDown);
220
+ // Every open starts fresh in the read-only view -- a reused instance
221
+ // must never carry a half-finished edit (or its error state) over
222
+ // from whatever the previous proposal was.
223
+ this.editing = false;
224
+ this.draftText = '';
225
+ this.draftError = '';
226
+ }
227
+ else {
228
+ this.releaseScrollLock?.();
229
+ this.releaseScrollLock = undefined;
230
+ document.removeEventListener('keydown', this.onDocKeyDown);
231
+ }
232
+ }
233
+ // A consumer flipping editable off mid-edit (e.g. a policy change
234
+ // pushed while this dialog happens to be open) must not leave an
235
+ // unreachable edit UI on screen with no Edit/Cancel button left to
236
+ // dismiss it.
237
+ if (changed.has('editable') && !this.editable && this.editing) {
238
+ this.editing = false;
239
+ this.draftText = '';
240
+ this.draftError = '';
241
+ }
242
+ }
243
+ // Runs after render (not willUpdate) so [part="panel"]/[part="deny-button"]
244
+ // have already landed in the DOM before the focus calls below can rely on
245
+ // them -- mirrors lyra-dialog's identical ordering rationale.
246
+ updated(changed) {
247
+ if (changed.has('open') && this.open) {
248
+ // Deliberately the Deny button, not "the first focusable element" --
249
+ // see the class doc's focus-management paragraph.
250
+ const deny = this.shadowRoot?.querySelector('[part="deny-button"]');
251
+ if (deny) {
252
+ deny.focus();
253
+ }
254
+ else {
255
+ this.shadowRoot?.querySelector('[part="panel"]')?.focus();
256
+ }
257
+ return;
258
+ }
259
+ if (changed.has('editing') && this.editing) {
260
+ // Entering edit mode is a deliberate request to start typing --
261
+ // steering focus into the textarea beats leaving it on the Edit
262
+ // button the click already left it on.
263
+ this.shadowRoot?.querySelector('[part="args-editor"]')?.focus();
264
+ }
265
+ }
266
+ connectedCallback() {
267
+ super.connectedCallback();
268
+ // A reconnect (e.g. a drag-and-drop reparent keeping this same element
269
+ // instance) fires disconnectedCallback then connectedCallback
270
+ // synchronously with no update in between, so willUpdate never reruns to
271
+ // notice `open` is still true -- restore the scroll lock/trap it dropped.
272
+ if (this.hasUpdated && this.open && !this.releaseScrollLock) {
273
+ this.releaseScrollLock = lockScroll();
274
+ document.addEventListener('keydown', this.onDocKeyDown);
275
+ }
276
+ }
277
+ disconnectedCallback() {
278
+ super.disconnectedCallback();
279
+ this.releaseScrollLock?.();
280
+ this.releaseScrollLock = undefined;
281
+ document.removeEventListener('keydown', this.onDocKeyDown);
282
+ }
283
+ /**
284
+ * Close the dialog and return focus to whatever had it before the dialog
285
+ * opened. `reason` is forwarded as the `lyra-close` detail — built-in
286
+ * triggers pass `'escape'`/`'backdrop'`/`'approve'`/`'deny'`; a consumer's
287
+ * own close affordance (e.g. a footer-slotted button) should call this
288
+ * directly with its own reason string, so every dismissal path funnels
289
+ * through the same event instead of the consumer having to also toggle
290
+ * `open` itself.
291
+ */
292
+ close(reason = 'api') {
293
+ if (!this.open)
294
+ return;
295
+ this.open = false;
296
+ this.emit('lyra-close', reason);
297
+ this.lastTrigger?.focus();
298
+ }
299
+ // Bounds Tab/Shift+Tab to the panel while open. Order follows the body
300
+ // (the json-viewer's own toggle/copy buttons, or the textarea, depending
301
+ // on `editing`), then the footer row (the footer slot, then Deny/Edit/
302
+ // Approve) -- the same order the flattened tree already tabs through.
303
+ // collectFocusable()'s own FOCUSABLE_SELECTOR check excludes the Approve
304
+ // button for free while it's `disabled`, so an invalid in-progress edit
305
+ // can't be Tab-trapped into.
306
+ getFocusableElements() {
307
+ const root = this.shadowRoot;
308
+ if (!root)
309
+ return [];
310
+ const body = root.querySelector('[part="body"]');
311
+ const footer = root.querySelector('[part="footer"]');
312
+ return [...(body ? collectFocusable(body) : []), ...(footer ? collectFocusable(footer) : [])].filter(isRendered);
313
+ }
314
+ getActiveElement() {
315
+ let active = document.activeElement;
316
+ while (active) {
317
+ const inner = active.shadowRoot?.activeElement ?? null;
318
+ if (!inner)
319
+ break;
320
+ active = inner;
321
+ }
322
+ return active;
323
+ }
324
+ stringifyArgs() {
325
+ try {
326
+ // JSON.stringify(undefined, ...) returns the *value* undefined, not a
327
+ // string -- the ?? covers that alongside the try/catch's circular-
328
+ // reference case, so the textarea always opens with real text.
329
+ return JSON.stringify(this.args, null, 2) ?? 'null';
330
+ }
331
+ catch {
332
+ return 'null';
333
+ }
334
+ }
335
+ render() {
336
+ const hasError = this.editing && this.draftError.length > 0;
337
+ return html `
338
+ <div part="backdrop" @click=${this.onBackdropClick}></div>
339
+ <div
340
+ part="panel"
341
+ role=${this.open ? 'dialog' : nothing}
342
+ aria-modal=${this.open ? 'true' : nothing}
343
+ aria-labelledby=${this.titleId}
344
+ tabindex="-1"
345
+ >
346
+ <div part="header">
347
+ <h2 id=${this.titleId}>Approve <span part="tool-name">${this.toolName || 'tool'}</span> call?</h2>
348
+ </div>
349
+ <div part="body">
350
+ ${this.editing
351
+ ? html `
352
+ <textarea
353
+ part="args-editor"
354
+ spellcheck="false"
355
+ autocomplete="off"
356
+ aria-label="Tool call arguments (JSON)"
357
+ aria-invalid=${hasError ? 'true' : 'false'}
358
+ aria-describedby=${hasError ? this.errorId : nothing}
359
+ .value=${this.draftText}
360
+ @input=${this.onDraftInput}
361
+ ></textarea>
362
+ <p part="error" id=${this.errorId} role="alert" ?hidden=${!hasError}>${this.draftError}</p>
363
+ `
364
+ : html `<lyra-json-viewer part="args-view" .data=${this.args}></lyra-json-viewer>`}
365
+ </div>
366
+ <div part="footer">
367
+ <slot name="footer"></slot>
368
+ <button part="deny-button" type="button" @click=${this.onDeny}>Deny</button>
369
+ ${this.editable
370
+ ? html `<button part="edit-button" type="button" @click=${this.toggleEdit}>
371
+ ${this.editing ? 'Cancel' : 'Edit'}
372
+ </button>`
373
+ : nothing}
374
+ <button part="approve-button" type="button" ?disabled=${hasError} @click=${this.onApprove}>
375
+ Approve
376
+ </button>
377
+ </div>
378
+ </div>
379
+ `;
380
+ }
381
+ }
382
+ __decorate([
383
+ property({ type: Boolean, reflect: true })
384
+ ], LyraToolApprovalDialog.prototype, "open", void 0);
385
+ __decorate([
386
+ property({ attribute: 'tool-name' })
387
+ ], LyraToolApprovalDialog.prototype, "toolName", void 0);
388
+ __decorate([
389
+ property({ attribute: false })
390
+ ], LyraToolApprovalDialog.prototype, "args", void 0);
391
+ __decorate([
392
+ property({ type: Boolean, reflect: true })
393
+ ], LyraToolApprovalDialog.prototype, "editable", void 0);
394
+ __decorate([
395
+ state()
396
+ ], LyraToolApprovalDialog.prototype, "editing", void 0);
397
+ __decorate([
398
+ state()
399
+ ], LyraToolApprovalDialog.prototype, "draftText", void 0);
400
+ __decorate([
401
+ state()
402
+ ], LyraToolApprovalDialog.prototype, "draftError", void 0);
403
+ defineElement('tool-approval-dialog', LyraToolApprovalDialog);
@@ -0,0 +1 @@
1
+ export declare const styles: import("lit").CSSResult;
@@ -0,0 +1,160 @@
1
+ import { css } from 'lit';
2
+ export const styles = css `
3
+ :host {
4
+ /* Backdrop scrim color -- component-specific so a host can retheme it
5
+ without a raw literal leaking into the public API (no shared
6
+ --wa-*-overlay token exists in the design system to resolve through,
7
+ same rationale as lyra-dialog's --lyra-dialog-overlay-color and
8
+ lyra-tool-select-dialog's --lyra-tool-select-dialog-overlay-color). */
9
+ --lyra-tool-approval-dialog-overlay-color: rgb(0 0 0 / 0.5);
10
+ /* Contained here (rather than a bare font-family literal on the
11
+ textarea) so a host page can retheme it -- same rationale as
12
+ lyra-json-viewer's --lyra-json-viewer-font; raw args are code, not
13
+ prose, so the editor gets the same monospace treatment as that
14
+ viewer's own tree rendering. */
15
+ --lyra-tool-approval-dialog-mono-font: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
16
+ display: none;
17
+ position: fixed;
18
+ inset: 0;
19
+ z-index: 1000;
20
+ align-items: center;
21
+ justify-content: center;
22
+ padding: var(--lyra-space-l);
23
+ }
24
+ :host([open]) {
25
+ display: flex;
26
+ }
27
+ [part='backdrop'] {
28
+ position: absolute;
29
+ inset: 0;
30
+ background: var(--lyra-tool-approval-dialog-overlay-color);
31
+ }
32
+ [part='panel'] {
33
+ position: relative;
34
+ display: flex;
35
+ flex-direction: column;
36
+ inline-size: min(32rem, 100%);
37
+ max-block-size: min(36rem, 100%);
38
+ background: var(--lyra-color-surface);
39
+ border: 1px solid var(--lyra-color-border);
40
+ border-radius: var(--lyra-radius);
41
+ box-shadow: var(--lyra-shadow);
42
+ overflow: hidden;
43
+ }
44
+ [part='header'] {
45
+ padding: var(--lyra-space-l) var(--lyra-space-l) 0;
46
+ }
47
+ [part='header'] h2 {
48
+ margin: 0;
49
+ font-size: 1.0625rem;
50
+ font-weight: 600;
51
+ }
52
+ [part='tool-name'] {
53
+ font-family: var(--lyra-tool-approval-dialog-mono-font);
54
+ font-weight: 700;
55
+ color: var(--lyra-color-brand);
56
+ word-break: break-word;
57
+ }
58
+
59
+ [part='body'] {
60
+ flex: 1 1 auto;
61
+ min-block-size: 0;
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: var(--lyra-space-xs);
65
+ padding: var(--lyra-space-m) var(--lyra-space-l) var(--lyra-space-l);
66
+ overflow: auto;
67
+ }
68
+ [part='args-view'] {
69
+ /* lyra-json-viewer grows with its content by default (its own
70
+ max-height is 'none'); this component's [part='body'] is what caps
71
+ and scrolls it instead, so it stays consistent with the plain
72
+ [part='args-editor'] textarea below, which has no scroll cap of its
73
+ own either. */
74
+ flex: 1 1 auto;
75
+ min-block-size: 0;
76
+ }
77
+ [part='args-editor'] {
78
+ flex: 1 1 auto;
79
+ min-block-size: 10rem;
80
+ box-sizing: border-box;
81
+ resize: vertical;
82
+ padding: var(--lyra-space-s) var(--lyra-space-m);
83
+ border: 1px solid var(--lyra-color-border);
84
+ border-radius: var(--lyra-radius);
85
+ background: var(--lyra-color-surface);
86
+ color: inherit;
87
+ font-family: var(--lyra-tool-approval-dialog-mono-font);
88
+ font-size: 0.8125rem;
89
+ line-height: 1.5;
90
+ }
91
+ [part='args-editor']:focus-visible {
92
+ outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
93
+ outline-offset: var(--lyra-focus-ring-offset);
94
+ }
95
+ [part='args-editor'][aria-invalid='true'] {
96
+ border-color: var(--lyra-color-danger);
97
+ }
98
+ [part='error'] {
99
+ margin: 0;
100
+ font-size: 0.8125rem;
101
+ color: var(--lyra-color-danger);
102
+ }
103
+ [part='error'][hidden] {
104
+ display: none;
105
+ }
106
+
107
+ [part='footer'] {
108
+ display: flex;
109
+ align-items: center;
110
+ justify-content: flex-end;
111
+ gap: var(--lyra-space-s);
112
+ padding: var(--lyra-space-m) var(--lyra-space-l);
113
+ border-block-start: 1px solid var(--lyra-color-border);
114
+ }
115
+ [part='footer'] ::slotted(*) {
116
+ /* Any consumer-supplied footer content sits ahead of the built-in
117
+ buttons and soaks up the row's remaining space, so it reads as
118
+ start-aligned while Deny/Edit/Approve stay pinned to the end (the
119
+ row itself is justify-content: flex-end for the empty-slot case). */
120
+ margin-inline-end: auto;
121
+ }
122
+
123
+ [part='deny-button'],
124
+ [part='edit-button'],
125
+ [part='approve-button'] {
126
+ font: inherit;
127
+ font-size: 0.875rem;
128
+ padding: var(--lyra-space-xs) var(--lyra-space-m);
129
+ border-radius: var(--lyra-radius);
130
+ cursor: pointer;
131
+ border: 1px solid var(--lyra-color-border);
132
+ }
133
+ [part='deny-button'],
134
+ [part='edit-button'] {
135
+ background: var(--lyra-color-surface);
136
+ color: var(--lyra-color-text);
137
+ }
138
+ [part='deny-button']:hover,
139
+ [part='edit-button']:hover {
140
+ background: var(--lyra-color-brand-quiet);
141
+ }
142
+ [part='approve-button'] {
143
+ background: var(--lyra-color-brand);
144
+ color: var(--lyra-color-on-brand);
145
+ border-color: var(--lyra-color-brand);
146
+ }
147
+ [part='approve-button']:hover:not(:disabled) {
148
+ filter: brightness(1.1);
149
+ }
150
+ [part='approve-button']:disabled {
151
+ cursor: not-allowed;
152
+ opacity: var(--lyra-opacity-disabled);
153
+ }
154
+ [part='deny-button']:focus-visible,
155
+ [part='edit-button']:focus-visible,
156
+ [part='approve-button']:focus-visible {
157
+ outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
158
+ outline-offset: var(--lyra-focus-ring-offset);
159
+ }
160
+ `;
@@ -0,0 +1,89 @@
1
+ import { type TemplateResult, type PropertyValues } from 'lit';
2
+ import { LyraElement } from '../../internal/lyra-element.js';
3
+ /** Same status vocabulary as `<lyra-tool-result-dialog>`, so a call's chip
4
+ * and its detail dialog always agree on icon/label/tone. */
5
+ export type ToolCallStatus = 'pending' | 'running' | 'success' | 'error' | 'denied';
6
+ export interface ToolChipSelectDetail {
7
+ name: string;
8
+ callId: string;
9
+ }
10
+ /**
11
+ * `<lyra-tool-call-chip>` — a compact inline pill representing one tool/
12
+ * function call an agent made mid-conversation, e.g.
13
+ * `web_search: Searching web…` with a `running` spinner. It owns no detail
14
+ * surface of its own: clicking (or Enter/Space-activating) it only fires
15
+ * `lyra-tool-chip-select` — a consumer wires that to opening a
16
+ * `<lyra-tool-result-dialog>` (or anything else) at the call site. Keeping
17
+ * the two decoupled means a chip can be reused wherever a compact call
18
+ * summary is useful, with or without a detail surface behind it.
19
+ *
20
+ * The default slot is *not* the chip's visible content — the chip's own
21
+ * label is always built from `name`/`summary`/`status`/`duration-ms`. It's
22
+ * reserved for optional rich detail content (e.g. the tool's raw arguments,
23
+ * a short preview) shown in a floating tooltip on hover/focus, positioned
24
+ * with `internal/positioner.js`'s `place()` the same way `<lyra-combobox>`
25
+ * positions its listbox. No tooltip is shown at all when the slot carries no
26
+ * content — hovering an empty chip does nothing.
27
+ *
28
+ * The `icon` slot overrides the built-in per-status glyph entirely via the
29
+ * platform's own slot-fallback-content mechanism (`<slot
30
+ * name="icon">${fallback}</slot>` — the same pattern `<lyra-stat>`'s
31
+ * `caption` slot and `<lyra-file-input>`'s default slot already use):
32
+ * whatever is assigned to `slot="icon"` wins; otherwise the `icon` prop is
33
+ * rendered as a literal hint (e.g. an emoji); otherwise the built-in glyph
34
+ * for the current `status` is used.
35
+ *
36
+ * @customElement lyra-tool-call-chip
37
+ * @slot - Rich tooltip/detail content, shown on hover/focus. Nothing renders
38
+ * (no hover affordance at all) when this slot is empty.
39
+ * @slot icon - Overrides the built-in status glyph entirely.
40
+ * @event lyra-tool-chip-select - The chip was activated (click or Enter/Space
41
+ * while focused). `detail: { name, callId }`.
42
+ * @csspart base - The clickable pill (`<button>`).
43
+ * @csspart icon - Wrapper around the status glyph / `icon` slot.
44
+ * @csspart label - Wrapper around `category`, `name` and `summary`.
45
+ * @csspart category - The optional grouping label.
46
+ * @csspart name - The tool/function name.
47
+ * @csspart summary - The short status text.
48
+ * @csspart meta - Wrapper around `status-text` and `duration`.
49
+ * @csspart status-text - The visible text twin of the status glyph/color — carries the state in text, not just color.
50
+ * @csspart duration - The formatted `duration-ms`, when set.
51
+ * @csspart tooltip - The floating detail popup (only meaningful while open).
52
+ */
53
+ export declare class LyraToolCallChip extends LyraElement {
54
+ static styles: import("lit").CSSResultGroup[];
55
+ /** The tool/function name, e.g. `web_search`. */
56
+ name: string;
57
+ /** Optional grouping label, e.g. `research`. */
58
+ category: string;
59
+ /** The call's current lifecycle state — drives the glyph, color, and `status-text`. */
60
+ status: ToolCallStatus;
61
+ /** Short human-readable status text, e.g. `Searching web…`. */
62
+ summary: string;
63
+ /** How long the call took, in milliseconds. Omitted from the chip entirely when unset. */
64
+ durationMs?: number;
65
+ /** Literal icon hint (e.g. an emoji) used when the `icon` slot is empty — see the class doc's
66
+ * icon-precedence note. Ignored once anything is assigned to `slot="icon"`. */
67
+ icon: string;
68
+ /** Unique identifier for this specific invocation — echoed back in `lyra-tool-chip-select`'s
69
+ * detail so a listener can correlate the click with the call it fired for. */
70
+ callId: string;
71
+ private hasDetailSlot;
72
+ private tooltipOpen;
73
+ private cleanupPositioner?;
74
+ protected willUpdate(): void;
75
+ protected updated(changed: PropertyValues): void;
76
+ disconnectedCallback(): void;
77
+ private onDetailSlotChange;
78
+ private showTooltip;
79
+ private hideTooltip;
80
+ private onKeyDown;
81
+ private onClick;
82
+ private get accessibleLabel();
83
+ render(): TemplateResult;
84
+ }
85
+ declare global {
86
+ interface HTMLElementTagNameMap {
87
+ 'lyra-tool-call-chip': LyraToolCallChip;
88
+ }
89
+ }