@aceshooting/lyra-ui 1.2.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/README.md +98 -14
  2. package/custom-elements.json +30279 -12124
  3. package/dist/components/app-rail/app-rail-item.d.ts +30 -0
  4. package/dist/components/app-rail/app-rail-item.js +68 -0
  5. package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
  6. package/dist/components/app-rail/app-rail-item.styles.js +65 -0
  7. package/dist/components/app-rail/app-rail.d.ts +168 -0
  8. package/dist/components/app-rail/app-rail.js +419 -0
  9. package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
  10. package/dist/components/app-rail/app-rail.styles.js +128 -0
  11. package/dist/components/attachment-chip/attachment-chip.d.ts +141 -0
  12. package/dist/components/attachment-chip/attachment-chip.js +356 -0
  13. package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
  14. package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
  15. package/dist/components/attachment-trigger/attachment-trigger.d.ts +96 -0
  16. package/dist/components/attachment-trigger/attachment-trigger.js +270 -0
  17. package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
  18. package/dist/components/attachment-trigger/attachment-trigger.styles.js +90 -0
  19. package/dist/components/chart/bar-chart.js +2 -18
  20. package/dist/components/chart/box-plot.d.ts +25 -1
  21. package/dist/components/chart/box-plot.js +147 -7
  22. package/dist/components/chart/box-plot.styles.js +13 -0
  23. package/dist/components/chart/bubble-chart.js +2 -18
  24. package/dist/components/chart/chart-loader.d.ts +44 -13
  25. package/dist/components/chart/chart-loader.js +65 -18
  26. package/dist/components/chart/chart.d.ts +55 -12
  27. package/dist/components/chart/chart.js +247 -49
  28. package/dist/components/chart/doughnut-chart.js +2 -18
  29. package/dist/components/chart/histogram-bin.d.ts +7 -1
  30. package/dist/components/chart/histogram-bin.js +32 -14
  31. package/dist/components/chart/histogram.js +8 -16
  32. package/dist/components/chart/line-chart.js +2 -18
  33. package/dist/components/chart/lite-chart.d.ts +134 -3
  34. package/dist/components/chart/lite-chart.js +382 -67
  35. package/dist/components/chart/lite-chart.styles.js +9 -0
  36. package/dist/components/chart/pie-chart.js +2 -18
  37. package/dist/components/chart/polar-area-chart.js +2 -18
  38. package/dist/components/chart/radar-chart.js +2 -18
  39. package/dist/components/chart/scatter-chart.js +2 -18
  40. package/dist/components/chat-composer/chat-composer.d.ts +133 -0
  41. package/dist/components/chat-composer/chat-composer.js +366 -0
  42. package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
  43. package/dist/components/chat-composer/chat-composer.styles.js +145 -0
  44. package/dist/components/chat-message/chat-message.d.ts +141 -0
  45. package/dist/components/chat-message/chat-message.js +331 -0
  46. package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
  47. package/dist/components/chat-message/chat-message.styles.js +203 -0
  48. package/dist/components/checkbox/checkbox.d.ts +117 -0
  49. package/dist/components/checkbox/checkbox.js +353 -0
  50. package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
  51. package/dist/components/checkbox/checkbox.styles.js +77 -0
  52. package/dist/components/chip/chip-group.d.ts +56 -0
  53. package/dist/components/chip/chip-group.js +130 -0
  54. package/dist/components/chip/chip-group.styles.d.ts +1 -0
  55. package/dist/components/chip/chip-group.styles.js +57 -0
  56. package/dist/components/chip/chip.d.ts +64 -0
  57. package/dist/components/chip/chip.js +122 -0
  58. package/dist/components/chip/chip.styles.d.ts +1 -0
  59. package/dist/components/chip/chip.styles.js +115 -0
  60. package/dist/components/citation-badge/citation-badge.d.ts +113 -0
  61. package/dist/components/citation-badge/citation-badge.js +318 -0
  62. package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
  63. package/dist/components/citation-badge/citation-badge.styles.js +96 -0
  64. package/dist/components/code-block/code-block.d.ts +127 -0
  65. package/dist/components/code-block/code-block.js +382 -0
  66. package/dist/components/code-block/code-block.styles.d.ts +1 -0
  67. package/dist/components/code-block/code-block.styles.js +187 -0
  68. package/dist/components/code-block/code-loader.d.ts +87 -0
  69. package/dist/components/code-block/code-loader.js +142 -0
  70. package/dist/components/combobox/combobox.d.ts +65 -6
  71. package/dist/components/combobox/combobox.js +258 -48
  72. package/dist/components/combobox/combobox.styles.js +3 -3
  73. package/dist/components/combobox/option.d.ts +5 -1
  74. package/dist/components/combobox/option.js +35 -0
  75. package/dist/components/context-meter/context-meter.d.ts +53 -0
  76. package/dist/components/context-meter/context-meter.js +159 -0
  77. package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
  78. package/dist/components/context-meter/context-meter.styles.js +114 -0
  79. package/dist/components/conversation-item/conversation-item.d.ts +125 -0
  80. package/dist/components/conversation-item/conversation-item.js +331 -0
  81. package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
  82. package/dist/components/conversation-item/conversation-item.styles.js +155 -0
  83. package/dist/components/date-picker/calendar-core.d.ts +24 -0
  84. package/dist/components/date-picker/calendar-core.js +51 -4
  85. package/dist/components/date-picker/date-input.d.ts +100 -9
  86. package/dist/components/date-picker/date-input.js +383 -66
  87. package/dist/components/date-picker/date-picker.d.ts +35 -4
  88. package/dist/components/date-picker/date-picker.js +171 -44
  89. package/dist/components/dialog/confirm.d.ts +40 -0
  90. package/dist/components/dialog/confirm.js +76 -0
  91. package/dist/components/dialog/dialog.d.ts +129 -0
  92. package/dist/components/dialog/dialog.js +288 -0
  93. package/dist/components/dialog/dialog.styles.d.ts +1 -0
  94. package/dist/components/dialog/dialog.styles.js +96 -0
  95. package/dist/components/dock-panel/dock-panel.d.ts +142 -0
  96. package/dist/components/dock-panel/dock-panel.js +359 -0
  97. package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
  98. package/dist/components/dock-panel/dock-panel.styles.js +159 -0
  99. package/dist/components/document-preview/document-preview.d.ts +143 -0
  100. package/dist/components/document-preview/document-preview.js +388 -0
  101. package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
  102. package/dist/components/document-preview/document-preview.styles.js +191 -0
  103. package/dist/components/empty/empty.d.ts +1 -2
  104. package/dist/components/empty/empty.js +18 -12
  105. package/dist/components/empty/empty.styles.js +0 -3
  106. package/dist/components/export-button/csv.js +1 -1
  107. package/dist/components/export-button/export-button.d.ts +12 -0
  108. package/dist/components/export-button/export-button.js +35 -5
  109. package/dist/components/export-button/export-button.styles.js +5 -1
  110. package/dist/components/file-input/accept.js +2 -0
  111. package/dist/components/file-input/file-input.d.ts +10 -1
  112. package/dist/components/file-input/file-input.js +36 -5
  113. package/dist/components/flag/flag.d.ts +29 -13
  114. package/dist/components/flag/flag.js +54 -14
  115. package/dist/components/flag/flag.styles.js +1 -1
  116. package/dist/components/flag/language-map.d.ts +4 -1
  117. package/dist/components/flag/language-map.js +6 -3
  118. package/dist/components/gauge/gauge.d.ts +10 -1
  119. package/dist/components/gauge/gauge.js +41 -13
  120. package/dist/components/generation-status/generation-status.d.ts +117 -0
  121. package/dist/components/generation-status/generation-status.js +327 -0
  122. package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
  123. package/dist/components/generation-status/generation-status.styles.js +84 -0
  124. package/dist/components/graph/graph.d.ts +37 -3
  125. package/dist/components/graph/graph.js +132 -20
  126. package/dist/components/heatmap/calendar-grid.d.ts +19 -7
  127. package/dist/components/heatmap/calendar-grid.js +42 -18
  128. package/dist/components/heatmap/heatmap-scale.d.ts +11 -1
  129. package/dist/components/heatmap/heatmap-scale.js +14 -2
  130. package/dist/components/heatmap/heatmap.d.ts +227 -12
  131. package/dist/components/heatmap/heatmap.js +488 -93
  132. package/dist/components/json-viewer/json-viewer.d.ts +70 -0
  133. package/dist/components/json-viewer/json-viewer.js +361 -0
  134. package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
  135. package/dist/components/json-viewer/json-viewer.styles.js +177 -0
  136. package/dist/components/kbd/kbd.d.ts +77 -0
  137. package/dist/components/kbd/kbd.js +231 -0
  138. package/dist/components/kbd/kbd.styles.d.ts +1 -0
  139. package/dist/components/kbd/kbd.styles.js +52 -0
  140. package/dist/components/live-region/live-region.d.ts +90 -0
  141. package/dist/components/live-region/live-region.js +189 -0
  142. package/dist/components/live-region/live-region.styles.d.ts +1 -0
  143. package/dist/components/live-region/live-region.styles.js +10 -0
  144. package/dist/components/map/map.d.ts +32 -7
  145. package/dist/components/map/map.js +133 -32
  146. package/dist/components/markdown/markdown-loader.d.ts +58 -0
  147. package/dist/components/markdown/markdown-loader.js +77 -0
  148. package/dist/components/markdown/markdown.d.ts +119 -0
  149. package/dist/components/markdown/markdown.js +389 -0
  150. package/dist/components/markdown/markdown.styles.d.ts +1 -0
  151. package/dist/components/markdown/markdown.styles.js +88 -0
  152. package/dist/components/media-card/media-card.d.ts +130 -0
  153. package/dist/components/media-card/media-card.js +273 -0
  154. package/dist/components/media-card/media-card.styles.d.ts +1 -0
  155. package/dist/components/media-card/media-card.styles.js +132 -0
  156. package/dist/components/mention-popover/mention-popover.d.ts +203 -0
  157. package/dist/components/mention-popover/mention-popover.js +493 -0
  158. package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
  159. package/dist/components/mention-popover/mention-popover.styles.js +101 -0
  160. package/dist/components/menu/menu-item.d.ts +91 -0
  161. package/dist/components/menu/menu-item.js +206 -0
  162. package/dist/components/menu/menu-item.styles.d.ts +1 -0
  163. package/dist/components/menu/menu-item.styles.js +75 -0
  164. package/dist/components/menu/menu.d.ts +167 -0
  165. package/dist/components/menu/menu.js +461 -0
  166. package/dist/components/menu/menu.styles.d.ts +1 -0
  167. package/dist/components/menu/menu.styles.js +67 -0
  168. package/dist/components/model-select/model-select.d.ts +170 -0
  169. package/dist/components/model-select/model-select.js +588 -0
  170. package/dist/components/model-select/model-select.styles.d.ts +1 -0
  171. package/dist/components/model-select/model-select.styles.js +203 -0
  172. package/dist/components/model-settings-panel/model-settings-panel.d.ts +93 -0
  173. package/dist/components/model-settings-panel/model-settings-panel.js +209 -0
  174. package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
  175. package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
  176. package/dist/components/playback/playback.d.ts +19 -3
  177. package/dist/components/playback/playback.js +109 -33
  178. package/dist/components/playback/playback.styles.js +6 -1
  179. package/dist/components/responsive-panel/responsive-panel.d.ts +163 -0
  180. package/dist/components/responsive-panel/responsive-panel.js +363 -0
  181. package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
  182. package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
  183. package/dist/components/result-card/result-card.d.ts +50 -0
  184. package/dist/components/result-card/result-card.js +89 -0
  185. package/dist/components/result-card/result-card.styles.d.ts +1 -0
  186. package/dist/components/result-card/result-card.styles.js +49 -0
  187. package/dist/components/result-card/result-field.d.ts +36 -0
  188. package/dist/components/result-card/result-field.js +87 -0
  189. package/dist/components/result-card/result-field.styles.d.ts +1 -0
  190. package/dist/components/result-card/result-field.styles.js +32 -0
  191. package/dist/components/select/select.d.ts +84 -4
  192. package/dist/components/select/select.js +251 -36
  193. package/dist/components/skeleton/skeleton.d.ts +3 -0
  194. package/dist/components/skeleton/skeleton.js +7 -1
  195. package/dist/components/skeleton/skeleton.styles.js +5 -4
  196. package/dist/components/slider/slider.d.ts +141 -0
  197. package/dist/components/slider/slider.js +467 -0
  198. package/dist/components/slider/slider.styles.d.ts +1 -0
  199. package/dist/components/slider/slider.styles.js +87 -0
  200. package/dist/components/source-card/source-card.d.ts +104 -0
  201. package/dist/components/source-card/source-card.js +195 -0
  202. package/dist/components/source-card/source-card.styles.d.ts +1 -0
  203. package/dist/components/source-card/source-card.styles.js +69 -0
  204. package/dist/components/source-list/source-list.d.ts +63 -0
  205. package/dist/components/source-list/source-list.js +130 -0
  206. package/dist/components/source-list/source-list.styles.d.ts +1 -0
  207. package/dist/components/source-list/source-list.styles.js +59 -0
  208. package/dist/components/sparkline/sparkline.js +58 -20
  209. package/dist/components/split/split.d.ts +224 -5
  210. package/dist/components/split/split.js +617 -43
  211. package/dist/components/split/split.styles.js +47 -0
  212. package/dist/components/stat/stat.d.ts +15 -4
  213. package/dist/components/stat/stat.js +53 -12
  214. package/dist/components/stream-status/stream-status.d.ts +126 -0
  215. package/dist/components/stream-status/stream-status.js +292 -0
  216. package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
  217. package/dist/components/stream-status/stream-status.styles.js +103 -0
  218. package/dist/components/streaming-text/streaming-text.d.ts +104 -0
  219. package/dist/components/streaming-text/streaming-text.js +224 -0
  220. package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
  221. package/dist/components/streaming-text/streaming-text.styles.js +63 -0
  222. package/dist/components/switch/switch.d.ts +103 -0
  223. package/dist/components/switch/switch.js +250 -0
  224. package/dist/components/switch/switch.styles.d.ts +1 -0
  225. package/dist/components/switch/switch.styles.js +75 -0
  226. package/dist/components/table/table.d.ts +89 -5
  227. package/dist/components/table/table.js +243 -26
  228. package/dist/components/table/table.styles.js +6 -1
  229. package/dist/components/tabs/tabs.d.ts +74 -0
  230. package/dist/components/tabs/tabs.js +254 -0
  231. package/dist/components/tabs/tabs.styles.d.ts +1 -0
  232. package/dist/components/tabs/tabs.styles.js +74 -0
  233. package/dist/components/thinking-panel/thinking-panel.d.ts +123 -0
  234. package/dist/components/thinking-panel/thinking-panel.js +260 -0
  235. package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
  236. package/dist/components/thinking-panel/thinking-panel.styles.js +123 -0
  237. package/dist/components/time-range/time-range.d.ts +59 -2
  238. package/dist/components/time-range/time-range.js +163 -67
  239. package/dist/components/toast/toast-item.d.ts +12 -2
  240. package/dist/components/toast/toast-item.js +106 -44
  241. package/dist/components/toast/toast-item.styles.js +59 -28
  242. package/dist/components/toast/toast.js +17 -5
  243. package/dist/components/toast/toaster.js +10 -1
  244. package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +131 -0
  245. package/dist/components/tool-approval-dialog/tool-approval-dialog.js +329 -0
  246. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
  247. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
  248. package/dist/components/tool-call-chip/tool-call-chip.d.ts +105 -0
  249. package/dist/components/tool-call-chip/tool-call-chip.js +349 -0
  250. package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
  251. package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
  252. package/dist/components/tool-param-form/tool-param-form.d.ts +206 -0
  253. package/dist/components/tool-param-form/tool-param-form.js +610 -0
  254. package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
  255. package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
  256. package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +122 -0
  257. package/dist/components/tool-result-dialog/tool-result-dialog.js +358 -0
  258. package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
  259. package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
  260. package/dist/components/tool-result-view/registry.d.ts +73 -0
  261. package/dist/components/tool-result-view/registry.js +89 -0
  262. package/dist/components/tool-result-view/tool-result-view.d.ts +58 -0
  263. package/dist/components/tool-result-view/tool-result-view.js +152 -0
  264. package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
  265. package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
  266. package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
  267. package/dist/components/tool-select-dialog/tool-select-dialog.js +350 -0
  268. package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
  269. package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +191 -0
  270. package/dist/components/tree/tree-node.d.ts +15 -3
  271. package/dist/components/tree/tree-node.js +20 -7
  272. package/dist/components/tree/tree.d.ts +25 -10
  273. package/dist/components/tree/tree.js +39 -31
  274. package/dist/components/typing-indicator/typing-indicator.d.ts +70 -0
  275. package/dist/components/typing-indicator/typing-indicator.js +108 -0
  276. package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
  277. package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
  278. package/dist/components/virtual-list/virtual-list.d.ts +210 -0
  279. package/dist/components/virtual-list/virtual-list.js +607 -0
  280. package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
  281. package/dist/components/virtual-list/virtual-list.styles.js +56 -0
  282. package/dist/components/widget/widget.d.ts +5 -4
  283. package/dist/components/widget/widget.js +54 -120
  284. package/dist/components/widget/widget.styles.js +8 -2
  285. package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
  286. package/dist/components/word-cloud/word-cloud-layout.js +29 -2
  287. package/dist/components/word-cloud/word-cloud.d.ts +28 -2
  288. package/dist/components/word-cloud/word-cloud.js +69 -19
  289. package/dist/components/word-cloud/word-cloud.styles.js +16 -3
  290. package/dist/internal/anchored-validity.d.ts +1 -0
  291. package/dist/internal/anchored-validity.js +86 -0
  292. package/dist/internal/announcer.d.ts +57 -0
  293. package/dist/internal/announcer.js +71 -0
  294. package/dist/internal/form-associated.d.ts +8 -0
  295. package/dist/internal/form-associated.js +98 -15
  296. package/dist/internal/group-by-recency.d.ts +50 -0
  297. package/dist/internal/group-by-recency.js +80 -0
  298. package/dist/internal/numbers.d.ts +12 -0
  299. package/dist/internal/numbers.js +26 -0
  300. package/dist/internal/overlay-manager.d.ts +51 -0
  301. package/dist/internal/overlay-manager.js +523 -0
  302. package/dist/internal/positioner.js +27 -3
  303. package/dist/internal/rtl.d.ts +23 -0
  304. package/dist/internal/rtl.js +28 -0
  305. package/dist/internal/safe-url.d.ts +12 -0
  306. package/dist/internal/safe-url.js +41 -0
  307. package/dist/internal/scroll-lock.d.ts +10 -5
  308. package/dist/internal/scroll-lock.js +30 -14
  309. package/dist/internal/tokens.styles.js +22 -10
  310. package/dist/lyra.d.ts +133 -31
  311. package/dist/lyra.js +96 -26
  312. package/llms-full.txt +4546 -183
  313. package/llms.txt +21 -5
  314. package/package.json +41 -6
  315. package/dist/components/chart/bar-chart.stories.d.ts +0 -5
  316. package/dist/components/chart/bar-chart.stories.js +0 -20
  317. package/dist/components/chart/box-plot.stories.d.ts +0 -5
  318. package/dist/components/chart/box-plot.stories.js +0 -29
  319. package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
  320. package/dist/components/chart/bubble-chart.stories.js +0 -26
  321. package/dist/components/chart/chart.stories.d.ts +0 -32
  322. package/dist/components/chart/chart.stories.js +0 -141
  323. package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
  324. package/dist/components/chart/doughnut-chart.stories.js +0 -26
  325. package/dist/components/chart/histogram.stories.d.ts +0 -5
  326. package/dist/components/chart/histogram.stories.js +0 -17
  327. package/dist/components/chart/line-chart.stories.d.ts +0 -22
  328. package/dist/components/chart/line-chart.stories.js +0 -99
  329. package/dist/components/chart/lite-chart.stories.d.ts +0 -14
  330. package/dist/components/chart/lite-chart.stories.js +0 -114
  331. package/dist/components/chart/pie-chart.stories.d.ts +0 -5
  332. package/dist/components/chart/pie-chart.stories.js +0 -26
  333. package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
  334. package/dist/components/chart/polar-area-chart.stories.js +0 -20
  335. package/dist/components/chart/radar-chart.stories.d.ts +0 -5
  336. package/dist/components/chart/radar-chart.stories.js +0 -20
  337. package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
  338. package/dist/components/chart/scatter-chart.stories.js +0 -31
  339. package/dist/components/combobox/combobox.stories.d.ts +0 -24
  340. package/dist/components/combobox/combobox.stories.js +0 -102
  341. package/dist/components/date-picker/date-input.stories.d.ts +0 -10
  342. package/dist/components/date-picker/date-input.stories.js +0 -48
  343. package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
  344. package/dist/components/date-picker/date-picker.stories.js +0 -25
  345. package/dist/components/empty/empty.stories.d.ts +0 -7
  346. package/dist/components/empty/empty.stories.js +0 -34
  347. package/dist/components/export-button/export-button.stories.d.ts +0 -7
  348. package/dist/components/export-button/export-button.stories.js +0 -37
  349. package/dist/components/file-input/file-input.stories.d.ts +0 -7
  350. package/dist/components/file-input/file-input.stories.js +0 -19
  351. package/dist/components/flag/flag.stories.d.ts +0 -6
  352. package/dist/components/flag/flag.stories.js +0 -31
  353. package/dist/components/gauge/gauge.stories.d.ts +0 -8
  354. package/dist/components/gauge/gauge.stories.js +0 -19
  355. package/dist/components/graph/graph.stories.d.ts +0 -8
  356. package/dist/components/graph/graph.stories.js +0 -68
  357. package/dist/components/heatmap/heatmap.stories.d.ts +0 -27
  358. package/dist/components/heatmap/heatmap.stories.js +0 -179
  359. package/dist/components/map/map.stories.d.ts +0 -15
  360. package/dist/components/map/map.stories.js +0 -135
  361. package/dist/components/playback/playback.stories.d.ts +0 -7
  362. package/dist/components/playback/playback.stories.js +0 -16
  363. package/dist/components/select/select.stories.d.ts +0 -21
  364. package/dist/components/select/select.stories.js +0 -91
  365. package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
  366. package/dist/components/skeleton/skeleton.stories.js +0 -16
  367. package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
  368. package/dist/components/sparkline/sparkline.stories.js +0 -39
  369. package/dist/components/split/split.stories.d.ts +0 -7
  370. package/dist/components/split/split.stories.js +0 -36
  371. package/dist/components/stat/stat.stories.d.ts +0 -9
  372. package/dist/components/stat/stat.stories.js +0 -81
  373. package/dist/components/table/table.stories.d.ts +0 -12
  374. package/dist/components/table/table.stories.js +0 -67
  375. package/dist/components/time-range/time-range.stories.d.ts +0 -8
  376. package/dist/components/time-range/time-range.stories.js +0 -26
  377. package/dist/components/toast/toast.stories.d.ts +0 -8
  378. package/dist/components/toast/toast.stories.js +0 -72
  379. package/dist/components/tree/tree.stories.d.ts +0 -9
  380. package/dist/components/tree/tree.stories.js +0 -52
  381. package/dist/components/widget/widget.stories.d.ts +0 -9
  382. package/dist/components/widget/widget.stories.js +0 -74
  383. package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
  384. package/dist/components/word-cloud/word-cloud.stories.js +0 -55
@@ -0,0 +1,389 @@
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 } from 'lit';
8
+ import { property, state } from 'lit/decorators.js';
9
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
10
+ import { LyraElement } from '../../internal/lyra-element.js';
11
+ import { defineElement } from '../../internal/prefix.js';
12
+ import { loadMarkdownDeps, getMarkdownDepsIfLoaded } from './markdown-loader.js';
13
+ import { styles } from './markdown.styles.js';
14
+ const HTML_ESCAPES = {
15
+ '&': '&amp;',
16
+ '<': '&lt;',
17
+ '>': '&gt;',
18
+ '"': '&quot;',
19
+ "'": '&#39;',
20
+ };
21
+ function escapeHtml(text) {
22
+ return text.replace(/[&<>"']/g, (ch) => HTML_ESCAPES[ch] ?? ch);
23
+ }
24
+ /**
25
+ * Mirrors marked's own default `link()` renderer's `cleanUrl()`: a malformed
26
+ * percent-escape or lone UTF-16 surrogate in the raw href throws inside
27
+ * `encodeURI`, and marked's default renderer responds by dropping the anchor
28
+ * (rendering the link text alone) rather than emitting a broken `href` —
29
+ * returning `null` here lets the caller do the same. The
30
+ * `.replace(/%25/g, '%')` compensates for `encodeURI` re-escaping the `%` of
31
+ * an href that was already percent-encoded (the common case for a real
32
+ * markdown link) — without it, every existing `%XX` escape would become
33
+ * `%25XX`, double-encoding it.
34
+ */
35
+ function cleanHref(href) {
36
+ try {
37
+ return encodeURI(href).replace(/%25/g, '%');
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ }
43
+ /**
44
+ * `<lyra-markdown>` — sanitized Markdown-to-HTML rendering (GFM tables,
45
+ * fenced code blocks, links, blockquotes) built on the optional peer
46
+ * dependencies `marked` (parsing) and `dompurify` (sanitizing), both
47
+ * lazy-loaded via `markdown-loader.ts` on first connect.
48
+ *
49
+ * Rendering never ships unsanitized or broken markup silently:
50
+ * - If `marked` fails to load, or throws while parsing malformed input, the
51
+ * component falls back to plain text (`white-space: pre-wrap`, no HTML
52
+ * parsing at all) and fires `lyra-render-error`.
53
+ * - If `sanitize` is `true` (the default) and `dompurify` fails to load, the
54
+ * component *also* falls back to plain text + `lyra-render-error` — it
55
+ * never renders marked's raw HTML output when sanitization was requested
56
+ * (or defaulted to) but is unavailable, even though `marked` itself loaded
57
+ * fine.
58
+ * - If `sanitize` is explicitly `false`, marked's raw output renders as-is
59
+ * regardless of whether `dompurify` is installed — the consumer opted out
60
+ * of sanitization, so `dompurify`'s absence is irrelevant to that path.
61
+ *
62
+ * That same plain-text fallback rendering (`data-fallback` on the `content`
63
+ * part) is also, unconditionally and by default, a brief *transient* state on
64
+ * every connect, not just a failure path: `connectedCallback()`'s dynamic
65
+ * `import()` of `marked`/`dompurify` (see `markdown-loader.ts`) is
66
+ * asynchronous, so the very first paint of any `<lyra-markdown>` on a page
67
+ * shows plain text for at least one microtask — even when both peers are
68
+ * already installed and load without error — until that import resolves and
69
+ * a second render replaces it with the real Markdown output. Set
70
+ * `eager-load` to skip that window once the shared dependency cache is
71
+ * already warm; see that property's doc for exactly what "warm" requires.
72
+ *
73
+ * `heading`/`code`/`blockquote`/`table`/`link`/`image` tokens are rendered
74
+ * through a `marked` renderer override that injects `part="..."` attributes
75
+ * directly into the produced HTML — a single pass, not a second DOM walk
76
+ * after insertion.
77
+ *
78
+ * @customElement lyra-markdown
79
+ * @event lyra-link-click - Fired (and the click prevented) when a rendered
80
+ * link's `href` starts with `internal-link-prefix`. `detail: { href:
81
+ * string, internal: true }`. Ordinary external links navigate normally
82
+ * (in `link-target`) and never fire this event.
83
+ * @event lyra-render-error - Fired whenever rendering falls back to plain
84
+ * text. `detail: { error: unknown }`.
85
+ * @csspart content - The wrapper around the rendered (or plain-text
86
+ * fallback) output.
87
+ * @csspart heading - Every rendered `<h1>`–`<h6>` (shifted by
88
+ * `heading-offset`).
89
+ * @csspart code-block - Every rendered fenced/indented `<pre>`.
90
+ * @csspart link - Every rendered `<a>`.
91
+ * @csspart table - Every rendered `<table>`.
92
+ * @csspart blockquote - Every rendered `<blockquote>`.
93
+ * @csspart img - Every rendered `<img>`.
94
+ */
95
+ export class LyraMarkdown extends LyraElement {
96
+ constructor() {
97
+ super(...arguments);
98
+ /** The Markdown source to render. */
99
+ this.content = '';
100
+ /** Sanitize marked's HTML output with DOMPurify before rendering. See the
101
+ * class doc for what happens when this is `true` (the default) but the
102
+ * `dompurify` peer isn't installed. */
103
+ this.sanitize = true;
104
+ /** Enable GitHub-flavored Markdown (tables, strikethrough, autolinks, task lists). */
105
+ this.gfm = true;
106
+ /** `target` applied to every rendered `<a>`, with `rel="noopener
107
+ * noreferrer"` always added alongside it whenever a `target` is emitted.
108
+ * `'_blank'` (the default) preserves today's exact output. Set to `null`
109
+ * (or the empty string, e.g. via the `link-target=""` attribute) to omit
110
+ * `target`/`rel` entirely, so rendered links open in the same tab. */
111
+ this.linkTarget = '_blank';
112
+ /** When set, a rendered link whose `href` starts with this prefix is
113
+ * treated as internal — its click is intercepted and reported via
114
+ * `lyra-link-click` instead of navigating. Empty (the default) means
115
+ * every link is treated as external. */
116
+ this.internalLinkPrefix = '';
117
+ /** Added to every rendered heading's source `token.depth` before emitting
118
+ * `<h${depth}>` — e.g. `heading-offset="2"` renders a source `#` as
119
+ * `<h3>` and a source `##` as `<h4>`. The result is clamped to `[1, 6]`
120
+ * (a source `######` with a positive offset stays at `<h6>` rather than
121
+ * overflowing past the HTML heading levels; the floor at `1` is
122
+ * defensive, since this property is meant to be additive-only). `0`
123
+ * (the default) preserves today's exact `<h${token.depth}>` output. */
124
+ this.headingOffset = 0;
125
+ /** When `true`, `connectedCallback()` skips awaiting `loadMarkdownDeps()`'s
126
+ * dynamic `import()` if the shared `marked`/`dompurify` module cache (see
127
+ * `markdown-loader.ts`'s `getMarkdownDepsIfLoaded()`) has *already*
128
+ * resolved — e.g. because an earlier `<lyra-markdown>` instance on the
129
+ * page already finished loading, or the consumer primed the cache
130
+ * directly by calling `loadMarkdownDeps()` themselves at startup — and
131
+ * renders synchronously instead. When the cache isn't warm yet (most
132
+ * notably: the very first `<lyra-markdown>` ever connected on a page,
133
+ * since nothing has called `loadMarkdownDeps()` before it), this still
134
+ * falls back to the normal async path — a dynamic `import()` can't be
135
+ * made synchronous, so this is a fast path for the common "already warm"
136
+ * case, not a hard guarantee. `false` (the default) is byte-identical to
137
+ * today: always the async `import()`, fallback-text window included. */
138
+ this.eagerLoad = false;
139
+ /** Forward-compatible hint for a dedicated streaming renderer expected to
140
+ * build on this component later (coalescing partial tokens as they
141
+ * arrive) — setting it has no rendering effect yet. Reflects so a
142
+ * consumer can already target `lyra-markdown[streaming]` in CSS ahead of
143
+ * that behavior landing. */
144
+ this.streaming = false;
145
+ // `null` covers both "the optional peers are still loading" and "a render
146
+ // attempt just fell back after a failure" — the two states intentionally
147
+ // look identical (plain text, see render()) since a consumer distinguishes
148
+ // them via `lyra-render-error`, not a visual difference.
149
+ this.renderedHtml = null;
150
+ // A single delegated listener on the content wrapper (not one per <a>) —
151
+ // the rendered markup is fully replaced on every content change, so a
152
+ // per-anchor listener would need re-attaching on every render anyway.
153
+ this.onContentClick = (e) => {
154
+ const prefix = this.internalLinkPrefix;
155
+ if (!prefix)
156
+ return;
157
+ const anchor = e.composedPath().find((el) => el instanceof HTMLAnchorElement);
158
+ if (!anchor)
159
+ return;
160
+ // Compared against the raw `href` *attribute*, not the `.href` IDL
161
+ // property — the property is always browser-resolved to an absolute URL
162
+ // (e.g. "https://example.com/docs") even for a relative/prefixed path,
163
+ // which would never match a relative `internal-link-prefix`.
164
+ const href = anchor.getAttribute('href') ?? '';
165
+ if (!href.startsWith(prefix))
166
+ return;
167
+ e.preventDefault();
168
+ this.emit('lyra-link-click', { href, internal: true });
169
+ };
170
+ }
171
+ static { this.styles = [LyraElement.styles, styles]; }
172
+ connectedCallback() {
173
+ super.connectedCallback();
174
+ if (this.eagerLoad) {
175
+ // Only takes this synchronous path when the shared module cache has
176
+ // *already* settled (see getMarkdownDepsIfLoaded()'s doc) -- otherwise
177
+ // falls through to the same async path as the default below, since a
178
+ // dynamic import() can't be made synchronous from scratch.
179
+ const alreadyLoaded = getMarkdownDepsIfLoaded();
180
+ if (alreadyLoaded) {
181
+ this.deps = alreadyLoaded;
182
+ this.renderMarkdown();
183
+ return;
184
+ }
185
+ }
186
+ void loadMarkdownDeps().then((resolved) => {
187
+ // The (module-cached, page-lifetime) loadMarkdownDeps() promise can
188
+ // resolve after this instance was removed from the DOM -- e.g. an
189
+ // <lyra-markdown> inside a conditionally-rendered chat message or a
190
+ // virtualized list. Without this guard, a detached instance would
191
+ // still have its `deps` set and renderMarkdown() called, mutating the
192
+ // @state() renderedHtml property and scheduling a Lit update no one
193
+ // will ever see. Mirrors chart.ts's own connectedCallback() guard for
194
+ // the identical race.
195
+ if (!this.isConnected)
196
+ return;
197
+ this.deps = resolved;
198
+ this.renderMarkdown();
199
+ });
200
+ }
201
+ // Runs before render (not updated()) so mutating the `renderedHtml` state
202
+ // property below is absorbed into the *same* update cycle instead of
203
+ // scheduling a second one -- Lit's documented pattern for deriving one
204
+ // reactive property from a change to others.
205
+ willUpdate(changed) {
206
+ if (!this.deps) {
207
+ // Still loading the optional peers — the connectedCallback promise
208
+ // above calls renderMarkdown() itself once they resolve, using
209
+ // whatever property values are current at that time.
210
+ return;
211
+ }
212
+ if (changed.has('content') ||
213
+ changed.has('sanitize') ||
214
+ changed.has('gfm') ||
215
+ changed.has('linkTarget') ||
216
+ changed.has('headingOffset')) {
217
+ this.renderMarkdown();
218
+ }
219
+ }
220
+ updated() {
221
+ if (this.deps) {
222
+ this.removeAttribute('aria-busy');
223
+ }
224
+ else {
225
+ this.setAttribute('aria-busy', 'true');
226
+ }
227
+ }
228
+ renderMarkdown() {
229
+ const deps = this.deps;
230
+ if (!deps)
231
+ return;
232
+ if (!deps.marked) {
233
+ // markdown-loader.ts already logged the specific import failure.
234
+ this.applyFallback(new Error('<lyra-markdown> could not render: the "marked" peer dependency failed to load.'));
235
+ return;
236
+ }
237
+ let rawHtml;
238
+ try {
239
+ rawHtml = this.parseMarkdown(deps.marked);
240
+ }
241
+ catch (error) {
242
+ this.applyFallback(error);
243
+ return;
244
+ }
245
+ if (!this.sanitize) {
246
+ // Consumer explicitly opted out of sanitization — dompurify's
247
+ // presence or absence is irrelevant to this path.
248
+ this.renderedHtml = rawHtml;
249
+ return;
250
+ }
251
+ if (!deps.DOMPurify) {
252
+ const error = new Error('<lyra-markdown> could not render: sanitize is enabled (the default) but the "dompurify" peer ' +
253
+ 'dependency failed to load — refusing to render unsanitized HTML. Install it with `pnpm add ' +
254
+ 'dompurify`, or set sanitize="false" to explicitly opt out of sanitization.');
255
+ console.warn(error.message);
256
+ this.applyFallback(error);
257
+ return;
258
+ }
259
+ // `target` is not in DOMPurify's default attribute allowlist (unlike
260
+ // `part`/`rel`/`class`, which already are) — without ADD_ATTR here,
261
+ // every rendered link's target="..." would be silently stripped even
262
+ // though the anchor itself survives sanitization.
263
+ this.renderedHtml = deps.DOMPurify.sanitize(rawHtml, { ADD_ATTR: ['target'] });
264
+ }
265
+ applyFallback(error) {
266
+ this.renderedHtml = null;
267
+ this.emit('lyra-render-error', { error });
268
+ }
269
+ parseMarkdown(marked) {
270
+ // Falsy (`null` or `''`) means the consumer explicitly opted out of
271
+ // target="..."/rel="..." on rendered links -- see the linkTarget doc.
272
+ // The default '_blank' is already truthy, so this preserves today's
273
+ // exact output when the property is left unset.
274
+ const linkTarget = this.linkTarget;
275
+ const headingOffset = this.headingOffset;
276
+ const instance = new marked.Marked();
277
+ // A fresh renderer per parse (rather than a shared/cached one) so it
278
+ // always closes over the *current* `linkTarget`/`headingOffset` — these
279
+ // properties can change between renders, and marked's `.use()` otherwise
280
+ // persists whatever renderer it was given for the lifetime of the
281
+ // instance.
282
+ instance.use({
283
+ renderer: {
284
+ heading(token) {
285
+ // Clamped to [1, 6]: a positive offset can never push a heading
286
+ // past <h6> (there is no <h7>), and the floor at 1 is defensive
287
+ // since headingOffset is meant to be additive-only (0 is the only
288
+ // documented non-positive value).
289
+ const depth = Math.min(6, Math.max(1, token.depth + headingOffset));
290
+ return `<h${depth} part="heading">${this.parser.parseInline(token.tokens)}</h${depth}>\n`;
291
+ },
292
+ code(token) {
293
+ const lang = (token.lang ?? '').trim().split(/\s+/)[0] ?? '';
294
+ const body = `${token.text.replace(/\n$/, '')}\n`;
295
+ const text = token.escaped ? body : escapeHtml(body);
296
+ const cls = lang ? ` class="language-${escapeHtml(lang)}"` : '';
297
+ return `<pre part="code-block"><code${cls}>${text}</code></pre>\n`;
298
+ },
299
+ blockquote(token) {
300
+ return `<blockquote part="blockquote">\n${this.parser.parse(token.tokens)}</blockquote>\n`;
301
+ },
302
+ table(token) {
303
+ // Built directly here (rather than delegating to the inherited
304
+ // tablecell()) so a scope="col" can be added -- marked's own
305
+ // default tablecell() never emits it, and without it a screen
306
+ // reader can't reliably associate a data cell with its column
307
+ // header beyond the simplest table.
308
+ let headerRow = '';
309
+ for (const cell of token.header) {
310
+ const text = this.parser.parseInline(cell.tokens);
311
+ const alignAttr = cell.align ? ` align="${cell.align}"` : '';
312
+ headerRow += `<th scope="col"${alignAttr}>${text}</th>`;
313
+ }
314
+ let bodyRows = '';
315
+ for (const row of token.rows) {
316
+ let rowHtml = '';
317
+ for (const cell of row)
318
+ rowHtml += this.tablecell(cell);
319
+ bodyRows += this.tablerow({ text: rowHtml });
320
+ }
321
+ const thead = `<thead>\n${this.tablerow({ text: headerRow })}</thead>\n`;
322
+ const tbody = bodyRows ? `<tbody>${bodyRows}</tbody>\n` : '';
323
+ return `<table part="table">\n${thead}${tbody}</table>\n`;
324
+ },
325
+ link(token) {
326
+ const text = this.parser.parseInline(token.tokens);
327
+ const href = cleanHref(token.href);
328
+ if (href === null)
329
+ return text;
330
+ const titleAttr = token.title ? ` title="${escapeHtml(token.title)}"` : '';
331
+ const targetAttr = linkTarget
332
+ ? ` target="${escapeHtml(linkTarget)}" rel="noopener noreferrer"`
333
+ : '';
334
+ return `<a part="link" href="${escapeHtml(href)}"${titleAttr}${targetAttr}>${text}</a>`;
335
+ },
336
+ image(token) {
337
+ // Mirrors marked's own default image() renderer (alt text
338
+ // re-rendered through the plain textRenderer so nested emphasis/
339
+ // strong/etc. inside the alt collapses to plain text, href run
340
+ // through the same cleanHref() the link() override above uses)
341
+ // with a part="img" added.
342
+ const altText = this.parser.parseInline(token.tokens, this.parser.textRenderer);
343
+ const href = cleanHref(token.href);
344
+ if (href === null)
345
+ return escapeHtml(altText);
346
+ const titleAttr = token.title ? ` title="${escapeHtml(token.title)}"` : '';
347
+ return `<img part="img" src="${escapeHtml(href)}" alt="${escapeHtml(altText)}"${titleAttr}>`;
348
+ },
349
+ },
350
+ });
351
+ return instance.parse(this.content, { gfm: this.gfm, async: false });
352
+ }
353
+ render() {
354
+ const isFallback = this.renderedHtml === null;
355
+ return html `
356
+ <div part="content" ?data-fallback=${isFallback} @click=${this.onContentClick}>
357
+ ${isFallback ? this.content : unsafeHTML(this.renderedHtml)}
358
+ </div>
359
+ `;
360
+ }
361
+ }
362
+ __decorate([
363
+ property()
364
+ ], LyraMarkdown.prototype, "content", void 0);
365
+ __decorate([
366
+ property({ type: Boolean })
367
+ ], LyraMarkdown.prototype, "sanitize", void 0);
368
+ __decorate([
369
+ property({ type: Boolean })
370
+ ], LyraMarkdown.prototype, "gfm", void 0);
371
+ __decorate([
372
+ property({ attribute: 'link-target' })
373
+ ], LyraMarkdown.prototype, "linkTarget", void 0);
374
+ __decorate([
375
+ property({ attribute: 'internal-link-prefix' })
376
+ ], LyraMarkdown.prototype, "internalLinkPrefix", void 0);
377
+ __decorate([
378
+ property({ type: Number, attribute: 'heading-offset' })
379
+ ], LyraMarkdown.prototype, "headingOffset", void 0);
380
+ __decorate([
381
+ property({ type: Boolean, attribute: 'eager-load' })
382
+ ], LyraMarkdown.prototype, "eagerLoad", void 0);
383
+ __decorate([
384
+ property({ type: Boolean, reflect: true })
385
+ ], LyraMarkdown.prototype, "streaming", void 0);
386
+ __decorate([
387
+ state()
388
+ ], LyraMarkdown.prototype, "renderedHtml", void 0);
389
+ defineElement('markdown', LyraMarkdown);
@@ -0,0 +1 @@
1
+ export declare const styles: import("lit").CSSResult;
@@ -0,0 +1,88 @@
1
+ import { css } from 'lit';
2
+ export const styles = css `
3
+ :host {
4
+ display: block;
5
+ /* Contained here (rather than left as a bare font-family literal) so a
6
+ host page can retheme it -- same rationale as lyra-json-viewer's
7
+ identical --lyra-json-viewer-font, no shared --wa-*/--lyra-*
8
+ monospace token exists to resolve through. */
9
+ --lyra-markdown-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
10
+ line-height: 1.6;
11
+ }
12
+ [part='content'] {
13
+ overflow-wrap: break-word;
14
+ }
15
+ /* Shared by both the "still loading" and "fell back after a failure"
16
+ states -- see the renderedHtml field doc in markdown.ts. */
17
+ [part='content'][data-fallback] {
18
+ white-space: pre-wrap;
19
+ font-family: inherit;
20
+ }
21
+ [part='content'] > :first-child {
22
+ margin-block-start: 0;
23
+ }
24
+ [part='content'] > :last-child {
25
+ margin-block-end: 0;
26
+ }
27
+ [part='heading'] {
28
+ line-height: 1.25;
29
+ margin-block: var(--lyra-space-l) var(--lyra-space-s);
30
+ }
31
+ [part='content'] p,
32
+ [part='content'] ul,
33
+ [part='content'] ol {
34
+ margin-block: 0 var(--lyra-space-s);
35
+ }
36
+ [part='content'] code {
37
+ font-family: var(--lyra-markdown-font-mono);
38
+ font-size: 0.875em;
39
+ background: var(--lyra-color-brand-quiet);
40
+ border-radius: calc(var(--lyra-radius) * 0.5);
41
+ padding: 0.125rem 0.3125rem;
42
+ }
43
+ [part='code-block'] {
44
+ margin-block: 0 var(--lyra-space-s);
45
+ padding: var(--lyra-space-s) var(--lyra-space-m);
46
+ border-radius: var(--lyra-radius);
47
+ background: var(--lyra-color-brand-quiet);
48
+ overflow-x: auto;
49
+ }
50
+ [part='code-block'] code {
51
+ padding: 0;
52
+ background: none;
53
+ font-size: 0.8125rem;
54
+ line-height: 1.5;
55
+ }
56
+ [part='link'] {
57
+ color: var(--lyra-color-brand);
58
+ text-underline-offset: 0.125rem;
59
+ }
60
+ /* Keeps an oversized source image from overflowing the content wrapper --
61
+ matches the overflow-wrap: break-word guard on [part='content'] above,
62
+ which only covers text, not replaced elements like <img>. */
63
+ [part='img'] {
64
+ max-width: 100%;
65
+ }
66
+ [part='blockquote'] {
67
+ margin-block: 0 var(--lyra-space-s);
68
+ margin-inline: 0;
69
+ padding-inline-start: var(--lyra-space-m);
70
+ border-inline-start: 3px solid var(--lyra-color-border);
71
+ color: var(--lyra-color-text-quiet);
72
+ }
73
+ [part='table'] {
74
+ border-collapse: collapse;
75
+ margin-block: 0 var(--lyra-space-s);
76
+ inline-size: 100%;
77
+ }
78
+ [part='table'] th,
79
+ [part='table'] td {
80
+ border: 1px solid var(--lyra-color-border);
81
+ padding: var(--lyra-space-xs) var(--lyra-space-s);
82
+ text-align: start;
83
+ }
84
+ [part='table'] th {
85
+ background: var(--lyra-color-brand-quiet);
86
+ font-weight: 600;
87
+ }
88
+ `;
@@ -0,0 +1,130 @@
1
+ import { type TemplateResult } from 'lit';
2
+ import { LyraElement } from '../../internal/lyra-element.js';
3
+ export type MediaCardKind = 'image' | 'video' | 'file';
4
+ export interface MediaCardOpenDetail {
5
+ src: string;
6
+ filename: string;
7
+ }
8
+ /** Validates `url` for an `<img>`/`<video>` source. Kept as a public wrapper
9
+ * so existing imports and generated API metadata remain stable. */
10
+ export declare function safeMediaSrc(url: string): string | null;
11
+ /** Validates `url` for the library's download/open link sinks. Kept as a
12
+ * public wrapper so existing imports and generated API metadata remain stable. */
13
+ export declare function safeLinkHref(url: string): string | null;
14
+ /**
15
+ * `<lyra-media-card>` — a lightweight inline preview for one already-sent,
16
+ * already-available attachment inside a rendered chat message body (e.g.
17
+ * plugged into `<lyra-chat-message>`'s `attachments` slot, or embedded
18
+ * directly by a markdown/message renderer). Distinct from two other,
19
+ * similarly-named components in this family: `<lyra-document-preview>` is a
20
+ * fuller viewer with header chrome and an async server-side-conversion
21
+ * state machine (`status="converting"`), and `<lyra-attachment-chip>` is a
22
+ * pre-send queued-file chip with upload progress. This component has
23
+ * neither concern — it only ever shows a `src` that's already final.
24
+ *
25
+ * **Format dispatch.** `kind` selects `'image'` (a plain `<img>`), `'video'`
26
+ * (a plain `<video controls>`), or `'file'` (an icon + filename chip with a
27
+ * download/open affordance). Leave `kind` unset to auto-detect from
28
+ * `mime-type` (`image/*` / `video/*` / anything else -> `'file'`);
29
+ * explicitly setting `kind` always wins over detection.
30
+ *
31
+ * **Safe-URL checking.** `src` is validated before it's ever assigned to an
32
+ * `<img>`/`<video>` `src` or an `<a href>` — only `http:`/`https:`/`blob:`
33
+ * (plus `data:` for a *media* `src` only) or a scheme-relative/relative URL
34
+ * with no scheme at all pass; anything else (`javascript:`, `vbscript:`,
35
+ * and similarly suspicious schemes) is rejected. `safeMediaSrc()` and
36
+ * `safeLinkHref()` share a platform-URL-based validator; their sink-specific
37
+ * allowlists explain why `data:` gets two different answers depending on
38
+ * where it is used. An `image`/`video` `kind` whose `src` fails the
39
+ * media-src check falls back to the generic file-chip rendering — this is
40
+ * the "plain preview unavailable state" a dangerous URL degrades to, rather
41
+ * than ever reaching a real media/anchor sink. That fallback also re-checks
42
+ * `src` against the stricter href allowlist for its own download affordance,
43
+ * but since the href allowlist is a strict subset of the media-src allowlist,
44
+ * that re-check can only ever change the outcome for a direct/auto-detected
45
+ * `kind="file"` `src` — an `image`/`video` `src` that already failed the
46
+ * wider media-src check necessarily fails the narrower href check too, so
47
+ * the fallback for those two kinds is always the plain, unclickable `span`.
48
+ *
49
+ * **The `video` case renders its open affordance separately from `base`.**
50
+ * `image`/`file` wrap their *entire* card in one native `<button>`/`<a>` —
51
+ * safe because an `<img>` and a plain icon+text chip have no interactive
52
+ * content of their own to conflict with. A `<video controls>` element is
53
+ * itself interactive content (its own play/seek/volume controls), and HTML
54
+ * forbids nesting interactive content inside a `<button>`/`<a>` — doing so
55
+ * anyway would also make every click on the video's own controls bubble up
56
+ * and spuriously fire `lyra-open`. So for `kind="video"`, `base` is a plain,
57
+ * non-interactive wrapper around `[part="media"]`, and a small separate
58
+ * `[part="open-button"]` (not one of this component's originally-scoped
59
+ * parts, added as the "explicit view/open affordance" the class is free to
60
+ * provide) is the thing that actually fires `lyra-open`.
61
+ *
62
+ * **Navigation.** This component never navigates on its own for `image`/
63
+ * `video` — activating the card only fires `lyra-open`; a host decides what
64
+ * "open" means (a lightbox, a new tab, whatever). The `file`-chip case is
65
+ * the one exception: when `src` passes the (stricter) href safety check, the
66
+ * chip is a real `<a href download>` so a bare drop-in still does something
67
+ * useful — but `lyra-open` fires first and is `cancelable`; a host that
68
+ * calls `preventDefault()` on it suppresses that default download/open so it
69
+ * can substitute its own handling instead.
70
+ *
71
+ * @customElement lyra-media-card
72
+ * @event lyra-open - The card (or, for `kind="video"`, its `open-button`)
73
+ * was activated. `detail: { src, filename }`. Cancelable — see the class
74
+ * doc's "Navigation" section for what calling `preventDefault()` on it does
75
+ * in the `file`-chip case.
76
+ * @csspart base - The root interactive/container element. A `<button>` for
77
+ * `kind="image"`, a plain wrapper `<div>` for `kind="video"`, and either an
78
+ * `<a>` (when `src` passes the href safety check) or a plain `<span>`
79
+ * (otherwise) for the `file`-chip fallback.
80
+ * @csspart media - The `<img>` or `<video>` element.
81
+ * @csspart file-icon - The generic file glyph, shown only in the file-chip fallback.
82
+ * @csspart filename - The filename text, shown only in the file-chip fallback.
83
+ * @csspart open-button - The explicit "open" affordance rendered next to
84
+ * `[part="media"]` for `kind="video"` only — see the class doc.
85
+ */
86
+ export declare class LyraMediaCard extends LyraElement {
87
+ static styles: import("lit").CSSResultGroup[];
88
+ /** The media URL. Always re-validated against a safe-scheme allowlist
89
+ * before use — see the class doc. */
90
+ src: string;
91
+ /** Explicit format dispatch. Leave unset to auto-detect from `mime-type`. */
92
+ kind?: MediaCardKind;
93
+ /** Drives auto-detection when `kind` is unset. */
94
+ mimeType: string;
95
+ /** Shown in the file-chip fallback, used as the download link's suggested
96
+ * filename, and folded into the accessible name of the whole card. */
97
+ filename: string;
98
+ /** Alt text for the image case (and reused as a video label fallback).
99
+ * Falls back to `filename`, then a generic per-kind description. */
100
+ alt: string;
101
+ /** A CSS length (e.g. `"16rem"`); once set, overrides the
102
+ * `--lyra-media-card-max-height` custom property for this instance only —
103
+ * same contract as `<lyra-document-preview>`'s identically-named prop. */
104
+ maxHeight: string;
105
+ /** Effective kind used for rendering — `kind` if explicitly set,
106
+ * otherwise detected from `mime-type`. */
107
+ private get resolvedKind();
108
+ private get displayFilename();
109
+ /** Accessible name for the card's own actionable element (`base` or, for
110
+ * video, `open-button`) — always phrased as the action it performs. */
111
+ private get accessibleLabel();
112
+ private get imgAlt();
113
+ private get videoLabel();
114
+ /** Per-instance override for `--lyra-media-card-max-height`, applied
115
+ * inline on `[part="base"]` -- the only mechanism that reliably wins
116
+ * over the `:host{}`-declared default from outside the shadow root. */
117
+ private get baseStyle();
118
+ private emitOpen;
119
+ private onActivate;
120
+ private onLinkClick;
121
+ private renderImage;
122
+ private renderVideo;
123
+ private renderFileFallback;
124
+ render(): TemplateResult;
125
+ }
126
+ declare global {
127
+ interface HTMLElementTagNameMap {
128
+ 'lyra-media-card': LyraMediaCard;
129
+ }
130
+ }