@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
@@ -56,6 +56,17 @@ function loadFlagUrlResolver() {
56
56
  }
57
57
  return flagUrlResolver;
58
58
  }
59
+ /**
60
+ * @internal Test-only seam: overrides (or, with `undefined`, clears) the module-level cache that
61
+ * `willUpdate()` reads through `loadFlagUrlResolver()`. The real `@aceshooting/lyra-flags` peer's
62
+ * `flagUrl(code)` never actually rejects (unknown codes just resolve `undefined`), so this is the
63
+ * only way to exercise a resolver-function rejection — e.g. a network failure fetching a flag
64
+ * asset — without uninstalling the real package. Not part of the public API; not re-exported from
65
+ * the root barrel.
66
+ */
67
+ export function __setFlagUrlResolverForTesting(value) {
68
+ flagUrlResolver = value;
69
+ }
59
70
  /**
60
71
  * `<lyra-flag>` — a country/language flag.
61
72
  *
@@ -75,16 +86,19 @@ function loadFlagUrlResolver() {
75
86
  * `src` instead to skip the peer-package round trip (and its loading-skeleton
76
87
  * flash) entirely.
77
88
  *
78
- * A handful of flags (e.g. `es`, `pt` — any whose design includes a detailed coat of
79
- * arms/seal/emblem) ship a second, full-detail source SVG alongside the default icon-optimized
80
- * one; set `detailed` to request it (e.g. for a hero-scale display where the extra illustrative
81
- * detail is actually visible). A no-op for every other code see `detailed`'s own doc.
89
+ * The ~65 flags whose design includes a detailed coat of arms/seal/emblem (e.g. `es`, `pt`) ship
90
+ * three fidelity tiers; choose one with `variant`: `"compact"` (a tiny WebP raster for icon-scale
91
+ * use menu items, language selectors, dense lists), the default `"standard"` (icon-optimized
92
+ * vector for card/row sizes), or `"detailed"` (the pristine full-detail vector for hero-scale
93
+ * display). A no-op for every other code — all tiers resolve to the same file. See `variant`'s own
94
+ * doc.
82
95
  *
83
96
  * @customElement lyra-flag
84
97
  * @example <lyra-flag country="fr"></lyra-flag>
85
98
  * @example <lyra-flag language="en" label="English"></lyra-flag>
86
99
  * @example <lyra-flag src=${frUrl} label="French"></lyra-flag>
87
- * @example <lyra-flag country="es" detailed></lyra-flag>
100
+ * @example <lyra-flag country="es" variant="compact"></lyra-flag>
101
+ * @example <lyra-flag country="es" variant="detailed"></lyra-flag>
88
102
  * @csspart image - The underlying <img>.
89
103
  */
90
104
  export class LyraFlag extends LyraElement {
@@ -93,13 +107,8 @@ export class LyraFlag extends LyraElement {
93
107
  /** Render as a circular flag. */
94
108
  this.round = false;
95
109
  /**
96
- * Requests the pristine, full-detail source SVG instead of the default icon-optimized one
97
- * only meaningful for the minority of `country`/`language` codes whose source art was large
98
- * enough to need optimizing (e.g. `es`, `pt`, a national coat of arms/seal/emblem); for every
99
- * other code this is a safe no-op (the default and detailed variants are the same file). Has no
100
- * effect when `src` is set — a pre-resolved URL is used as-is regardless. Intended for rendering
101
- * a flag larger than icon scale (e.g. a hero display) where the extra illustrative detail is
102
- * actually visible.
110
+ * @deprecated Use `variant="detailed"` instead. Kept as an alias for one minor cycle; when
111
+ * `variant` is unset, `detailed` still maps to the detailed tier. Removed in the next major.
103
112
  */
104
113
  this.detailed = false;
105
114
  /** True while the lazy-loaded `@aceshooting/lyra-flags` peer resolver is in flight. */
@@ -113,6 +122,11 @@ export class LyraFlag extends LyraElement {
113
122
  this.resolveToken = 0;
114
123
  }
115
124
  static { this.styles = [LyraElement.styles, styles]; }
125
+ /** The effective tier to request: an explicit `variant` wins; otherwise the deprecated
126
+ * `detailed` boolean is honored; otherwise `"standard"`. */
127
+ get effectiveVariant() {
128
+ return this.variant ?? (this.detailed ? 'detailed' : 'standard');
129
+ }
116
130
  get code() {
117
131
  if (this.country) {
118
132
  return ALPHA2_RE.test(this.country) ? this.country.toLowerCase() : undefined;
@@ -132,6 +146,7 @@ export class LyraFlag extends LyraElement {
132
146
  !changed.has('country') &&
133
147
  !changed.has('language') &&
134
148
  !changed.has('src') &&
149
+ !changed.has('variant') &&
135
150
  !changed.has('detailed')) {
136
151
  return;
137
152
  }
@@ -148,13 +163,21 @@ export class LyraFlag extends LyraElement {
148
163
  return;
149
164
  }
150
165
  this.loading = true;
166
+ const variant = this.effectiveVariant;
151
167
  void loadFlagUrlResolver()
152
- .then((resolve) => resolve?.(code, this.detailed ? { variant: 'detailed' } : undefined))
168
+ .then((resolve) => resolve?.(code, variant === 'standard' ? undefined : { variant }))
153
169
  .then((url) => {
154
170
  if (token !== this.resolveToken)
155
171
  return; // superseded by a later country/language/src change
156
172
  this.resolvedSrc = url;
157
173
  this.loading = false;
174
+ })
175
+ .catch((err) => {
176
+ if (token !== this.resolveToken)
177
+ return; // superseded by a later country/language/src change
178
+ console.warn(`<lyra-flag> failed to resolve a flag URL for "${code}":`, err);
179
+ this.resolvedSrc = undefined;
180
+ this.loading = false;
158
181
  });
159
182
  }
160
183
  updated() {
@@ -189,6 +212,9 @@ __decorate([
189
212
  __decorate([
190
213
  property({ type: Boolean, reflect: true })
191
214
  ], LyraFlag.prototype, "round", void 0);
215
+ __decorate([
216
+ property()
217
+ ], LyraFlag.prototype, "variant", void 0);
192
218
  __decorate([
193
219
  property({ type: Boolean, reflect: true })
194
220
  ], LyraFlag.prototype, "detailed", void 0);
@@ -57,28 +57,37 @@ export class LyraGauge extends LyraElement {
57
57
  }
58
58
  static { this.styles = [LyraElement.styles, styles]; }
59
59
  get ratio() {
60
- if (isNaN(this.value) || isNaN(this.min) || isNaN(this.max))
60
+ if (!Number.isFinite(this.value) || !Number.isFinite(this.min) || !Number.isFinite(this.max))
61
61
  return 0;
62
- const span = this.max - this.min || 1;
63
- return Math.min(1, Math.max(0, (this.value - this.min) / span));
62
+ const lo = Math.min(this.min, this.max);
63
+ const hi = Math.max(this.min, this.max);
64
+ const span = hi - lo || 1;
65
+ return Math.min(1, Math.max(0, (this.value - lo) / span));
64
66
  }
65
67
  willUpdate() {
66
68
  this.setAttribute('role', 'meter');
67
- if (!isNaN(this.value) && !isNaN(this.min) && !isNaN(this.max)) {
68
- const clamped = Math.min(this.max, Math.max(this.min, this.value));
69
+ const finiteTrio = Number.isFinite(this.value) && Number.isFinite(this.min) && Number.isFinite(this.max);
70
+ // Normalize a reversed min > max domain the same way `ratio` does, so the
71
+ // announced aria-value* trio always agrees with the visual fill instead
72
+ // of aria-valuenow pinning to one bound regardless of `value` (and
73
+ // aria-valuemin/valuemax reporting an inverted, invalid ARIA range).
74
+ const lo = Number.isFinite(this.min) && Number.isFinite(this.max) ? Math.min(this.min, this.max) : this.min;
75
+ const hi = Number.isFinite(this.min) && Number.isFinite(this.max) ? Math.max(this.min, this.max) : this.max;
76
+ if (finiteTrio) {
77
+ const clamped = Math.min(hi, Math.max(lo, this.value));
69
78
  this.setAttribute('aria-valuenow', String(clamped));
70
79
  }
71
80
  else {
72
81
  this.removeAttribute('aria-valuenow');
73
82
  }
74
- if (isNaN(this.min))
83
+ if (Number.isFinite(lo))
84
+ this.setAttribute('aria-valuemin', String(lo));
85
+ else
75
86
  this.removeAttribute('aria-valuemin');
87
+ if (Number.isFinite(hi))
88
+ this.setAttribute('aria-valuemax', String(hi));
76
89
  else
77
- this.setAttribute('aria-valuemin', String(this.min));
78
- if (isNaN(this.max))
79
90
  this.removeAttribute('aria-valuemax');
80
- else
81
- this.setAttribute('aria-valuemax', String(this.max));
82
91
  if (this.label)
83
92
  this.setAttribute('aria-label', this.label);
84
93
  else
@@ -0,0 +1,109 @@
1
+ import { type TemplateResult, type PropertyValues } from 'lit';
2
+ import { LyraElement } from '../../internal/lyra-element.js';
3
+ /**
4
+ * `<lyra-generation-status>` — a compact, ticking status readout shown
5
+ * alongside an in-progress AI response: elapsed time, token count, and
6
+ * token-throughput, plus a built-in Stop button. Renders as e.g.
7
+ * `12.3s · 340 tokens · 27 tok/s [Stop]`.
8
+ *
9
+ * This is deliberately a *different* concern than the already-landed
10
+ * `<lyra-stream-status>`: that component is about transport/connection
11
+ * health (idle/connecting/streaming/stalled, heartbeat-aware stall
12
+ * detection), while this one is a user-facing metrics readout for a
13
+ * generation that both components' hosts typically already know is
14
+ * healthily in progress. Neither imports or depends on the other, and a
15
+ * consumer building a full generation UI is expected to compose both side by
16
+ * side rather than pick one.
17
+ *
18
+ * `active` drives an internal ~1s `setInterval` ticker that recomputes the
19
+ * elapsed-time display (a plain interval is sufficient here -- unlike
20
+ * `<lyra-stream-status>`'s stall timer, this never needs to be armed with a
21
+ * precise deadline, only to refresh a display roughly once a second). The
22
+ * elapsed clock's start instant is `started-at` when set (an epoch-ms
23
+ * timestamp -- lets a host that already knows exactly when generation began,
24
+ * e.g. from its own request-dispatch timestamp, feed that in directly and
25
+ * survive this component being created slightly later than that instant);
26
+ * when `started-at` is unset, this component falls back to capturing
27
+ * `Date.now()` itself at the moment `active` flips from `false`/unset to
28
+ * `true`, so the ticker still starts from a sensible instant with zero
29
+ * required host bookkeeping. The ticker is cleared whenever `active` becomes
30
+ * `false` and on disconnect; the display is left at whatever it last showed
31
+ * (frozen, not reset to zero) -- a static "Generated in 12.3s" reads better
32
+ * as a completed-state summary than the readout blanking out the instant
33
+ * generation ends.
34
+ *
35
+ * `tokens-per-second`, when the host supplies it directly (e.g. from its own
36
+ * smoothed/windowed rate calculation), is always used as-is. When omitted,
37
+ * this component derives a live figure itself from `token-count` divided by
38
+ * elapsed seconds -- but only once at least one full second of elapsed time
39
+ * has accumulated, since dividing by a sub-second elapsed window can produce
40
+ * wildly-swinging, misleading early readings (e.g. 3 tokens in 40ms reading
41
+ * as "75 tok/s"). A host that wants a stable figure from the very first tick
42
+ * should supply `tokens-per-second` itself. The tokens segment and the
43
+ * throughput segment are independently optional: either, both, or neither
44
+ * may render depending on what's available, per each property's own doc.
45
+ *
46
+ * Accessibility: this readout ticks roughly once per second while active,
47
+ * which is exactly the kind of high-frequency update
48
+ * `<lyra-live-region>`/`Announcer` (`../../internal/announcer.js`) exists to
49
+ * *prevent* from being read aloud verbatim -- routing a per-second numeric
50
+ * tick through even a throttled announcer would still narrate a new number
51
+ * to a screen-reader user roughly once every throttle window for as long as
52
+ * generation runs, which is noise, not information. This component
53
+ * therefore carries no `role="status"`/`aria-live` of its own and never
54
+ * announces anything; a host that wants generation-start/-end announced
55
+ * should pair this with something that announces state *transitions* (e.g.
56
+ * `<lyra-typing-indicator>`'s mount-time announcement), not this ticking
57
+ * readout. The one genuinely actionable, infrequent control here -- the Stop
58
+ * button -- gets a normal, always-present `aria-label`, no different from
59
+ * any other icon-only button in this library.
60
+ *
61
+ * @customElement lyra-generation-status
62
+ * @event lyra-stop - The built-in Stop button was clicked. No detail payload.
63
+ * @csspart base - The root inline layout container.
64
+ * @csspart elapsed - The elapsed-time segment, e.g. `"12.3s"`. Always rendered (reads `"0.0s"` before the component has ever been active).
65
+ * @csspart tokens - The token-count segment, e.g. `"340 tokens"`. Only rendered when `token-count` is set.
66
+ * @csspart throughput - The throughput segment, e.g. `"27 tok/s"`. Only rendered when a value is available (host-supplied or derived; see the class doc).
67
+ * @csspart stop-button - The built-in Stop button. Only rendered while `show-stop` is true.
68
+ */
69
+ export declare class LyraGenerationStatus extends LyraElement {
70
+ static styles: import("lit").CSSResultGroup[];
71
+ /** Whether generation is currently in progress. The elapsed-time ticker
72
+ * runs only while this is `true` (see the class doc). */
73
+ active: boolean;
74
+ /** Epoch-ms timestamp of when generation began. Optional -- when unset
75
+ * while `active` is `true`, this component captures the current time
76
+ * itself the moment `active` becomes `true` and counts from there instead
77
+ * (see the class doc). */
78
+ startedAt?: number;
79
+ /** Running token count so far. Omitted from the readout entirely (no
80
+ * `tokens` segment) while unset. */
81
+ tokenCount?: number;
82
+ /** Host-computed tokens/sec figure, used as-is when set. When unset, this
83
+ * component derives a live figure from `token-count` and elapsed time
84
+ * itself once one is available -- see the class doc for the exact rule
85
+ * and why. */
86
+ tokensPerSecond?: number;
87
+ /** Whether the built-in Stop button renders at all. */
88
+ showStop: boolean;
89
+ private elapsedMs;
90
+ private tickTimer?;
91
+ private fallbackStartMs?;
92
+ disconnectedCallback(): void;
93
+ protected willUpdate(changed: PropertyValues): void;
94
+ protected updated(changed: PropertyValues): void;
95
+ private startTicker;
96
+ private stopTicker;
97
+ private computeElapsedMs;
98
+ /** `tokens-per-second` when set; otherwise a derived figure once enough
99
+ * elapsed time has accumulated for it to be meaningful; otherwise
100
+ * `undefined` (the throughput segment doesn't render at all). */
101
+ private get effectiveTokensPerSecond();
102
+ private onStopClick;
103
+ render(): TemplateResult;
104
+ }
105
+ declare global {
106
+ interface HTMLElementTagNameMap {
107
+ 'lyra-generation-status': LyraGenerationStatus;
108
+ }
109
+ }
@@ -0,0 +1,273 @@
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, svg } 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 './generation-status.styles.js';
12
+ // Mirrors the shared icon set's viewBox/stroke conventions
13
+ // (internal/icons.ts's chevronIcon()/closeIcon()/etc.) without adding a
14
+ // stop glyph to that module -- it's off limits here -- so this one-off icon
15
+ // still reads as part of the same visual language as the rest of the
16
+ // library's inline icons. Identical shape to `<lyra-chat-composer>`'s own
17
+ // local `stopIcon()` (the conventional filled-square "stop generating"
18
+ // glyph), duplicated rather than imported since these are two independently
19
+ // consumable components with no dependency between them.
20
+ function stopIcon() {
21
+ return svg `
22
+ <svg
23
+ width="1em"
24
+ height="1em"
25
+ viewBox="0 0 24 24"
26
+ fill="currentColor"
27
+ stroke="none"
28
+ aria-hidden="true"
29
+ focusable="false"
30
+ ><rect x="6" y="6" width="12" height="12" rx="1.5"></rect></svg>
31
+ `;
32
+ }
33
+ /** `4200` -> `"4.2s"`; `65000` -> `"1m 5s"`. Sub-minute durations get one
34
+ * decimal place of seconds (the common case: most single generations finish
35
+ * in single-digit seconds, where whole-second precision would look static
36
+ * between ticks); once a full minute is reached, `"Xm Ys"` reads better than
37
+ * a fractional-minute or a 3-4 digit seconds count. The `59.95` cutoff (not
38
+ * a plain `60`) exists so a value that *rounds* to `"60.0s"` at one-decimal
39
+ * precision is displayed as `"1m 0s"` instead -- without it, the two
40
+ * branches could each independently round the same instant to a different
41
+ * minute. */
42
+ function formatElapsed(ms) {
43
+ const totalSeconds = Math.max(0, ms) / 1000;
44
+ if (totalSeconds < 59.95) {
45
+ return `${(Math.round(totalSeconds * 10) / 10).toFixed(1)}s`;
46
+ }
47
+ const wholeSeconds = Math.round(totalSeconds);
48
+ const minutes = Math.floor(wholeSeconds / 60);
49
+ const seconds = wholeSeconds % 60;
50
+ return `${minutes}m ${seconds}s`;
51
+ }
52
+ /** `340` -> `"340 tokens"`; `1` -> `"1 token"`. Same plain singular/plural
53
+ * ternary `<lyra-json-viewer>`'s array/object summary already uses -- this
54
+ * library has no general i18n/pluralization system (see
55
+ * `<lyra-source-list>`'s class doc for that stance), but a two-way English
56
+ * ternary for one fixed noun is a different, much smaller thing than a
57
+ * general pluralization engine, and reads better than an unconditional
58
+ * "1 tokens". */
59
+ function formatTokenCount(count) {
60
+ const rounded = Math.max(0, Math.round(count));
61
+ return `${rounded} ${rounded === 1 ? 'token' : 'tokens'}`;
62
+ }
63
+ /** `27.4` -> `"27 tok/s"`; `3.2` -> `"3.2 tok/s"`. Same shape as this file's
64
+ * `formatElapsed`/`<lyra-tool-call-chip>`'s `formatDuration`: the low end of
65
+ * the range (where a whole-number rounding would flatten every early
66
+ * reading to the same "0" or "1") gets one decimal place, while anything at
67
+ * or above 10 tok/s rounds to a whole number, which is plenty precise for a
68
+ * live-updating throughput figure. */
69
+ function formatThroughput(value) {
70
+ const clamped = Math.max(0, value);
71
+ const rounded = clamped < 10 ? Math.round(clamped * 10) / 10 : Math.round(clamped);
72
+ return `${rounded} tok/s`;
73
+ }
74
+ /**
75
+ * `<lyra-generation-status>` — a compact, ticking status readout shown
76
+ * alongside an in-progress AI response: elapsed time, token count, and
77
+ * token-throughput, plus a built-in Stop button. Renders as e.g.
78
+ * `12.3s · 340 tokens · 27 tok/s [Stop]`.
79
+ *
80
+ * This is deliberately a *different* concern than the already-landed
81
+ * `<lyra-stream-status>`: that component is about transport/connection
82
+ * health (idle/connecting/streaming/stalled, heartbeat-aware stall
83
+ * detection), while this one is a user-facing metrics readout for a
84
+ * generation that both components' hosts typically already know is
85
+ * healthily in progress. Neither imports or depends on the other, and a
86
+ * consumer building a full generation UI is expected to compose both side by
87
+ * side rather than pick one.
88
+ *
89
+ * `active` drives an internal ~1s `setInterval` ticker that recomputes the
90
+ * elapsed-time display (a plain interval is sufficient here -- unlike
91
+ * `<lyra-stream-status>`'s stall timer, this never needs to be armed with a
92
+ * precise deadline, only to refresh a display roughly once a second). The
93
+ * elapsed clock's start instant is `started-at` when set (an epoch-ms
94
+ * timestamp -- lets a host that already knows exactly when generation began,
95
+ * e.g. from its own request-dispatch timestamp, feed that in directly and
96
+ * survive this component being created slightly later than that instant);
97
+ * when `started-at` is unset, this component falls back to capturing
98
+ * `Date.now()` itself at the moment `active` flips from `false`/unset to
99
+ * `true`, so the ticker still starts from a sensible instant with zero
100
+ * required host bookkeeping. The ticker is cleared whenever `active` becomes
101
+ * `false` and on disconnect; the display is left at whatever it last showed
102
+ * (frozen, not reset to zero) -- a static "Generated in 12.3s" reads better
103
+ * as a completed-state summary than the readout blanking out the instant
104
+ * generation ends.
105
+ *
106
+ * `tokens-per-second`, when the host supplies it directly (e.g. from its own
107
+ * smoothed/windowed rate calculation), is always used as-is. When omitted,
108
+ * this component derives a live figure itself from `token-count` divided by
109
+ * elapsed seconds -- but only once at least one full second of elapsed time
110
+ * has accumulated, since dividing by a sub-second elapsed window can produce
111
+ * wildly-swinging, misleading early readings (e.g. 3 tokens in 40ms reading
112
+ * as "75 tok/s"). A host that wants a stable figure from the very first tick
113
+ * should supply `tokens-per-second` itself. The tokens segment and the
114
+ * throughput segment are independently optional: either, both, or neither
115
+ * may render depending on what's available, per each property's own doc.
116
+ *
117
+ * Accessibility: this readout ticks roughly once per second while active,
118
+ * which is exactly the kind of high-frequency update
119
+ * `<lyra-live-region>`/`Announcer` (`../../internal/announcer.js`) exists to
120
+ * *prevent* from being read aloud verbatim -- routing a per-second numeric
121
+ * tick through even a throttled announcer would still narrate a new number
122
+ * to a screen-reader user roughly once every throttle window for as long as
123
+ * generation runs, which is noise, not information. This component
124
+ * therefore carries no `role="status"`/`aria-live` of its own and never
125
+ * announces anything; a host that wants generation-start/-end announced
126
+ * should pair this with something that announces state *transitions* (e.g.
127
+ * `<lyra-typing-indicator>`'s mount-time announcement), not this ticking
128
+ * readout. The one genuinely actionable, infrequent control here -- the Stop
129
+ * button -- gets a normal, always-present `aria-label`, no different from
130
+ * any other icon-only button in this library.
131
+ *
132
+ * @customElement lyra-generation-status
133
+ * @event lyra-stop - The built-in Stop button was clicked. No detail payload.
134
+ * @csspart base - The root inline layout container.
135
+ * @csspart elapsed - The elapsed-time segment, e.g. `"12.3s"`. Always rendered (reads `"0.0s"` before the component has ever been active).
136
+ * @csspart tokens - The token-count segment, e.g. `"340 tokens"`. Only rendered when `token-count` is set.
137
+ * @csspart throughput - The throughput segment, e.g. `"27 tok/s"`. Only rendered when a value is available (host-supplied or derived; see the class doc).
138
+ * @csspart stop-button - The built-in Stop button. Only rendered while `show-stop` is true.
139
+ */
140
+ export class LyraGenerationStatus extends LyraElement {
141
+ constructor() {
142
+ super(...arguments);
143
+ /** Whether generation is currently in progress. The elapsed-time ticker
144
+ * runs only while this is `true` (see the class doc). */
145
+ this.active = false;
146
+ /** Whether the built-in Stop button renders at all. */
147
+ this.showStop = true;
148
+ // Recomputed on activation and on every ~1s tick; frozen (not reset) once
149
+ // `active` goes false -- see the class doc's "ticker" paragraph.
150
+ this.elapsedMs = 0;
151
+ this.onStopClick = () => {
152
+ this.emit('lyra-stop');
153
+ };
154
+ }
155
+ static { this.styles = [LyraElement.styles, styles]; }
156
+ disconnectedCallback() {
157
+ super.disconnectedCallback();
158
+ this.stopTicker();
159
+ }
160
+ // Recomputing `elapsedMs` here (rather than in `updated()`) matters: Lit
161
+ // runs `willUpdate()` *before* render, as part of the same update pass, so
162
+ // a property set here is picked up by this same render with no extra
163
+ // cycle. Setting a reactive property from inside `updated()` instead would
164
+ // schedule a *second* update after the first has already completed (Lit
165
+ // warns about exactly this in dev mode) -- meaning a caller doing
166
+ // `el.active = true; await el.updateComplete;` would still observe the
167
+ // stale pre-activation `elapsedMs` once that first promise resolves.
168
+ //
169
+ // `changed.has('active')` fires on the very first update too when the
170
+ // element mounts already `active` (the parsed-attribute/property value
171
+ // differs from the `false` field-initializer default that was seen first)
172
+ // -- same mechanism `<lyra-stream-status>`'s `onPhaseChanged` relies on to
173
+ // arm its stall timer on a `phase="streaming"` mount, so mounting this
174
+ // component already active correctly seeds `elapsedMs` with no separate
175
+ // first-update special case needed.
176
+ willUpdate(changed) {
177
+ if (changed.has('active') && this.active) {
178
+ if (this.startedAt == null)
179
+ this.fallbackStartMs = Date.now();
180
+ this.elapsedMs = this.computeElapsedMs();
181
+ }
182
+ else if (this.active && changed.has('startedAt')) {
183
+ // A `started-at` that arrives (or changes) mid-generation should
184
+ // immediately re-baseline the displayed elapsed time rather than wait
185
+ // up to ~1s for the next tick.
186
+ this.elapsedMs = this.computeElapsedMs();
187
+ }
188
+ }
189
+ // Starting/stopping the interval is a genuine side effect (not a reactive-
190
+ // property write), so it belongs in `updated()`, unlike the `elapsedMs`
191
+ // computation above.
192
+ updated(changed) {
193
+ if (changed.has('active')) {
194
+ if (this.active)
195
+ this.startTicker();
196
+ else
197
+ this.stopTicker();
198
+ }
199
+ }
200
+ startTicker() {
201
+ this.stopTicker();
202
+ // Setting `elapsedMs` here (unlike inside `updated()`, see that method's
203
+ // doc) is fine: an interval callback is a wholly separate future task,
204
+ // not a continuation of an in-progress Lit update, so this starts a
205
+ // normal, self-contained update cycle rather than a same-tick "second
206
+ // update" scheduled mid-render.
207
+ this.tickTimer = setInterval(() => {
208
+ this.elapsedMs = this.computeElapsedMs();
209
+ }, 1000);
210
+ }
211
+ stopTicker() {
212
+ if (this.tickTimer !== undefined) {
213
+ clearInterval(this.tickTimer);
214
+ this.tickTimer = undefined;
215
+ }
216
+ }
217
+ computeElapsedMs() {
218
+ const start = this.startedAt ?? this.fallbackStartMs;
219
+ return start == null ? 0 : Math.max(0, Date.now() - start);
220
+ }
221
+ /** `tokens-per-second` when set; otherwise a derived figure once enough
222
+ * elapsed time has accumulated for it to be meaningful; otherwise
223
+ * `undefined` (the throughput segment doesn't render at all). */
224
+ get effectiveTokensPerSecond() {
225
+ if (this.tokensPerSecond != null && Number.isFinite(this.tokensPerSecond)) {
226
+ return this.tokensPerSecond;
227
+ }
228
+ if (this.tokenCount != null && Number.isFinite(this.tokenCount)) {
229
+ const elapsedSeconds = this.elapsedMs / 1000;
230
+ if (elapsedSeconds >= 1)
231
+ return this.tokenCount / elapsedSeconds;
232
+ }
233
+ return undefined;
234
+ }
235
+ render() {
236
+ const hasTokens = this.tokenCount != null && Number.isFinite(this.tokenCount);
237
+ const throughput = this.effectiveTokensPerSecond;
238
+ const hasThroughput = throughput !== undefined;
239
+ return html `
240
+ <div part="base">
241
+ <span part="elapsed">${formatElapsed(this.elapsedMs)}</span>
242
+ ${hasTokens ? html `<span part="tokens">${formatTokenCount(this.tokenCount)}</span>` : nothing}
243
+ ${hasThroughput ? html `<span part="throughput">${formatThroughput(throughput)}</span>` : nothing}
244
+ ${this.showStop
245
+ ? html `
246
+ <button part="stop-button" type="button" aria-label="Stop generating" @click=${this.onStopClick}>
247
+ ${stopIcon()}
248
+ </button>
249
+ `
250
+ : nothing}
251
+ </div>
252
+ `;
253
+ }
254
+ }
255
+ __decorate([
256
+ property({ type: Boolean, reflect: true })
257
+ ], LyraGenerationStatus.prototype, "active", void 0);
258
+ __decorate([
259
+ property({ type: Number, attribute: 'started-at' })
260
+ ], LyraGenerationStatus.prototype, "startedAt", void 0);
261
+ __decorate([
262
+ property({ type: Number, attribute: 'token-count' })
263
+ ], LyraGenerationStatus.prototype, "tokenCount", void 0);
264
+ __decorate([
265
+ property({ type: Number, attribute: 'tokens-per-second' })
266
+ ], LyraGenerationStatus.prototype, "tokensPerSecond", void 0);
267
+ __decorate([
268
+ property({ type: Boolean, attribute: 'show-stop' })
269
+ ], LyraGenerationStatus.prototype, "showStop", void 0);
270
+ __decorate([
271
+ state()
272
+ ], LyraGenerationStatus.prototype, "elapsedMs", void 0);
273
+ defineElement('generation-status', LyraGenerationStatus);
@@ -0,0 +1 @@
1
+ export declare const styles: import("lit").CSSResult;
@@ -0,0 +1,84 @@
1
+ import { css } from 'lit';
2
+ export const styles = css `
3
+ :host {
4
+ display: inline-flex;
5
+ vertical-align: middle;
6
+ max-inline-size: 100%;
7
+ }
8
+
9
+ [part='base'] {
10
+ display: inline-flex;
11
+ align-items: center;
12
+ max-inline-size: 100%;
13
+ font-size: 0.8125rem;
14
+ line-height: 1.3;
15
+ color: var(--lyra-color-text-quiet);
16
+ }
17
+
18
+ [part='elapsed'] {
19
+ /* Full-strength text, not the quieter --lyra-color-text-quiet the rest
20
+ of the readout uses -- elapsed time is the one figure this component
21
+ always shows (tokens/throughput are optional), so it gets the higher-
22
+ contrast treatment to read as the primary value at a glance. */
23
+ color: var(--lyra-color-text);
24
+ font-variant-numeric: tabular-nums;
25
+ white-space: nowrap;
26
+ }
27
+ [part='tokens'],
28
+ [part='throughput'] {
29
+ font-variant-numeric: tabular-nums;
30
+ white-space: nowrap;
31
+ }
32
+
33
+ /* Segments are joined with a middot rather than a flex gap + separate
34
+ separator element, so a segment that doesn't render (tokens/throughput
35
+ are both optional, see the class doc) never leaves a dangling
36
+ double-gap -- the dot only ever appears immediately before a segment
37
+ that's actually present. */
38
+ [part='tokens']::before,
39
+ [part='throughput']::before {
40
+ content: '·';
41
+ margin-inline: 0.4em;
42
+ opacity: 0.6;
43
+ }
44
+
45
+ [part='stop-button'] {
46
+ flex: 0 0 auto;
47
+ display: inline-flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ /* Same "shrink the shared icon-button token for a compact inline
51
+ control" idiom as lyra-attachment-chip's retry-/remove-button. */
52
+ min-inline-size: min(var(--lyra-icon-button-size), 1.75rem);
53
+ min-block-size: min(var(--lyra-icon-button-size), 1.75rem);
54
+ margin-inline-start: var(--lyra-space-s);
55
+ padding: 0;
56
+ border: 1px solid var(--lyra-color-border);
57
+ border-radius: 50%;
58
+ background: var(--lyra-color-surface);
59
+ color: var(--lyra-color-text);
60
+ cursor: pointer;
61
+ -webkit-tap-highlight-color: transparent;
62
+ transition:
63
+ background-color var(--lyra-transition-fast),
64
+ border-color var(--lyra-transition-fast),
65
+ color var(--lyra-transition-fast);
66
+ }
67
+ [part='stop-button']:hover {
68
+ border-color: var(--lyra-color-brand);
69
+ color: var(--lyra-color-brand);
70
+ }
71
+ [part='stop-button']:focus-visible {
72
+ outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
73
+ outline-offset: var(--lyra-focus-ring-offset);
74
+ }
75
+ [part='stop-button'] svg {
76
+ display: block;
77
+ }
78
+
79
+ @media (prefers-reduced-motion: reduce) {
80
+ [part='stop-button'] {
81
+ transition: none !important;
82
+ }
83
+ }
84
+ `;
@@ -23,7 +23,10 @@ export declare function parseIsoDate(iso: string): Date;
23
23
  * string yields an `Invalid Date` (`getTime()` is `NaN`), and letting that
24
24
  * single `NaN` reach the min/max below would poison `firstWeekStart` (and
25
25
  * therefore every cell's `week`) for the whole grid instead of just the bad
26
- * entry.
26
+ * entry. Likewise, an entry whose `date` is numerically well-formed but
27
+ * calendar-invalid (e.g. `'2026-02-30'`, which `Date.UTC` silently rolls
28
+ * over into March) is dropped rather than silently renormalized — see
29
+ * `isCalendarValid()`.
27
30
  */
28
31
  export declare function buildCalendarGrid(days: CalendarDay[]): {
29
32
  cells: CalendarCell[];