@aceshooting/lyra-ui 1.2.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 (330) hide show
  1. package/README.md +11 -0
  2. package/custom-elements.json +23341 -11202
  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 +1 -2
  19. package/dist/components/chart/chart.js +67 -12
  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 +54 -0
  23. package/dist/components/chart/lite-chart.js +140 -22
  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 +29 -13
  88. package/dist/components/flag/flag.js +39 -13
  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 +74 -0
  99. package/dist/components/heatmap/heatmap.js +135 -23
  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 +43 -2
  159. package/dist/components/select/select.js +150 -17
  160. package/dist/components/slider/slider.d.ts +89 -0
  161. package/dist/components/slider/slider.js +352 -0
  162. package/dist/components/slider/slider.styles.d.ts +1 -0
  163. package/dist/components/slider/slider.styles.js +87 -0
  164. package/dist/components/source-card/source-card.d.ts +92 -0
  165. package/dist/components/source-card/source-card.js +148 -0
  166. package/dist/components/source-card/source-card.styles.d.ts +1 -0
  167. package/dist/components/source-card/source-card.styles.js +69 -0
  168. package/dist/components/source-list/source-list.d.ts +63 -0
  169. package/dist/components/source-list/source-list.js +122 -0
  170. package/dist/components/source-list/source-list.styles.d.ts +1 -0
  171. package/dist/components/source-list/source-list.styles.js +59 -0
  172. package/dist/components/sparkline/sparkline.js +27 -13
  173. package/dist/components/split/split.d.ts +93 -1
  174. package/dist/components/split/split.js +284 -15
  175. package/dist/components/split/split.styles.js +30 -0
  176. package/dist/components/stat/stat.d.ts +6 -1
  177. package/dist/components/stat/stat.js +8 -2
  178. package/dist/components/stream-status/stream-status.d.ts +110 -0
  179. package/dist/components/stream-status/stream-status.js +210 -0
  180. package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
  181. package/dist/components/stream-status/stream-status.styles.js +103 -0
  182. package/dist/components/streaming-text/streaming-text.d.ts +98 -0
  183. package/dist/components/streaming-text/streaming-text.js +209 -0
  184. package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
  185. package/dist/components/streaming-text/streaming-text.styles.js +62 -0
  186. package/dist/components/switch/switch.d.ts +58 -0
  187. package/dist/components/switch/switch.js +179 -0
  188. package/dist/components/switch/switch.styles.d.ts +1 -0
  189. package/dist/components/switch/switch.styles.js +75 -0
  190. package/dist/components/table/table.d.ts +73 -4
  191. package/dist/components/table/table.js +169 -20
  192. package/dist/components/table/table.styles.js +6 -1
  193. package/dist/components/tabs/tabs.d.ts +51 -0
  194. package/dist/components/tabs/tabs.js +190 -0
  195. package/dist/components/tabs/tabs.styles.d.ts +1 -0
  196. package/dist/components/tabs/tabs.styles.js +63 -0
  197. package/dist/components/thinking-panel/thinking-panel.d.ts +121 -0
  198. package/dist/components/thinking-panel/thinking-panel.js +235 -0
  199. package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
  200. package/dist/components/thinking-panel/thinking-panel.styles.js +117 -0
  201. package/dist/components/toast/toast-item.d.ts +1 -0
  202. package/dist/components/toast/toast-item.js +31 -6
  203. package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +130 -0
  204. package/dist/components/tool-approval-dialog/tool-approval-dialog.js +403 -0
  205. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
  206. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
  207. package/dist/components/tool-call-chip/tool-call-chip.d.ts +89 -0
  208. package/dist/components/tool-call-chip/tool-call-chip.js +288 -0
  209. package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
  210. package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
  211. package/dist/components/tool-param-form/tool-param-form.d.ts +145 -0
  212. package/dist/components/tool-param-form/tool-param-form.js +366 -0
  213. package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
  214. package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
  215. package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +102 -0
  216. package/dist/components/tool-result-dialog/tool-result-dialog.js +393 -0
  217. package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
  218. package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
  219. package/dist/components/tool-result-view/registry.d.ts +81 -0
  220. package/dist/components/tool-result-view/registry.js +84 -0
  221. package/dist/components/tool-result-view/tool-result-view.d.ts +55 -0
  222. package/dist/components/tool-result-view/tool-result-view.js +138 -0
  223. package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
  224. package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
  225. package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
  226. package/dist/components/tool-select-dialog/tool-select-dialog.js +439 -0
  227. package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
  228. package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +182 -0
  229. package/dist/components/tree/tree-node.d.ts +11 -2
  230. package/dist/components/tree/tree-node.js +16 -6
  231. package/dist/components/tree/tree.d.ts +8 -2
  232. package/dist/components/tree/tree.js +18 -11
  233. package/dist/components/typing-indicator/typing-indicator.d.ts +60 -0
  234. package/dist/components/typing-indicator/typing-indicator.js +96 -0
  235. package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
  236. package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
  237. package/dist/components/virtual-list/virtual-list.d.ts +173 -0
  238. package/dist/components/virtual-list/virtual-list.js +461 -0
  239. package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
  240. package/dist/components/virtual-list/virtual-list.styles.js +44 -0
  241. package/dist/components/word-cloud/word-cloud-layout.js +14 -1
  242. package/dist/components/word-cloud/word-cloud.d.ts +6 -0
  243. package/dist/components/word-cloud/word-cloud.js +25 -14
  244. package/dist/components/word-cloud/word-cloud.styles.js +3 -2
  245. package/dist/internal/announcer.d.ts +57 -0
  246. package/dist/internal/announcer.js +71 -0
  247. package/dist/internal/form-associated.d.ts +1 -0
  248. package/dist/internal/form-associated.js +55 -11
  249. package/dist/internal/group-by-recency.d.ts +50 -0
  250. package/dist/internal/group-by-recency.js +80 -0
  251. package/dist/internal/rtl.d.ts +23 -0
  252. package/dist/internal/rtl.js +28 -0
  253. package/dist/internal/scroll-lock.d.ts +10 -5
  254. package/dist/internal/scroll-lock.js +30 -14
  255. package/dist/internal/tokens.styles.js +6 -0
  256. package/dist/lyra.d.ts +130 -31
  257. package/dist/lyra.js +94 -26
  258. package/llms-full.txt +3836 -17
  259. package/llms.txt +16 -1
  260. package/package.json +23 -5
  261. package/dist/components/chart/bar-chart.stories.d.ts +0 -5
  262. package/dist/components/chart/bar-chart.stories.js +0 -20
  263. package/dist/components/chart/box-plot.stories.d.ts +0 -5
  264. package/dist/components/chart/box-plot.stories.js +0 -29
  265. package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
  266. package/dist/components/chart/bubble-chart.stories.js +0 -26
  267. package/dist/components/chart/chart.stories.d.ts +0 -32
  268. package/dist/components/chart/chart.stories.js +0 -141
  269. package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
  270. package/dist/components/chart/doughnut-chart.stories.js +0 -26
  271. package/dist/components/chart/histogram.stories.d.ts +0 -5
  272. package/dist/components/chart/histogram.stories.js +0 -17
  273. package/dist/components/chart/line-chart.stories.d.ts +0 -22
  274. package/dist/components/chart/line-chart.stories.js +0 -99
  275. package/dist/components/chart/lite-chart.stories.d.ts +0 -14
  276. package/dist/components/chart/lite-chart.stories.js +0 -114
  277. package/dist/components/chart/pie-chart.stories.d.ts +0 -5
  278. package/dist/components/chart/pie-chart.stories.js +0 -26
  279. package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
  280. package/dist/components/chart/polar-area-chart.stories.js +0 -20
  281. package/dist/components/chart/radar-chart.stories.d.ts +0 -5
  282. package/dist/components/chart/radar-chart.stories.js +0 -20
  283. package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
  284. package/dist/components/chart/scatter-chart.stories.js +0 -31
  285. package/dist/components/combobox/combobox.stories.d.ts +0 -24
  286. package/dist/components/combobox/combobox.stories.js +0 -102
  287. package/dist/components/date-picker/date-input.stories.d.ts +0 -10
  288. package/dist/components/date-picker/date-input.stories.js +0 -48
  289. package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
  290. package/dist/components/date-picker/date-picker.stories.js +0 -25
  291. package/dist/components/empty/empty.stories.d.ts +0 -7
  292. package/dist/components/empty/empty.stories.js +0 -34
  293. package/dist/components/export-button/export-button.stories.d.ts +0 -7
  294. package/dist/components/export-button/export-button.stories.js +0 -37
  295. package/dist/components/file-input/file-input.stories.d.ts +0 -7
  296. package/dist/components/file-input/file-input.stories.js +0 -19
  297. package/dist/components/flag/flag.stories.d.ts +0 -6
  298. package/dist/components/flag/flag.stories.js +0 -31
  299. package/dist/components/gauge/gauge.stories.d.ts +0 -8
  300. package/dist/components/gauge/gauge.stories.js +0 -19
  301. package/dist/components/graph/graph.stories.d.ts +0 -8
  302. package/dist/components/graph/graph.stories.js +0 -68
  303. package/dist/components/heatmap/heatmap.stories.d.ts +0 -27
  304. package/dist/components/heatmap/heatmap.stories.js +0 -179
  305. package/dist/components/map/map.stories.d.ts +0 -15
  306. package/dist/components/map/map.stories.js +0 -135
  307. package/dist/components/playback/playback.stories.d.ts +0 -7
  308. package/dist/components/playback/playback.stories.js +0 -16
  309. package/dist/components/select/select.stories.d.ts +0 -21
  310. package/dist/components/select/select.stories.js +0 -91
  311. package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
  312. package/dist/components/skeleton/skeleton.stories.js +0 -16
  313. package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
  314. package/dist/components/sparkline/sparkline.stories.js +0 -39
  315. package/dist/components/split/split.stories.d.ts +0 -7
  316. package/dist/components/split/split.stories.js +0 -36
  317. package/dist/components/stat/stat.stories.d.ts +0 -9
  318. package/dist/components/stat/stat.stories.js +0 -81
  319. package/dist/components/table/table.stories.d.ts +0 -12
  320. package/dist/components/table/table.stories.js +0 -67
  321. package/dist/components/time-range/time-range.stories.d.ts +0 -8
  322. package/dist/components/time-range/time-range.stories.js +0 -26
  323. package/dist/components/toast/toast.stories.d.ts +0 -8
  324. package/dist/components/toast/toast.stories.js +0 -72
  325. package/dist/components/tree/tree.stories.d.ts +0 -9
  326. package/dist/components/tree/tree.stories.js +0 -52
  327. package/dist/components/widget/widget.stories.d.ts +0 -9
  328. package/dist/components/widget/widget.stories.js +0 -74
  329. package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
  330. package/dist/components/word-cloud/word-cloud.stories.js +0 -55
@@ -0,0 +1,365 @@
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 { styles } from './responsive-panel.styles.js';
13
+ const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
14
+ // Shadow-piercing so a slotted custom element's real focusable target (e.g.
15
+ // an <input> inside its own shadow root) is found even though the host tag
16
+ // itself doesn't match FOCUSABLE_SELECTOR. Deliberately duplicated from
17
+ // lyra-dialog's identical helper rather than imported/shared -- every
18
+ // overlay-shaped component in this family (lyra-dialog, lyra-widget,
19
+ // lyra-tool-result-dialog, lyra-tool-select-dialog) re-implements this
20
+ // locally rather than nesting a previous overlay component inside its own
21
+ // shadow DOM, because slot-forwarding would break the inner component's own
22
+ // light-DOM scanning.
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 identical helper. */
44
+ function isRendered(el) {
45
+ return el.checkVisibility ? el.checkVisibility() : el.getClientRects().length > 0;
46
+ }
47
+ /**
48
+ * Pure resolution of the `mode` prop + current viewport into the actual
49
+ * presentation. Kept separate from the `matchMedia` listener wiring below so
50
+ * it's independently unit-testable, and so the live-viewport-response logic
51
+ * can be exercised in tests by calling it (or the instance method that wraps
52
+ * it) directly instead of needing control over the real browser window,
53
+ * which `@web/test-runner` doesn't give.
54
+ */
55
+ export function resolveEffectiveMode(mode, belowBreakpoint) {
56
+ if (mode === 'inline' || mode === 'overlay')
57
+ return mode;
58
+ return belowBreakpoint ? 'overlay' : 'inline';
59
+ }
60
+ /**
61
+ * `<lyra-responsive-panel>` — the same slotted content either docked inline
62
+ * in the page's normal layout flow (desktop) or presented as a full-screen/
63
+ * bottom-sheet overlay (mobile), depending on viewport width. Typical uses:
64
+ * a settings panel or a conversation-history sidebar that's a permanent
65
+ * docked pane on a wide screen but a modal on a phone.
66
+ *
67
+ * Breakpoint detection uses `matchMedia('(max-width: ' + mobileBreakpoint +
68
+ * ')')`, re-evaluated live while connected -- resizing/rotating a device
69
+ * that crosses the breakpoint while `mode="auto"` (the default) updates the
70
+ * effective presentation without unmounting or re-creating the slotted
71
+ * content: inline and overlay presentation share the exact same shadow DOM
72
+ * structure (only a css class, and the overlay-only `role`/`aria-modal`
73
+ * attributes and backdrop element, differ), so lit-html's diffing keeps
74
+ * `[part="body"]` and its `<slot>` as the same DOM node across the
75
+ * transition -- scroll position and focus inside the slotted content survive
76
+ * it for free, with no extra bookkeeping required. The one exception is
77
+ * focus: crossing the breakpoint while already open does *not* forcibly
78
+ * move focus into the panel (unlike an `open` transition, which does) --
79
+ * doing so on a resize could yank focus away from an input the user is
80
+ * actively typing into inside the now-newly-modal panel, which is worse UX
81
+ * than a modal that's very briefly missing its initial focus placement.
82
+ *
83
+ * The overlay presentation duplicates lyra-dialog's `role="dialog"` +
84
+ * focus-trap + Escape/backdrop-dismiss + scroll-lock mechanics locally
85
+ * rather than nesting a `<lyra-dialog>` inside this component's shadow DOM,
86
+ * per the established precedent for every overlay-shaped component in this
87
+ * family (see lyra-dialog's own module doc).
88
+ *
89
+ * @customElement lyra-responsive-panel
90
+ * @slot - The panel body.
91
+ * @slot header - Optional header content, rendered above the body.
92
+ * @slot footer - Optional footer content (e.g. action buttons), rendered below the body.
93
+ * @event lyra-close - `detail: ResponsivePanelCloseReason`. Fired by the overlay presentation's
94
+ * built-in dismiss triggers (Escape, backdrop click) and by any `close()` call, in either
95
+ * presentation -- a plain `open = false` property write does not fire it (matching
96
+ * lyra-dialog's own precedent: only going through `close()` counts as a dismissal), and this
97
+ * is deliberately the same event/semantics in both presentations, rather than only being
98
+ * meaningful for the overlay case, so a consumer only has to wire up one listener regardless
99
+ * of which presentation is currently active.
100
+ * @event lyra-mode-change - `detail: ResponsivePanelModeChangeDetail`. Fired whenever the
101
+ * *effective* mode (not the `mode` prop's literal value, which may be `'auto'`) changes between
102
+ * `'inline'` and `'overlay'` -- crossing the breakpoint while `mode="auto"`, or the host
103
+ * reassigning `mode` to a value that changes the effective presentation. Never fired for the
104
+ * initial render, only for a live change thereafter.
105
+ * @csspart base - The root wrapper; `display: none` while closed, positioned `fixed` while open
106
+ * and in the overlay presentation.
107
+ * @csspart backdrop - The full-viewport scrim behind the panel -- only rendered in the overlay
108
+ * presentation.
109
+ * @csspart panel - The panel surface itself (`role="dialog"` while open and in the overlay
110
+ * presentation).
111
+ * @csspart header - The wrapper around the `header` slot.
112
+ * @csspart body - The wrapper around the default slot.
113
+ * @csspart footer - The wrapper around the `footer` slot.
114
+ */
115
+ export class LyraResponsivePanel extends LyraElement {
116
+ constructor() {
117
+ super(...arguments);
118
+ /** Whether the panel is open. In the inline presentation this just means visible/mounted; in
119
+ * the overlay presentation this is the actual modal open/closed state. */
120
+ this.open = false;
121
+ /** `'auto'` (default) tracks `mobile-breakpoint` live; `'inline'`/`'overlay'` force that
122
+ * presentation regardless of viewport width. */
123
+ this.mode = 'auto';
124
+ /** Only affects the overlay presentation's visual treatment -- `'fullscreen'` (default) covers
125
+ * the whole viewport; `'bottom-sheet'` slides up from the bottom and doesn't cover the full
126
+ * height. */
127
+ this.variant = 'fullscreen';
128
+ /** Accessible name for the overlay presentation's `role="dialog"`. Unused in the inline
129
+ * presentation, which has no dialog semantics to name. */
130
+ this.label = '';
131
+ /** CSS length passed to `matchMedia` as `(max-width: <this>)` to decide, in `mode="auto"`,
132
+ * whether the effective presentation is `'overlay'` (below/at this width) or `'inline'`
133
+ * (above it). */
134
+ this.mobileBreakpoint = '768px';
135
+ this.belowBreakpoint = false;
136
+ this.effectiveMode = 'inline';
137
+ this.hasHeaderSlot = false;
138
+ this.hasFooterSlot = false;
139
+ /** Whether the overlay-only mechanics (scroll-lock, document Escape/Tab trap) are currently
140
+ * engaged -- derived from `effectiveMode === 'overlay' && open`, tracked separately from those
141
+ * two properties so willUpdate can diff "was engaged" vs "should be engaged now" regardless of
142
+ * which of the two changed. */
143
+ this.overlayChromeActive = false;
144
+ this.isFirstUpdate = true;
145
+ this.onMediaChange = (e) => {
146
+ this.handleBreakpointChange(e.matches);
147
+ };
148
+ this.onHeaderSlotChange = (e) => {
149
+ this.hasHeaderSlot = e.target.assignedElements({ flatten: true }).length > 0;
150
+ };
151
+ this.onFooterSlotChange = (e) => {
152
+ this.hasFooterSlot = e.target.assignedElements({ flatten: true }).length > 0;
153
+ };
154
+ this.onBackdropClick = () => {
155
+ this.close('backdrop');
156
+ };
157
+ this.onDocKeyDown = (e) => {
158
+ if (!this.overlayChromeActive)
159
+ return;
160
+ if (e.key === 'Escape') {
161
+ e.preventDefault();
162
+ this.close('escape');
163
+ return;
164
+ }
165
+ if (e.key !== 'Tab')
166
+ return;
167
+ const focusable = this.getFocusableElements();
168
+ if (focusable.length === 0) {
169
+ e.preventDefault();
170
+ return;
171
+ }
172
+ const first = focusable[0];
173
+ const last = focusable[focusable.length - 1];
174
+ const active = this.getActiveElement();
175
+ if (e.shiftKey && active === first) {
176
+ e.preventDefault();
177
+ last.focus();
178
+ }
179
+ else if (!e.shiftKey && active === last) {
180
+ e.preventDefault();
181
+ first.focus();
182
+ }
183
+ };
184
+ }
185
+ static { this.styles = [LyraElement.styles, styles]; }
186
+ willUpdate(changed) {
187
+ this.isFirstUpdate = !this.hasUpdated;
188
+ if (this.isFirstUpdate) {
189
+ this.hasHeaderSlot = Array.from(this.children).some((el) => el.getAttribute('slot') === 'header');
190
+ this.hasFooterSlot = Array.from(this.children).some((el) => el.getAttribute('slot') === 'footer');
191
+ }
192
+ if (this.isFirstUpdate || changed.has('mode') || changed.has('belowBreakpoint')) {
193
+ this.effectiveMode = resolveEffectiveMode(this.mode, this.belowBreakpoint);
194
+ }
195
+ if (changed.has('mobileBreakpoint') && this.isConnected) {
196
+ this.setupMediaQuery();
197
+ }
198
+ const overlayOpen = this.effectiveMode === 'overlay' && this.open;
199
+ if (overlayOpen !== this.overlayChromeActive) {
200
+ this.overlayChromeActive = overlayOpen;
201
+ if (overlayOpen) {
202
+ const active = this.getActiveElement();
203
+ this.lastTrigger = active instanceof HTMLElement ? active : undefined;
204
+ this.releaseScrollLock = lockScroll();
205
+ document.addEventListener('keydown', this.onDocKeyDown);
206
+ }
207
+ else {
208
+ this.releaseScrollLock?.();
209
+ this.releaseScrollLock = undefined;
210
+ document.removeEventListener('keydown', this.onDocKeyDown);
211
+ }
212
+ }
213
+ }
214
+ // Runs after render (not willUpdate) so [part="panel"] has already landed
215
+ // in the DOM before the fallback .focus() call below can rely on it --
216
+ // mirrors lyra-dialog's identical ordering rationale. Only a genuine `open`
217
+ // transition steals focus (see the class doc for why a breakpoint-crossing
218
+ // while already open deliberately does not).
219
+ updated(changed) {
220
+ if (!this.isFirstUpdate && changed.has('effectiveMode')) {
221
+ this.emit('lyra-mode-change', { mode: this.effectiveMode });
222
+ }
223
+ if (changed.has('open') && this.open && this.effectiveMode === 'overlay') {
224
+ const first = this.getFocusableElements()[0];
225
+ if (first) {
226
+ first.focus();
227
+ }
228
+ else {
229
+ this.shadowRoot?.querySelector('[part="panel"]')?.focus();
230
+ }
231
+ }
232
+ }
233
+ connectedCallback() {
234
+ super.connectedCallback();
235
+ this.setupMediaQuery();
236
+ // A reconnect (e.g. a drag-and-drop reparent keeping this same element
237
+ // instance) fires disconnectedCallback then connectedCallback
238
+ // synchronously with no update in between, so willUpdate never reruns to
239
+ // notice overlay chrome is still supposed to be active -- restore it.
240
+ // Mirrors lyra-dialog's identical reconnect handling.
241
+ if (this.hasUpdated && this.overlayChromeActive && !this.releaseScrollLock) {
242
+ this.releaseScrollLock = lockScroll();
243
+ document.addEventListener('keydown', this.onDocKeyDown);
244
+ }
245
+ }
246
+ disconnectedCallback() {
247
+ super.disconnectedCallback();
248
+ this.mediaQuery?.removeEventListener('change', this.onMediaChange);
249
+ this.mediaQuery = undefined;
250
+ this.releaseScrollLock?.();
251
+ this.releaseScrollLock = undefined;
252
+ document.removeEventListener('keydown', this.onDocKeyDown);
253
+ }
254
+ setupMediaQuery() {
255
+ this.mediaQuery?.removeEventListener('change', this.onMediaChange);
256
+ this.mediaQuery = window.matchMedia(`(max-width: ${this.mobileBreakpoint})`);
257
+ this.mediaQuery.addEventListener('change', this.onMediaChange);
258
+ this.handleBreakpointChange(this.mediaQuery.matches);
259
+ }
260
+ /** The breakpoint-response logic itself, kept callable independently of the
261
+ * `matchMedia` listener that normally drives it -- tests invoke this
262
+ * directly to simulate crossing the breakpoint. */
263
+ handleBreakpointChange(matches) {
264
+ this.belowBreakpoint = matches;
265
+ }
266
+ /**
267
+ * Close the panel. `reason` is forwarded as the `lyra-close` detail --
268
+ * built-in overlay triggers pass `'escape'`/`'backdrop'`; a consumer's own
269
+ * close affordance (e.g. a footer button, or a docked panel's own toggle)
270
+ * should call this directly with its own reason string. Fires in both
271
+ * presentations (see the class doc's `lyra-close` note) but only returns
272
+ * focus to the trigger that opened it when the overlay presentation is
273
+ * active, since the inline presentation never took focus away from
274
+ * anything to begin with.
275
+ */
276
+ close(reason = 'api') {
277
+ if (!this.open)
278
+ return;
279
+ this.open = false;
280
+ this.emit('lyra-close', reason);
281
+ if (this.effectiveMode === 'overlay') {
282
+ this.lastTrigger?.focus();
283
+ }
284
+ }
285
+ // Bounds Tab/Shift+Tab to the panel while overlay chrome is active. Order
286
+ // follows the header slot, then the body slot, then the footer slot -- the
287
+ // same order the flattened tree already tabs through.
288
+ getFocusableElements() {
289
+ const root = this.shadowRoot;
290
+ if (!root)
291
+ return [];
292
+ const fromSlot = (selector) => {
293
+ const slot = root.querySelector(selector);
294
+ return slot ? slot.assignedElements({ flatten: true }).flatMap(collectFocusable) : [];
295
+ };
296
+ return [
297
+ ...fromSlot('slot[name="header"]'),
298
+ ...fromSlot('slot:not([name])'),
299
+ ...fromSlot('slot[name="footer"]'),
300
+ ].filter(isRendered);
301
+ }
302
+ getActiveElement() {
303
+ let active = document.activeElement;
304
+ while (active) {
305
+ const inner = active.shadowRoot?.activeElement ?? null;
306
+ if (!inner)
307
+ break;
308
+ active = inner;
309
+ }
310
+ return active;
311
+ }
312
+ render() {
313
+ const overlay = this.effectiveMode === 'overlay';
314
+ return html `
315
+ <div part="base" class=${overlay ? 'overlay' : 'inline'}>
316
+ ${overlay ? html `<div part="backdrop" @click=${this.onBackdropClick}></div>` : nothing}
317
+ <div
318
+ part="panel"
319
+ role=${overlay ? 'dialog' : nothing}
320
+ aria-modal=${overlay ? 'true' : nothing}
321
+ aria-label=${overlay && this.label ? this.label : nothing}
322
+ tabindex=${overlay ? '-1' : nothing}
323
+ >
324
+ <div part="header" ?hidden=${!this.hasHeaderSlot}>
325
+ <slot name="header" @slotchange=${this.onHeaderSlotChange}></slot>
326
+ </div>
327
+ <div part="body">
328
+ <slot></slot>
329
+ </div>
330
+ <div part="footer" ?hidden=${!this.hasFooterSlot}>
331
+ <slot name="footer" @slotchange=${this.onFooterSlotChange}></slot>
332
+ </div>
333
+ </div>
334
+ </div>
335
+ `;
336
+ }
337
+ }
338
+ __decorate([
339
+ property({ type: Boolean, reflect: true })
340
+ ], LyraResponsivePanel.prototype, "open", void 0);
341
+ __decorate([
342
+ property({ reflect: true })
343
+ ], LyraResponsivePanel.prototype, "mode", void 0);
344
+ __decorate([
345
+ property({ reflect: true })
346
+ ], LyraResponsivePanel.prototype, "variant", void 0);
347
+ __decorate([
348
+ property()
349
+ ], LyraResponsivePanel.prototype, "label", void 0);
350
+ __decorate([
351
+ property({ attribute: 'mobile-breakpoint' })
352
+ ], LyraResponsivePanel.prototype, "mobileBreakpoint", void 0);
353
+ __decorate([
354
+ state()
355
+ ], LyraResponsivePanel.prototype, "belowBreakpoint", void 0);
356
+ __decorate([
357
+ state()
358
+ ], LyraResponsivePanel.prototype, "effectiveMode", void 0);
359
+ __decorate([
360
+ state()
361
+ ], LyraResponsivePanel.prototype, "hasHeaderSlot", void 0);
362
+ __decorate([
363
+ state()
364
+ ], LyraResponsivePanel.prototype, "hasFooterSlot", void 0);
365
+ defineElement('responsive-panel', LyraResponsivePanel);
@@ -0,0 +1 @@
1
+ export declare const styles: import("lit").CSSResult;
@@ -0,0 +1,103 @@
1
+ import { css } from 'lit';
2
+ export const styles = css `
3
+ :host {
4
+ /* Overlay 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 own --lyra-dialog-overlay-color and
8
+ lyra-widget's --lyra-widget-overlay-color). */
9
+ --lyra-responsive-panel-overlay-color: rgb(0 0 0 / 0.5);
10
+ display: block;
11
+ }
12
+
13
+ /* [part="base"] is display:none whenever the panel isn't open, in both
14
+ presentations -- a docked (inline) panel can be toggled closed just like
15
+ an overlay one, it just doesn't need backdrop/focus-trap/scroll-lock
16
+ mechanics to do it. */
17
+ [part='base'] {
18
+ display: none;
19
+ }
20
+ :host([open]) [part='base'] {
21
+ display: block;
22
+ }
23
+ :host([open]) [part='base'].overlay {
24
+ display: flex;
25
+ position: fixed;
26
+ inset: 0;
27
+ z-index: 1000;
28
+ }
29
+ /* Bottom-sheet anchors its panel to the block-end edge instead of
30
+ stretching it full-height like fullscreen does. */
31
+ :host([variant='bottom-sheet'][open]) [part='base'].overlay {
32
+ align-items: flex-end;
33
+ }
34
+
35
+ [part='backdrop'] {
36
+ position: absolute;
37
+ inset: 0;
38
+ background: var(--lyra-responsive-panel-overlay-color);
39
+ }
40
+
41
+ [part='panel'] {
42
+ position: relative;
43
+ display: flex;
44
+ flex-direction: column;
45
+ min-block-size: 0;
46
+ background: var(--lyra-color-surface);
47
+ }
48
+
49
+ /* Inline (docked) presentation: a normal panel in the page's layout flow,
50
+ bordered like a card so it reads as a distinct region. */
51
+ [part='base']:not(.overlay) [part='panel'] {
52
+ border: 1px solid var(--lyra-color-border);
53
+ border-radius: var(--lyra-radius);
54
+ overflow: auto;
55
+ }
56
+
57
+ /* Overlay/fullscreen (default variant): the panel fills the entire
58
+ viewport edge-to-edge -- no backdrop is visible around it, but the
59
+ backdrop element still renders/still matters for the shared
60
+ Escape/backdrop-click dismissal wiring described on the class. */
61
+ [part='base'].overlay [part='panel'] {
62
+ inline-size: 100%;
63
+ block-size: 100%;
64
+ box-shadow: var(--lyra-shadow);
65
+ overflow: auto;
66
+ }
67
+
68
+ /* Overlay/bottom-sheet: a partial-height sheet, rounded only on the top
69
+ edge, that leaves the backdrop (and whatever page content sits behind
70
+ it) visible above it. */
71
+ :host([variant='bottom-sheet']) [part='base'].overlay [part='panel'] {
72
+ block-size: auto;
73
+ max-block-size: 85vh;
74
+ border-start-start-radius: var(--lyra-radius);
75
+ border-start-end-radius: var(--lyra-radius);
76
+ }
77
+
78
+ [part='header'] {
79
+ padding: var(--lyra-space-m) var(--lyra-space-l);
80
+ border-block-end: 1px solid var(--lyra-color-border);
81
+ }
82
+ [part='header'][hidden] {
83
+ display: none;
84
+ }
85
+
86
+ [part='body'] {
87
+ flex: 1;
88
+ padding: var(--lyra-space-l);
89
+ overflow: auto;
90
+ }
91
+
92
+ [part='footer'] {
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: flex-end;
96
+ gap: var(--lyra-space-s);
97
+ padding: var(--lyra-space-m) var(--lyra-space-l);
98
+ border-block-start: 1px solid var(--lyra-color-border);
99
+ }
100
+ [part='footer'][hidden] {
101
+ display: none;
102
+ }
103
+ `;
@@ -0,0 +1,44 @@
1
+ import { type TemplateResult } from 'lit';
2
+ import { LyraElement } from '../../internal/lyra-element.js';
3
+ /**
4
+ * `<lyra-result-card>` — a small bordered card shell for a custom tool-result
5
+ * renderer's body (see `<lyra-tool-result-view>`'s `registerToolRenderer()`
6
+ * in `../tool-result-view/registry.js`). Purely visual, with no state of its
7
+ * own beyond slot-presence tracking: it gives every custom renderer the same
8
+ * "small card" language (border, radius, optional title + header actions)
9
+ * without each one hand-rolling its own box.
10
+ *
11
+ * Pairs with `<lyra-result-field>` for the label/value rows that typically
12
+ * make up the body, though the default slot accepts any content — nothing
13
+ * here requires a `<lyra-result-field>` specifically.
14
+ *
15
+ * @customElement lyra-result-card
16
+ * @slot - The card body — typically one or more `<lyra-result-field>` rows.
17
+ * @slot actions - Small header controls (e.g. a copy button), rendered
18
+ * alongside the title.
19
+ * @csspart base - The outer bordered container.
20
+ * @csspart header - The header row wrapping the title and the `actions`
21
+ * slot. Present in the DOM at all times (so a later `slotchange` on
22
+ * `actions` is still observed) but `hidden` whenever there is no `title`
23
+ * and no `actions` content — an untitled, action-less card has no visible
24
+ * header bar at all.
25
+ * @csspart title - The title text.
26
+ * @csspart actions - The wrapper around the `actions` slot. `hidden`
27
+ * whenever the slot has no assigned content.
28
+ * @csspart body - The wrapper around the default slot.
29
+ */
30
+ export declare class LyraResultCard extends LyraElement {
31
+ static styles: import("lit").CSSResultGroup[];
32
+ /** Small heading for the card. Leave unset for an untitled card (e.g. a
33
+ * bare block of `<lyra-result-field>` rows with no natural heading). */
34
+ title: string;
35
+ private hasActionsSlot;
36
+ protected willUpdate(): void;
37
+ private onActionsSlotChange;
38
+ render(): TemplateResult;
39
+ }
40
+ declare global {
41
+ interface HTMLElementTagNameMap {
42
+ 'lyra-result-card': LyraResultCard;
43
+ }
44
+ }
@@ -0,0 +1,83 @@
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 { styles } from './result-card.styles.js';
12
+ /**
13
+ * `<lyra-result-card>` — a small bordered card shell for a custom tool-result
14
+ * renderer's body (see `<lyra-tool-result-view>`'s `registerToolRenderer()`
15
+ * in `../tool-result-view/registry.js`). Purely visual, with no state of its
16
+ * own beyond slot-presence tracking: it gives every custom renderer the same
17
+ * "small card" language (border, radius, optional title + header actions)
18
+ * without each one hand-rolling its own box.
19
+ *
20
+ * Pairs with `<lyra-result-field>` for the label/value rows that typically
21
+ * make up the body, though the default slot accepts any content — nothing
22
+ * here requires a `<lyra-result-field>` specifically.
23
+ *
24
+ * @customElement lyra-result-card
25
+ * @slot - The card body — typically one or more `<lyra-result-field>` rows.
26
+ * @slot actions - Small header controls (e.g. a copy button), rendered
27
+ * alongside the title.
28
+ * @csspart base - The outer bordered container.
29
+ * @csspart header - The header row wrapping the title and the `actions`
30
+ * slot. Present in the DOM at all times (so a later `slotchange` on
31
+ * `actions` is still observed) but `hidden` whenever there is no `title`
32
+ * and no `actions` content — an untitled, action-less card has no visible
33
+ * header bar at all.
34
+ * @csspart title - The title text.
35
+ * @csspart actions - The wrapper around the `actions` slot. `hidden`
36
+ * whenever the slot has no assigned content.
37
+ * @csspart body - The wrapper around the default slot.
38
+ */
39
+ export class LyraResultCard extends LyraElement {
40
+ constructor() {
41
+ super(...arguments);
42
+ /** Small heading for the card. Leave unset for an untitled card (e.g. a
43
+ * bare block of `<lyra-result-field>` rows with no natural heading). */
44
+ this.title = '';
45
+ // See `<lyra-widget>`'s identical `hasActionsSlot` -- a `[part]` wrapper
46
+ // always contains a literal `<slot>` child regardless of assigned
47
+ // content, so CSS `:empty` never matches; real emptiness is tracked here
48
+ // in JS instead and used to both hide the actions wrapper and decide
49
+ // whether the header row itself has anything to show.
50
+ this.hasActionsSlot = false;
51
+ this.onActionsSlotChange = (e) => {
52
+ this.hasActionsSlot = e.target.assignedElements({ flatten: true }).length > 0;
53
+ };
54
+ }
55
+ static { this.styles = [LyraElement.styles, styles]; }
56
+ willUpdate() {
57
+ if (!this.hasUpdated) {
58
+ this.hasActionsSlot = Array.from(this.children).some((el) => el.getAttribute('slot') === 'actions');
59
+ }
60
+ }
61
+ render() {
62
+ const hasTitle = this.title.length > 0;
63
+ const hasHeader = hasTitle || this.hasActionsSlot;
64
+ return html `
65
+ <div part="base">
66
+ <div part="header" ?hidden=${!hasHeader}>
67
+ ${hasTitle ? html `<span part="title">${this.title}</span>` : nothing}
68
+ <div part="actions" ?hidden=${!this.hasActionsSlot}>
69
+ <slot name="actions" @slotchange=${this.onActionsSlotChange}></slot>
70
+ </div>
71
+ </div>
72
+ <div part="body"><slot></slot></div>
73
+ </div>
74
+ `;
75
+ }
76
+ }
77
+ __decorate([
78
+ property()
79
+ ], LyraResultCard.prototype, "title", void 0);
80
+ __decorate([
81
+ state()
82
+ ], LyraResultCard.prototype, "hasActionsSlot", void 0);
83
+ defineElement('result-card', LyraResultCard);
@@ -0,0 +1 @@
1
+ export declare const styles: import("lit").CSSResult;
@@ -0,0 +1,50 @@
1
+ import { css } from 'lit';
2
+ export const styles = css `
3
+ :host {
4
+ display: block;
5
+ }
6
+ [part='base'] {
7
+ display: flex;
8
+ flex-direction: column;
9
+ border: 1px solid var(--lyra-color-border);
10
+ border-radius: var(--lyra-radius);
11
+ background: var(--lyra-color-surface);
12
+ overflow: hidden;
13
+ font-size: 0.8125rem;
14
+ }
15
+ [part='header'] {
16
+ display: flex;
17
+ align-items: center;
18
+ gap: var(--lyra-space-s);
19
+ padding: var(--lyra-space-xs) var(--lyra-space-s);
20
+ border-block-end: 1px solid var(--lyra-color-border);
21
+ }
22
+ [part='header'][hidden] {
23
+ display: none;
24
+ }
25
+ [part='title'] {
26
+ flex: 1 1 auto;
27
+ min-inline-size: 0;
28
+ color: var(--lyra-color-text);
29
+ font-weight: 600;
30
+ font-size: 0.8125rem;
31
+ overflow: hidden;
32
+ text-overflow: ellipsis;
33
+ white-space: nowrap;
34
+ }
35
+ [part='actions'] {
36
+ display: flex;
37
+ align-items: center;
38
+ gap: var(--lyra-space-xs);
39
+ flex: 0 0 auto;
40
+ }
41
+ [part='actions'][hidden] {
42
+ display: none;
43
+ }
44
+ [part='body'] {
45
+ display: flex;
46
+ flex-direction: column;
47
+ gap: var(--lyra-space-xs);
48
+ padding: var(--lyra-space-s);
49
+ }
50
+ `;